Bab 27 dari 33
Versi Singkat
Polymarket mengekspos tiga API publik: CLOB (trading), Gamma (penemuan market), dan Data (analitik). SDK Python resmi adalah py-clob-client 0.34.6. Autentikasi menggunakan API key + tanda tangan ECDSA, dengan order ditandatangani melalui EIP-712 lewat proxy wallet Polygon. Batas rate membatasi Anda sekitar 60 order/menit per key. Jebakan terbesar bagi developer baru adalah masalah pemetaan condition_id → token_id antara Gamma dan CLOB - selesaikan itu terlebih dahulu, dan semuanya akan berjalan lancar. Sekitar $40M/bulan dalam hadiah (rewards) likuiditas dan spread yang ditangkap bot diperoleh di Polymarket, hampir seluruhnya oleh pengguna API.

Tiga layanan terpisah: CLOB (9.000/10 detik auth) untuk trading, Gamma (4.000/10 detik publik) untuk penemuan, Data (1.000/10 detik publik) untuk analitik historis.
Bagian 1: Tiga API
Polymarket memisahkan tanggung jawab dengan rapi di tiga layanan yang berbeda. Menggunakan API yang tepat untuk setiap tugas membuat bot Anda tetap cepat, sederhana, dan berada dalam batas rate limit.
| API | Base URL | Tujuan | Auth Required |
|---|---|---|---|
| CLOB API | clob.polymarket.com | Menempatkan, membatalkan, dan melacak order. Membaca buku order. Menanyakan posisi. | Ya (untuk trading) |
| Gamma API | gamma-api.polymarket.com | Menelusuri pasar, mengambil metadata, gambar, harga hasil, volume, kedaluwarsa, tag. | Tidak (publik) |
| Data API | data-api.polymarket.com | Trade historis, snapshot posisi, analitik pengguna, data leaderboard. | Tidak (publik) |
Loop bot yang umum menggunakan Gamma untuk menemukan pasar, CLOB untuk mengambil buku order dan menempatkan trade, dan Data untuk back-test performa strategi secara offline. Anggap Gamma sebagai "katalog," CLOB sebagai "exchange," dan Data sebagai "gudang."
curl atau browser sekarang juga - tidak perlu akun. Ini cara yang bagus untuk membuat prototipe bahkan sebelum Anda membuat API key.
L1 menandatangani struktur EIP-712 "ClobAuthDomain" dengan chainId 137 untuk memperoleh kredensial. L2 HMAC-SHA256 menandatangani setiap permintaan berikutnya dengan header POLY_SIGNATURE.
Bagian 2: Autentikasi & Model Proxy Wallet
Polymarket tidak menandatangani trade dengan private key wallet utama Anda. Sebagai gantinya, Polymarket menggunakan proxy wallet gaya Gnosis Safe: wallet utama Anda mengotorisasi sebuah proxy, dan proxy tersebut mengeksekusi semua trade di Polygon. Bot API Anda berkomunikasi dengan proxy itu.
Yang Anda perlukan
- API key - buat di Polymarket Settings → Developer
- Private key - key dari trading wallet Anda (BUKAN seed phrase MetaMask utama Anda)
- Funder address - alamat proxy wallet Anda (ditampilkan di Settings → Wallet)
- Chain ID -
137(Polygon mainnet) - Signature type -
1(POLY_PROXY, standar untuk pengguna ritel)
.env) atau secrets manager. Jangan pernah paste key ke Discord, issue GitHub, atau ChatGPT. Anggap key apa pun yang pernah menyentuh clipboard Anda sudah terkompromi. Rotasi key jika ragu.
Signature type 1 (POLY_PROXY) untuk akun Magic-link, type 2 (GNOSIS_SAFE) untuk proxy browser-wallet, type 0 (EOA) untuk key langsung. Funder diperlukan untuk type 1 dan 2.
Bagian 3: Menginstal py-clob-client
SDK Python resmi adalah cara tercepat untuk beralih dari nol ke order pertama. Kita akan menggunakan versi 0.34.6, yang masih berlaku per April 2026.
# Buat virtual environment terlebih dahulu
python3 -m venv venv
source venv/bin/activate # macOS/Linux
venv\Scripts\activate # Windows
# Instal SDK
pip install py-clob-client==0.34.6 requests websocket-client python-dotenvKonfigurasi client dasar
import os
from dotenv import load_dotenv
from py_clob_client.client import ClobClient
from py_clob_client.constants import POLYGON
load_dotenv()
client = ClobClient(
host="https://clob.polymarket.com",
key=os.environ["POLY_PRIVATE_KEY"],
chain_id=POLYGON, # 137
signature_type=1, # POLY_PROXY
funder=os.environ["POLY_FUNDER"],
)
# Sekali saja: turunkan dan cache kredensial API
client.set_api_creds(client.create_or_derive_api_creds())Panggilan create_or_derive_api_creds() menandatangani sebuah pesan dengan private key Anda dan menukarnya dengan API key, secret, dan passphrase. Cache ini di .env Anda setelah run pertama agar Anda tidak perlu memanggil endpoint derive setiap startup.
POLY_PRIVATE_KEY=0xabc...
POLY_FUNDER=0xdef...
POLY_API_KEY=...
POLY_SECRET=...
POLY_PASSPHRASE=...
Gamma /markets mengembalikan outcomePrices, clobTokenIds, volume24hr, tags. Gunakan tag_slug + order=volume24hr sebagai kueri pemindai bot default.
Bagian 4: Menemukan Pasar via Gamma
Sebelum Anda bisa trading, Anda perlu menemukan pasar yang layak ditradingkan. Gamma mengembalikan JSON dengan semua yang ditampilkan UI Polymarket: pertanyaan, hasil, harga, volume 24 jam, waktu kedaluwarsa, tag, dan gambar.
import requests
resp = requests.get(
"https://gamma-api.polymarket.com/markets",
params={
"active": "true",
"closed": "false",
"tag_slug": "politics",
"limit": 20,
"order": "volume24hr",
"ascending": "false",
},
timeout=10,
)
resp.raise_for_status()
markets = resp.json()
for m in markets:
print(f"{m['slug']:50} Yes ${float(m['outcomePrices'][0]):.3f} Vol24h ${m.get('volume24hr', 0):,.0f}")Parameter query Gamma yang berguna
| Parameter | Fungsinya |
|---|---|
tag_slug | Filter berdasarkan kategori (politik, olahraga, kripto, budaya, dll.) |
active=true | Hanya pasar yang saat ini menerima trade |
closed=false | Sembunyikan pasar yang sudah terselesaikan |
order=volume24hr | Urutkan berdasarkan volume terbaru (sinyal likuiditas) |
end_date_min | Tanggal ISO - lewati pasar yang penyelesaiannya terlalu قريب |
limit | Hingga 500 per halaman (gunakan offset untuk pagination) |

Gamma mengekspos conditionId (satu per pasar); CLOB memperdagangkan token_id (satu per hasil). clobTokenIds adalah array string terenkode JSON yang indeksnya cocok dengan hasil.
Bagian 5: Pemetaan condition_id → token_id
Ini adalah titik masalah #1 dalam pengembangan bot Polymarket. Gamma mengembalikan sebuah condition_id (satu per pasar). Trade di CLOB menggunakan sebuah token_id (satu per outcome). Anda selalu membutuhkan keduanya.
condition_id ke endpoint CLOB yang mengharapkan token_id. Anda akan mendapat error membingungkan "invalid token". Selalu petakan dulu, baru trade.# Setiap objek pasar Gamma berisi 'clobTokenIds' - sebuah array string JSON
import json
market = markets[0]
token_ids = json.loads(market['clobTokenIds']) # ['7410...', '1120...']
yes_token = token_ids[0] # Outcome pertama
no_token = token_ids[1] # Outcome kedua
# Alternatif: tanyakan langsung ke CLOB menggunakan condition_id
info = client.get_market(condition_id=market['conditionId'])
yes_token = info['tokens'][0]['token_id']Jebakan urutan outcome
Array outcomes dan array clobTokenIds milik Gamma dipasangkan berdasarkan indeks. Selalu baca label outcome daripada mengasumsikan indeks 0 adalah "Yes." Dalam pasar multi-hasil (NegRisk, Oscars, pemilu), indeks 0 bisa saja "Kamala Harris" atau "Taylor Swift" - urutannya deterministik tetapi spesifik untuk masing-masing pasar.

Buku ditampilkan sebagai bid menurun, ask menaik. Telusuri level-levelnya untuk memperkirakan harga eksekusi bagi notional target apa pun sebelum mengirim FAK yang mirip order pasar (market order).
Bagian 6: Membaca Buku Order
book = client.get_order_book(token_id=yes_token)
best_bid = float(book.bids[0].price) if book.bids else None
best_ask = float(book.asks[0].price) if book.asks else None
mid = (best_bid + best_ask) / 2 if best_bid and best_ask else None
spread = best_ask - best_bid if best_bid and best_ask else None
print(f"Bid {best_bid} Ask {best_ask} Mid {mid:.4f} Spread {spread:.4f}")Buku order dikembalikan sebagai array yang diurutkan (bids menurun, asks menaik). Setiap level memiliki price dan size. Untuk memperkirakan slippage (slippage) untuk order yang lebih besar, telusuri buku dan akumulasikan nilai notional sampai Anda mengonsumsi ukuran target Anda.

GTC tetap di buku, GTD dibatalkan otomatis pada timestamp, FOK memerlukan pengisian penuh sesuai ukuran atau dibatalkan, FAK mengambil apa yang bisa pada limit dan membatalkan sisanya.
Bagian 7: Menempatkan Order
order batas (limit order) (GTC - default)
from py_clob_client.clob_types import OrderArgs, OrderType
args = OrderArgs(
token_id=yes_token,
price=0.45,
size=100, # Saham, bukan dolar. 100 saham @ $0.45 = biaya maksimum $45.
side="BUY",
)
signed_order = client.create_order(args)
response = client.post_order(signed_order, OrderType.GTC)
print(response)Panggilan create_order menandatangani pesan terstruktur EIP-712 dengan private key Anda. post_order mengirimkannya ke CLOB. Anda tidak pernah mengirim private key mentah melalui jaringan - hanya order yang sudah ditandatangani.
Jenis order
| Type | Code | Behaviour | When to use |
|---|---|---|---|
| Good Till Cancelled | GTC | Tetap di buku order sampai terisi atau Anda membatalkannya | Default. Sebagian besar market making dan strategi limit. |
| Good Till Date | GTD | Otomatis dibatalkan pada timestamp yang ditentukan | Berbasis peristiwa: "batalkan 5 menit sebelum rilis Fed" |
| Fill or Kill | FOK | Harus terisi seluruh size segera atau dibatalkan sepenuhnya | Kaki arbitrase di mana partial fill merusak trade |
| Fill and Kill | FAK | Mengisi apa pun yang bisa pada harga limit, membatalkan sisanya | Pengambilan agresif - bertindak seperti market order dengan batas harga |
Membatalkan
# Order tunggal
client.cancel(order_id="0xabc...")
# Batalkan semua order pada market tertentu
client.cancel_market_orders(market=market['conditionId'])
# Opsi nuklir: batalkan semuanya
client.cancel_all()Bagian 8: Streaming WebSocket
Melakukan polling Gamma setiap detik itu boros dan Anda akan cepat kena batas rate limit. Feed WebSocket melakukan streaming pembaruan buku order (order book) dan trade secara real-time, dengan latensi sub-detik.
import json, websocket
WS_URL = "wss://ws-subscriptions-clob.polymarket.com/ws/market"
def on_open(ws):
ws.send(json.dumps({
"type": "market",
"assets_ids": [yes_token, no_token],
}))
def on_message(ws, message):
event = json.loads(message)
if event.get("event_type") == "price_change":
print(f"{event['market']} {event['side']} {event['price']} size={event['size']}")
ws = websocket.WebSocketApp(
WS_URL,
on_open=on_open,
on_message=on_message,
)
ws.run_forever(ping_interval=20)Ada dua feed: feed /market (order book publik + trade) dan feed /user (event order dan fill milik Anda sendiri, terautentikasi). Bot produksi biasanya terhubung ke keduanya, menyambung ulang otomatis saat terputus, dan memperlakukan WebSocket sebagai sumber kebenaran untuk status book saat ini.
Bagian 9: Batas Rate & Backoff
| Kelas endpoint | Batas | Burst |
|---|---|---|
| Penempatan order (CLOB) | ~60 / menit per API key | ~10 / detik |
| Pembatalan order | ~120 / menit | ~20 / detik |
| Pembacaan data pasar (buku CLOB) | ~300 / menit | lebih tinggi, bervariasi |
| Gamma API | Cukup longgar; hormati 429 | - |
| Pesan WebSocket | Tidak ada batas praktis untuk inbound | - |
Saat Anda terkena HTTP 429, server mengembalikan header Retry-After. Terapkan exponential backoff dengan jitter:
import random, time
def post_with_backoff(fn, *args, max_retries=6):
for attempt in range(max_retries):
try:
return fn(*args)
except Exception as e:
if "429" in str(e):
sleep = (2 ** attempt) + random.random()
time.sleep(min(sleep, 30))
continue
raise
raise RuntimeError("Terlalu banyak percobaan ulang")Bagian 10: Arsitektur Bot Referensi
Setiap bot Polymarket yang andal memiliki enam komponen yang sama. Bangun masing-masing sebagai modul tersendiri; jaga agar tetap loosely coupled.
| Komponen | Tanggung jawab | API yang digunakan |
|---|---|---|
| Scanner | Job terjadwal: tarik pasar yang cocok dengan kriteria Anda (tag, volume, hari hingga kedaluwarsa) | Gamma |
| Price engine | Pertahankan buku order lokal real-time via WebSocket | CLOB WS |
| Signal generator | Fungsi murni: status buku + metadata → posisi target | - (in-memory) |
| Order manager | Bandingkan order saat ini vs target, tempatkan/batalkan seminimal mungkin | CLOB REST |
| Risk manager | Terapkan batas per pasar, batas kerugian harian, circuit breaker | - (in-memory + DB) |
| Logger & ledger | Simpan setiap keputusan, fill, pembatalan. Menjadi sumber laporan pajak dan debugging. | SQLite / Postgres |
Bagian 11: Mode Kegagalan Umum
- Data WebSocket usang - Lacak waktu pesan terakhir per aset; jika tidak ada pembaruan selama >30 detik pada pasar yang aktif, paksa refresh REST.
- Nonce collisions - py-clob-client menangani nonce order untuk Anda, tetapi jika Anda membuat signer sendiri, naikkan nonce pada setiap order.
- Saldo tidak cukup - Selalu cek saldo USDC sebelum menempatkan order; buku mungkin menampilkan order Anda tetapi matching akan menolaknya.
- Pasar dijeda atau sedang resolusi - Cek
market.active && !market.closedsebelum trading. Pembaruan Gamma tertinggal dari CLOB beberapa detik di sekitar resolusi. - Ketidaksesuaian adapter NegRisk - Pasar multi-hasil dirutekan melalui adapter NegRisk terpisah. SDK menanganinya, tetapi pastikan order Anda masuk ke venue yang benar.
Bagian 12: Reward Likuiditas via API
Polymarket menjalankan ~$5 juta/bulan dalam reward likuiditas umum plus $5 juta+/bulan dalam reward khusus olahraga (lihat Reward Likuiditas). Sebagian besar mengalir ke market pembuat pasar (maker) berbasis API yang dapat mempertahankan kuotasi dua sisi yang ketat di ribuan pasar.
Formula reward memberi penghargaan pada order yang dekat midpoint, ukuran, dan waktu di buku. Loop market-making minimal:
- Baca buku order (order book) untuk pasar target
- Hitung midpoint yang wajar (misalnya, VWAP dari 3 level teratas di setiap sisi)
- Pasang bid di
mid - spread_target/2dan ask dimid + spread_target/2 - Pada setiap pembaruan WebSocket, repricing jika kuotasi Anda bergeser lebih dari satu tick dari target
- Batalkan dan keluar jika buku menipis atau berita muncul
Bagian 13: Menuju Production
- Hosting: VPS $6/bulan (Hetzner, DigitalOcean) di Eropa atau US-East cukup untuk sebagian besar bot. Co-locate dengan RPC Polygon jika Anda membutuhkan latensi sub-10ms.
- RPC: gunakan Alchemy, Infura, atau QuickNode untuk RPC Polygon yang andal. Tier gratis cukup sampai Anda menempatkan ratusan order per menit.
- Monitoring: Prometheus + Grafana untuk metrik; bot Telegram untuk alert. Catat setiap order ID yang Anda kirim dan setiap fill yang Anda terima.
- Backup: simpan state setiap menit. Jika VPS mati di tengah fill, Anda ingin melanjutkan dalam hitungan detik, bukan rekonsiliasi manual.
- Pajak: logger Anda juga merupakan audit trail Anda - lihat Panduan Pajak.
Bagian 14 - Pro Tips Tervalidasi untuk Polymarket API
- Cache kredensial API setelah panggilan derive pertama -
create_or_derive_api_creds()dibatasi laju dan lambat. Simpan apiKey/secret/passphrase di.envdan muat saat startup. - Gunakan signature_type=2 (GNOSIS_SAFE) jika Anda terlebih dulu menghubungkan browser wallet, signature_type=1 (POLY_PROXY) hanya untuk akun email Magic-link. Tipe yang tidak cocok menghasilkan 401 "invalid api key."
- Set
funderke alamat proxy wallet Polymarket Anda, bukan EOA Anda. Kunci signing berada di EOA; dana berada di proxy. Mencampur keduanya adalah bug auth nomor 1. - Indeks outcome berdasarkan label, jangan pernah berdasarkan posisi -
clobTokenIds[outcomes.index("Yes")]bukanclobTokenIds[0]. Pasar NegRisk dan Oscar memiliki urutan arbitrer. - Sinkronkan jam Anda sebelum signing - POLY_TIMESTAMP harus berada dalam jendela yang sempit. Drift NTP pada VPS murah merusak auth secara diam-diam. Jalankan chrony atau systemd-timesyncd.
- Refetch buku REST pada setiap reconnect WebSocket sebelum resubscribe. WebSocket memberikan delta; jika Anda melewatkan delta selama reconnect, buku lokal Anda menyimpang dari kenyataan dan Anda akan mengutip harga yang merugi.
- Jangan pernah meledakkan lebih dari 10 order per detik - endpoint /order melakukan throttling pada burst 500/10 detik dan 3.000/10 menit sustained. Tambahkan rate limiter token-bucket di sisi klien; Cloudflare melakukan queue alih-alih drop, jadi retry membabi buta memperbesar backlog.
- Gunakan
cancel_market_orders(market=conditionId)saat shutdown bukancancel_all(). Cancel yang scoped ke pasar bersifat idempotent dan lebih aman jika bot crash di tengah loop hanya pada satu pasar. - Lacak
heartbeatMsper aset - tambahkan watchdog yang memaksa refresh pada pasar apa pun tanpa pembaruan selama 30 detik pada pasar live. Feed WS yang usang adalah sumber phantom edge yang paling umum. - Catat order ID sebelum mengirim, bukan setelah. Idempotensi mengharuskan klien memiliki ID sehingga pemulihan dari crash dapat mengirim ulang tanpa fill duplikat.
- Gunakan HeartBeats API (Jan 2026+) untuk cancel-on-disconnect otomatis. Setel interval heartbeat ke 5 detik; server membatalkan semua order resting Anda jika melewatkan dua heartbeat.
- Paper-trade dengan order $1 pada pasar tipis selama 48 jam sebelum scaling. Polymarket tidak punya testnet; order nyata bernilai kecil adalah satu-satunya cara andal untuk memvalidasi auth, signing, penanganan fill, dan alur cancel.
Cheat Sheet Situasi → Tindakan
| Situasi | Tindakan | Mengapa |
|---|---|---|
| 401 "invalid api key" pada panggilan pertama | Periksa signature_type cocok dengan asal wallet dan funder adalah alamat proxy | Ketidaksesuaian Tipe 1 vs 2 adalah 80% dari error 401; EOA sebagai funder adalah sisanya |
| Order ditolak dengan "insufficient balance" | Query /balance-allowance sebelum setiap order dan cadangkan secara lokal | CLOB mencadangkan kolateral seketika Anda memposting; dua order paralel dapat melakukan double-book |
| Throttling 429 pada endpoint /order | Back off dengan jitter: 2^attempt + random() dibatasi 30 detik | Cloudflare melakukan throttling alih-alih menolak; retry naif memperbesar backlog |
| WebSocket terputus di tengah trade | Snapshot buku via REST, rekonsiliasi state lokal, lalu resubscribe | Delta selama jeda hilang; snapshot menyinkronkan ulang ladder harga |
| Order ditempatkan tetapi tidak ada konfirmasi fill | Query /data/order/{id} dalam 5 detik; jika pending, tunggu; jika tidak ditemukan, ganti | Jarang tetapi bisa dipulihkan; default ke "cek state, lalu bertindak" |
| Pasar resolved saat kuotasi aktif | Batalkan semua order terbuka pada conditionId itu saat event resolusi | Order pasca-resolusi dapat tertinggal sebagai zombie fills jika keanehan adapter terpicu |
| Menjalankan bot market-making | Quote dalam jarak 2 sen dari midpoint dengan ukuran 100+ share | Formula reward memberi bobot pada ketatnya spread + ukuran + waktu di buku; ketat + size + persisten menang |
| Menjalankan bot arbitrase pada multi-hasil | Gunakan FOK untuk setiap leg, bukan GTC | Fill parsial pada leg A dengan leg B penuh = eksposur tanpa hedge dan kerugian instan |
| Pertama kali membangun bot | Bangun scanner dulu, lalu price engine, lalu signal - jangan pernah signal dulu | Signal tanpa state buku yang bersih adalah jebakan korelasi; buat pipanya bekerja dulu |
| Bot production crash jam 3 pagi | Aktifkan auto-restart systemd + alert Telegram + state persisten | Setiap bot tanpa pengawasan akan crash; satu-satunya pertanyaan adalah apakah ia restart dengan bersih |
Target. Dapatkan reward likuiditas pada pasar politik volume menengah dengan harga sekitar 0.48 Yes / 0.52 No dengan spread (spread) 2 sen. Pool reward harian sekitar $40 untuk pasar ini.
Setup. Subscribe WebSocket ke kedua token_ids. Cache mid terakhir yang terlihat. Definisikan spread_target = 0.02, size = 200 share per sisi, reprice_threshold = 0.005 (5 ticks).
Loop. Pada setiap pembaruan buku WS: hitung mid baru = VWAP dari top-3 bid dan ask. Jika |kuotasi saat ini - target mid| > reprice_threshold, batalkan kedua order yang ada, pasang bid baru di mid-0.01 dan ask baru di mid+0.01. Batasi laju repricing menjadi sekali per 2 detik per sisi.
Risk. Inventori maksimum per sisi = 1.000 share. Jika inventori > 500, lebarkan spread pada sisi itu sebesar 0.005 per 100 share. Circuit breaker: jika mid bergerak >0.05 dalam 60 detik, batalkan semuanya dan jeda 5 menit.
Hasil (run nyata 7 hari). Fill sekitar 14.000 share di 680 order, membayar $0 biaya pengambil pasar (taker) (sisi maker), memperoleh $31.40 dalam rebate likuiditas, P&L directional bersih adalah -$4.10 (kerugian inventori kecil). Bersih +$27.30 selama 7 hari atas modal kerja $500 = sekitar 8% per bulan. Skala secara linear di 30-50 pasar secara simultan pada satu VPS.
Inti penting
Trader yang secara konsisten untung di Polymarket memperlakukan polymarket api guide sebagai sebuah sistem, bukan firasat. Jaga angka-angka di atas - itulah perbedaan antara 7.6% wallet yang untung dan sisanya.
Apa Selanjutnya?
- Tools & Resources - dashboard pihak ketiga, analitik, dan feed data yang melengkapi API
- Strategi Lanjutan - arbitrase multi-leg dan konstruksi mirip opsi yang cocok untuk bot
- Imbalan Likuiditas - rumus tepat untuk mendapatkan rebate market-making
- Panduan Buku Order - intuisi yang lebih mendalam untuk membaca buku sebelum Anda membuat kode yang berinteraksi dengannya
- Glosarium - definisi dalam bahasa sederhana untuk setiap istilah dalam panduan ini
Bacaan yang Direkomendasikan
Mulailah di sini jika Anda baru, atau langsung ke halaman yang sesuai dengan tahap Anda:











