Polymarket Bot Tutorial · Bab 7 dari 32
Deep dive Polymarket Gamma API: endpoint /events dan /markets, pagination, tag IDs (864 Tennis, 745 NBA, dll), filtering berdasarkan volume 24 jam, rate limits, serta contoh kode Python dan Node.
Apa yang dibahas dalam bab ini
Gamma adalah catalog API Polymarket - API ini menampilkan setiap event, setiap market, tag, image, dan resolved outcome yang ditampilkan front-end. CLOB API digunakan untuk trading; Gamma menjelaskan apa yang bisa ditradingkan. Sebagian besar bug bot di layer discovery berasal dari tertukarnya dua hal ini, atau karena melupakan pagination contract. Bab ini adalah referensi lapangan untuk endpoint utama Gamma dengan perilaku parameter yang tepat yang diandalkan oleh production fetcher kami.
- Gamma vs CLOB: kapan menggunakan yang mana
- Anatomi endpoint /events
- Anatomi endpoint /markets
- Tag dan tag IDs (daftar terverifikasi)
- Filtering: active, closed, urutan volume24hr
- Pagination dan limit
- Rate limits dan caching
- Code: fetch top 24h-volume markets
Gamma vs CLOB: kapan menggunakan yang mana
Dua layanan berbeda untuk dua pekerjaan berbeda.
Gamma (gamma-api.polymarket.com): catalog. Menampilkan event, market, tag, description, image, resolved outcome, volume 24 jam, total volume, dan end date. Read-only HTTP. Untuk sebagian besar read tidak diperlukan authentication. Diperbarui terus-menerus tetapi eventually consistent - market yang baru saja closed mungkin masih menampilkan closed: false selama beberapa detik.
CLOB (clob.polymarket.com): trading + order book. Menampilkan best bid/ask saat ini, depth book top-N, dan trade terbaru. Memerlukan authentication untuk write endpoints (order placement, cancellation). Tersedia channel WebSocket real-time untuk update book.
Aturan praktis: gunakan Gamma untuk mencari apa yang akan ditradingkan; gunakan CLOB untuk trading. Bot yang membaca harga dari Gamma menggunakan data yang stale - field harga Gamma diperbarui lebih jarang daripada order book CLOB. Bot yang membaca metadata market dari CLOB justru melakukan request lebih banyak dari yang diperlukan.
Anatomi endpoint /events
GET /events mengembalikan data level event. "Event" adalah halaman Polymarket; satu event dapat berisi beberapa market (misalnya event Pemilihan Presiden 2024 memiliki satu market per kandidat).
Field penting:
slug: identifier yang aman untuk URL, stabil selama event berlangsung.title,description: untuk tampilan manusia.endDate(ISO 8601): kapan event ditutup.active,closed: boolean; gabungkan dalam query dengan?active=true&closed=falseuntuk live events.volume,volume24hr: total USD.tags: array objek tag (lihat bagian tags di bawah).markets: array objek child market (lihat anatomi/markets).
Pola discovery yang paling umum: GET /events?active=true&closed=false&order=volume24hr&ascending=false&limit=100. Mengembalikan 100 event live dengan volume tertinggi saat ini.
Anatomi endpoint /markets
GET /markets mengembalikan data level market. Market adalah satu kontrak Y/N atau multi-outcome; market berada di dalam event.
Field penting:
slug: identifier yang aman untuk URL.question: judul yang ditampilkan di halaman trading (misalnya "Will Trump be president on January 1, 2027?").outcomes: JSON string nama outcome, misalnya'["Yes","No"]'. Selalu dua elemen untuk binary; lebih banyak untuk NegRisk.outcomePrices: JSON string harga saat ini dalam desimal, misalnya'["0.62","0.38"]'. Kedua sisi berjumlah ~1.0 dikurangi spread.clobTokenIds: JSON string ERC-1155 token IDs yang sejajar dengan outcomes. Inilah token yang sebenarnya Anda beli/jual.negRisk: boolean; true untuk market multi-outcome yang totalnya 1. Penting untuk order placement (bab 11).
Field outcomes / outcomePrices / clobTokenIds datang sebagai JSON string, bukan array yang sudah diparse - lakukan JSON-decode sebelum digunakan.
Tag dan tag IDs (daftar terverifikasi)
Tag adalah label kategori (Sports, Crypto, Tennis, NBA, dll.). Berikut tag ID production yang terverifikasi untuk kategori yang paling sering digunakan:
| Tag | ID | Tag | ID |
|---|---|---|---|
| Sports | 1 | NBA | 745 |
| Crypto | 21 | NFL | 450 |
| Politics | 2 | Tennis | 864 |
| Bitcoin | 100196 | Esports | 702 |
| Ethereum | 100383 | Soccer | 1059 |
| Election | 3 | EPL | 739 |
| Middle East | 1432 | UCL | 2186 |
Filter berdasarkan tag dengan ?tag_id=745 untuk tag tertentu, atau ?tag_slug=nba menggunakan slug. Filtering berbasis slug lebih mudah dibaca di code tetapi sedikit lebih lambat; berbasis ID adalah default production.
Filtering: active, closed, urutan volume24hr
Empat dimensi filter yang akan Anda gunakan 95% dari waktu.
active=true|false:truemengecualikan market yang disembunyikan tim Polymarket dari UI.closed=true|false:falsemengecualikan market yang sudah resolved. Kombinasiactive=true&closed=falseadalah filter live yang paling umum.order=volume24hr,order=volume,order=endDate: kunci sort. Yang paling berguna adalahvolume24hruntuk menemukan market yang sedang aktif.ascending=true|false: default-nya true di sebagian besar endpoint; Anda hampir selalu inginfalseuntuk ordering volume.
Catatan: filtering dengan tag_id yang dikombinasikan dengan order=volume24hr dan ascending=false kadang menghasilkan halaman kosong ketika tag tersebut memiliki sangat sedikit live market. Selalu over-fetch (request lebih banyak daripada yang Anda tampilkan) dan lakukan post-filter untuk menangani ini.
Pagination dan limit
Parameter limit menerima 1-500 per call. Default-nya 100 jika tidak ditentukan. Di atas 500 server akan membatasi secara diam-diam - Anda menerima 500 tetapi response tidak memberi indikasi adanya lebih banyak data.
Pagination berbasis offset: ?limit=500&offset=500 untuk halaman kedua. Tidak ada cursor-based pagination, jadi insert yang terjadi bersamaan dapat menggeser batas halaman di antara call. Untuk sebagian besar kebutuhan discovery bot, ini dapat diterima; untuk scrape arsip, sort berdasarkan field yang stabil (endDate atau createdAt) dan deteksi overlap berdasarkan slug.
Pola praktis untuk "semua live markets": fetch limit=500&order=volume24hr&ascending=false. Itu mencakup 500 teratas berdasarkan volume, yang pada dasarnya adalah setiap market dengan aktivitas yang tidak sepele. Melampaui page 1 jarang berguna - market di ekor distribusi volume pada dasarnya bukan tempat aksi terjadi.
Rate limits dan caching
Gamma berada di belakang Cloudflare dan memiliki soft rate limits per IP. Ambang empiris yang teramati di bawah production load:
- Sampai ~30 req/detik dari satu IP secara sustained: aman.
- Burst 100+ req/detik: kadang-kadang 429, retry berhasil.
- ~500 req/detik secara sustained: halaman rate-limit atau temporary block (10-60 detik).
Response headers yang dipublikasikan menyertakan nilai Cache-Control 30-60 detik untuk sebagian besar endpoint. Patuhi itu - tidak ada manfaatnya melakukan re-fetch event yang sama 10 kali dalam satu menit. Pola caching production: in-process LRU + TTL yang dikunci pada full URL, TTL 30 detik. Menghemat jumlah request dan mengurangi latency.
Untuk strategi frekuensi tinggi, mirror data Gamma ke local store yang diperbarui oleh satu proses fetcher; biarkan banyak consumer membaca dari store itu. Satu fetcher × banyak consumer > banyak fetcher × Gamma.
Code: fetch top 24h-volume markets
Reference fetcher dalam tiga bahasa, mengembalikan 50 live market teratas berdasarkan volume 24 jam.
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'
Endpoint Polymarket gamma /events TIDAK mendukung parameter free-text search - menambahkan ?q=foo atau ?search=foo akan diam-diam mengembalikan ordering default. Sebagai gantinya, filter berdasarkan slug atau tag.










