Skip to content

Instantly share code, notes, and snippets.

@BaptistG
Created December 11, 2025 09:10
Show Gist options
  • Select an option

  • Save BaptistG/5957e4ee4bb3657b9ed27fbfc9170ff0 to your computer and use it in GitHub Desktop.

Select an option

Save BaptistG/5957e4ee4bb3657b9ed27fbfc9170ff0 to your computer and use it in GitHub Desktop.
import requests
import csv
API_URL = "https://api.merkl.xyz/v4/opportunities"
CHAIN_ID = 143
ITEMS_PER_PAGE = 100
CSV_PATH = "campaigns_report.csv"
def fetch_all_opportunities():
page = 0
all_opps = []
while True:
params = {
"chainId": CHAIN_ID,
"campaigns": "true",
"items": ITEMS_PER_PAGE,
"page": page
}
resp = requests.get(API_URL, params=params)
resp.raise_for_status()
items = resp.json()
if not items:
break
all_opps.extend(items)
if len(items) < ITEMS_PER_PAGE:
break
page += 1
return all_opps
def main():
opps = fetch_all_opportunities()
rows = []
for opp in opps:
opp_name = opp.get("name", "")
protocol = opp.get("protocol", {}).get("name", "")
for camp in opp.get("campaigns", []):
campaign_id = camp.get("campaignId", "")
if not campaign_id.startswith("0x"):
continue
if camp.get("type") == "INVALID":
continue
creator = camp.get("creator", "")
# Extract just the address if creator is a dict
if isinstance(creator, dict):
creator = creator.get("address", "")
reward_token = camp.get("rewardToken", {})
symbol = reward_token.get("symbol", "")
decimals = reward_token.get("decimals", 18)
amount_raw = camp.get("amount", 0)
try:
amount = int(amount_raw) / (10 ** int(decimals))
except Exception:
amount = amount_raw
rows.append([
opp_name,
protocol,
campaign_id,
creator,
symbol,
amount
])
# Write to CSV
with open(CSV_PATH, "w", newline="") as f:
writer = csv.writer(f)
writer.writerow(["Opportunity name", "Protocol", "CampaignId", "creator", "Reward Token", "amount"])
writer.writerows(rows)
print(f"Saved {len(rows)} rows to {CSV_PATH}")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment