Polymarket Bot Tutorial · Hoofdstuk 7 van 32

Polymarket Gamma API deep dive: /events en /markets endpoints, pagination, tag IDs (864 Tennis, 745 NBA, etc.), filteren op 24h volume, rate limits en Python- en Node-codevoorbeelden.

Wat dit hoofdstuk behandelt

Gamma is Polymarkets catalogus-API — het lijst elk event, elke markt, tag, image en resolved outcome die de front-end toont. De CLOB API tradet; Gamma beschrijft wat tradeable is. De meeste bot-bugs op de discovery-laag komen van de twee verwarren of het missen van het pagination-contract. Dit hoofdstuk is de veldreferentie voor de hoofd-endpoints van Gamma met het exacte parameter-gedrag waarop onze productie-fetchers afhangen.

Dit is hoofdstuk 7 van onze 32-delige serie over het bouwen van een Polymarket trading bot. We behandelen het onderwerp in detail in de secties hieronder. De body content voor elke sectie wordt geschreven en hoofdstuk-per-hoofdstuk uitgerold; FAQ-antwoorden en referenties zijn al compleet en weerspiegelen production-ervaring van het draaien van onze eigen trader.

  • Gamma vs CLOB: wanneer welke gebruiken
  • /events endpoint anatomie
  • /markets endpoint anatomie
  • Tags en tag IDs (geverifieerde lijst)
  • Filteren: active, closed, volume24hr ordering
  • Pagination en limits
  • Rate limits en caching
  • Code: fetch top 24h-volume markten

Gamma vs CLOB: wanneer welke gebruiken

Twee verschillende services voor twee verschillende jobs.

Gamma (gamma-api.polymarket.com): catalogus. Lijst events, markten, tags, beschrijvingen, images, resolved outcomes, 24-uurs volume, totaal volume, end dates. Read-only HTTP. Geen authenticatie vereist voor de meeste reads. Continu geüpdatet maar eventually consistent — een markt die net gesloten is kan een paar seconden lang closed: false tonen.

CLOB (clob.polymarket.com): trading + order book. Lijst huidige best bid/ask, top-N book depth, recente trades. Geauthenticeerd voor write endpoints (order plaatsen, cancellation). Real-time WebSocket channels beschikbaar voor book updates.

Vuistregel: gebruik Gamma om te vinden wat te traden; gebruik CLOB om het te traden. Een bot die prijzen leest uit Gamma gebruikt stale data — Gamma's prijsvelden updaten minder frequent dan CLOB's order book. Een bot die market-metadata leest uit CLOB maakt meer requests dan nodig.

/events endpoint anatomie

GET /events geeft event-niveau data terug. Een "event" is een Polymarket-pagina; een enkel event kan meerdere markten bevatten (bijv. het 2024 Presidential Election event heeft één markt per kandidaat).

Belangrijke velden:

  • slug: URL-safe identifier, stabiel voor de levensduur van het event.
  • title, description: human display.
  • endDate (ISO 8601): wanneer het event sluit.
  • active, closed: booleans; combineer in een query met ?active=true&closed=false voor live events.
  • volume, volume24hr: USD-totalen.
  • tags: array van tag-objecten (zie tags-sectie hieronder).
  • markets: array van child market-objecten (zie /markets anatomie).

Het enkele meest voorkomende discovery-patroon: GET /events?active=true&closed=false&order=volume24hr&ascending=false&limit=100. Geeft de 100 hoogste-volume momenteel-live events terug.

/markets endpoint anatomie

GET /markets geeft market-niveau data terug. Een markt is één J/N of multi-outcome contract; hij leeft binnen een event.

Belangrijke velden:

  • slug: URL-safe identifier.
  • question: de titel getoond op de trading-pagina (bijv. "Will Trump be president on January 1, 2027?").
  • outcomes: JSON-string van outcome-namen, bijv. '["Yes","No"]'. Altijd twee elementen voor binary; meer voor NegRisk.
  • outcomePrices: JSON-string van huidige prijzen als decimalen, bijv. '["0.62","0.38"]'. Beide zijden sommeren tot ~1,0 minus spread.
  • clobTokenIds: JSON-string van ERC-1155 token-IDs uitgelijnd met outcomes. Dit zijn de tokens die je daadwerkelijk koopt/verkoopt.
  • negRisk: boolean; true voor multi-outcome sum-to-1 markten. Telt voor order plaatsing (hoofdstuk 11).

De outcomes / outcomePrices / clobTokenIds velden komen aan als JSON-strings, geen geparseerde arrays — JSON-decode ze voor gebruik.

Tags en tag IDs (geverifieerde lijst)

Tags zijn categorische labels (Sport, Crypto, Tennis, NBA, etc.). De geverifieerde productie tag-IDs voor de meest-gebruikte categorieën:

TagIDTagID
Sport1NBA745
Crypto21NFL450
Politiek2Tennis864
Bitcoin100196Esports702
Ethereum100383Voetbal1059
Verkiezing3EPL739
Midden-Oosten1432UCL2186

Filter op tag met ?tag_id=745 voor een specifieke tag, of ?tag_slug=nba met de slug. Slug-based filteren is leesbaarder in code maar iets langzamer; ID-based is de productie-default.

Filteren: active, closed, volume24hr ordering

De vier filter-dimensies die je 95% van de tijd zult gebruiken.

  • active=true|false: true sluit markten uit die het Polymarket-team heeft verborgen voor de UI.
  • closed=true|false: false sluit afgehandelde markten uit. De combinatie active=true&closed=false is de meest voorkomende live filter.
  • order=volume24hr, order=volume, order=endDate: sorteersleutel. Meest nuttig is volume24hr voor het vinden van momenteel-actieve markten.
  • ascending=true|false: default true op de meeste endpoints; je wilt bijna altijd false voor volume-orderings.

Caveat: filteren op tag_id gecombineerd met order=volume24hr en ascending=false geeft soms een lege pagina terug wanneer de tag zeer weinig live markten heeft. Over-fetch altijd (vraag meer aan dan je toont) en post-filter om dit te hanteren.

Pagination en limits

limit param accepteert 1-500 per call. Default is 100 als niet gespecificeerd. Boven 500 capt de server stil — je ontvangt 500 maar de respons heeft geen indicatie van meer.

Pagination is offset-based: ?limit=500&offset=500 voor de tweede pagina. Er is geen cursor-based pagination, dus gelijktijdige inserts kunnen page-boundaries doen schuiven tussen calls. Voor de meeste bot-discovery doelen is dit acceptabel; voor archive-scrapes, sorteer op een stabiel veld (endDate of createdAt) en detecteer overlap per slug.

Praktisch patroon voor "alle live markten": fetch limit=500&order=volume24hr&ascending=false. Dat dekt de top 500 op volume wat in essentie elke markt met niet-triviale activiteit is. Voorbij pagina 1 gaan is zelden nuttig — markten in de staart van de volume-verdeling zijn per definitie niet waar de actie is.

Rate limits en caching

Gamma is gefront door Cloudflare en heeft soft rate limits per IP. Empirische thresholds geobserveerd onder productie-load:

  • Tot ~30 req/sec vanaf één IP sustained: prima.
  • Bursts van 100+ req/sec: af en toe 429s, retries slagen.
  • ~500 req/sec sustained: rate-limit pagina of tijdelijke block (10-60s).

De gepubliceerde response headers bevatten Cache-Control waarden van 30-60 seconden voor de meeste endpoints. Respecteer ze — er is geen voordeel om hetzelfde event 10 keer per minuut opnieuw te fetchen. Productie-caching patroon: in-process LRU + TTL keyed op de volledige URL, 30s TTL. Bespaart request-count en vermindert latency.

Voor high-frequency strategieën, mirror Gamma-data naar een lokale store geüpdatet door een enkel fetcher-proces; laat meerdere consumers van die store lezen. Eén fetcher × veel consumers > veel fetchers × Gamma.

Code: fetch top 24h-volume markten

Referentie-fetcher in drie talen, geeft de top 50 live markten op 24-uurs volume terug.

Python:

import requests
r = requests.get("https://gamma-api.polymarket.com/events",
                 params={"active":"true","closed":"false",
                         "order":"volume24hr","ascending":"false","limit":50},
                 timeout=10)
for ev in r.json()[:50]:
    print(ev["slug"], ev.get("volume24hr"))

Node:

const url = "https://gamma-api.polymarket.com/events?active=true&closed=false" +
            "&order=volume24hr&ascending=false&limit=50";
const events = await fetch(url).then(r => r.json());
for (const ev of events) console.log(ev.slug, ev.volume24hr);

Curl:

curl -s "https://gamma-api.polymarket.com/events?active=true&closed=false&order=volume24hr&ascending=false&limit=50" \
  | jq '.[].slug'

Het Polymarket gamma /events endpoint ondersteunt GEEN free-text search parameter — ?q=foo of ?search=foo toevoegen geeft stil de default ordering terug. Filter op slug of tag in plaats daarvan.

Veelgestelde vragen

Wat is de Polymarket Gamma API?
Gamma is Polymarkets metadata- en discovery-API. Het serveert event/markt-lijsten, titels, beschrijvingen, end dates, tags en aggregate volume. Het serveert GEEN real-time order book data — dat leeft op de CLOB API. Voor de meeste discovery- en analytics-cases begin je met Gamma.
Wat is het verschil tussen een event en een markt op Polymarket?
Een event groepeert één of meer markten die een vraagthema delen. Een markt is een specifieke Yes/No outcome met eigen order book en token-IDs. Een "2026 NBA Champion" event bevat 30 markten (één per team). Voor binary Yes/No events heeft het event 1 onderliggende markt.
Hoe vind ik Polymarket tag-IDs?
Tags zijn exposed via het gamma /tags endpoint. Geverifieerde IDs die we in productie gebruiken: 864 Tennis, 745 NBA. Tag-slugs in URLs (?tag_slug=tennis) en free-text query (?q=tennis) zijn onbetrouwbaar — gebruik alleen numerieke tag_id. Check /tags voor je op een slug vertrouwt.
Hoe sorteer ik Polymarket events op 24h volume?
/events?order=volume24hr&ascending=false — dit is wat de meeste "trending markets" widgets aandrijft. Combineer met active=true&closed=false om verlopen of gepauzeerde markten uit te filteren. Limit default 25; max is 500 per call.
Zijn er pagination-limieten op Gamma?
Ja. De /events en /markets endpoints accepteren limit (max 500 per call) en offset voor pagination. De meeste libraries pagineren niet automatisch — als je het volledige universum nodig hebt, loop met offset totdat je een pagina krijgt met minder dan `limit` resultaten.
Ondersteunt Gamma WebSocket?
Nee. Gamma is REST-only. Voor real-time updates (price changes, nieuwe markten, order book) gebruik de CLOB WebSocket — behandeld in hoofdstuk 8 van deze serie.