DEV Community

Cover image for Pola Desain API dari Polymarket: Pasar Prediksi Terbesar di Dunia
Walse
Walse

Posted on • Originally published at apidog.com

Pola Desain API dari Polymarket: Pasar Prediksi Terbesar di Dunia

Pasar prediksi adalah domain yang menantai untuk membangun API: instrumen keuangan memiliki masa berlaku, harga merepresentasikan probabilitas secara real-time, peristiwa multi-hasil memiliki hubungan modal yang kompleks, dan pengguna mencakup manusia di UI hingga bot arbitrase. Dalam kondisi seperti ini, keputusan desain API langsung diuji oleh kebutuhan latensi, keamanan, dan konsistensi data.

Coba Apidog hari ini

Polymarket—platform pasar prediksi terbesar berdasarkan volume—menyediakan contoh arsitektur yang menarik untuk dipelajari. API-nya bukan sekadar lapisan CRUD di atas basis data, tetapi sistem berlapis yang memisahkan penemuan pasar, perdagangan, data pengguna, serta streaming real-time.

Berikut delapan pola yang dapat diterapkan saat merancang API untuk sistem keuangan, perdagangan, atau aplikasi real-time.


Pola 1: Pisahkan API Berdasarkan Domain, Bukan Entitas

Polymarket mengekspos tiga API dengan tanggung jawab yang berbeda:

  • Gamma API (gamma-api.polymarket.com) — penemuan pasar, peristiwa, tag, dan pencarian.
  • CLOB API (clob.polymarket.com) — buku pesanan, harga, dan penempatan pesanan.
  • Data API (data-api.polymarket.com) — posisi pengguna, perdagangan, analitik, dan papan peringkat.

Pemisahan ini bukan hanya soal penamaan. Setiap domain memiliki karakteristik operasional berbeda:

Domain Konsumen utama Kebutuhan utama
Penemuan pasar UI, pencarian, integrasi Data publik dan mudah dijelajahi
Perdagangan Trader dan bot Latensi rendah dan autentikasi
Analitik pengguna Dashboard dan pelaporan Query berbasis alamat dompet

Pendekatan yang kurang ideal biasanya menggabungkan semuanya dalam endpoint seperti:

/markets
/orders
/users
Enter fullscreen mode Exit fullscreen mode

Sebaliknya, tanyakan: untuk apa API ini digunakan?

  • Penemuan memiliki pola akses baca yang tinggi.
  • Perdagangan membutuhkan kontrol keamanan dan latensi.
  • Analitik membutuhkan query historis serta agregasi.

Dengan URL dasar terpisah, setiap API dapat diskalakan, diamankan, dan dikembangkan secara independen.

Langkah implementasi:

  1. Petakan domain bisnis utama, bukan hanya tabel database.
  2. Identifikasi kebutuhan autentikasi dan latensi setiap domain.
  3. Pisahkan gateway, rate limit, cache, atau infrastruktur streaming jika kebutuhannya berbeda.
  4. Hindari endpoint “serba bisa” yang menggabungkan penemuan, eksekusi, dan analitik.

Pola 2: Jadikan Data Baca Publik Jika Tidak Membutuhkan Otorisasi

Data pasar Polymarket—harga, buku pesanan, metadata peristiwa, dan perdagangan historis—dapat diakses secara publik:

curl "https://gamma-api.polymarket.com/events?limit=5"
Enter fullscreen mode Exit fullscreen mode

Tidak ada kunci API atau OAuth untuk data baca tersebut.

Pola ini relevan ketika nilai platform meningkat karena banyak pihak dapat membaca, menganalisis, dan membangun integrasi di atas data yang sama. Dalam konteks pasar, akses data publik dapat memperluas likuiditas dan ekosistem aplikasi.

Pisahkan dengan tegas operasi read dan write:

GET  /markets              → publik
GET  /order-book/:tokenId  → publik
POST /orders               → terautentikasi
DELETE /orders/:orderId    → terautentikasi
Enter fullscreen mode Exit fullscreen mode

Prinsip implementasi:

  • Jangan menerapkan autentikasi secara seragam hanya karena endpoint berada dalam produk yang sama.
  • Lindungi operasi yang mengubah keadaan: membuat pesanan, membatalkan pesanan, memindahkan dana, atau memperbarui profil.
  • Gunakan cache atau CDN untuk endpoint publik dengan trafik baca tinggi.
  • Dokumentasikan batas penggunaan dan perilaku cache untuk data pasar yang cepat berubah.

Untuk platform dengan rasio pembaca jauh lebih besar daripada penulis, desain ini mengurangi gesekan bagi sebagian besar pengguna tanpa mengorbankan keamanan operasi penting.


Pola 3: Gunakan Otentikasi Bertingkat untuk Risiko yang Berbeda

Endpoint perdagangan Polymarket menggunakan dua tingkat autentikasi.

L1: Buktikan kepemilikan dompet

L1 memakai tanda tangan EIP-712 dari kunci privat pengguna. Tujuannya adalah membuktikan bahwa pengguna mengendalikan dompet terkait, biasanya saat membuat atau memperoleh kredensial API.

// L1: gunakan kunci privat untuk mendapatkan kredensial API
const credentials = await client.createOrDeriveApiKey();

// { key: "...", secret: "...", passphrase: "..." }
Enter fullscreen mode Exit fullscreen mode

L2: Tanda tangani permintaan perdagangan rutin

Setelah memiliki kredensial API, permintaan perdagangan menggunakan HMAC-SHA256:

{
  "POLY_ADDRESS": "0x...",
  "POLY_SIGNATURE": "<hmac-sha256>",
  "POLY_TIMESTAMP": "1716000000",
  "POLY_API_KEY": "550e8400-...",
  "POLY_PASSPHRASE": "..."
}
Enter fullscreen mode Exit fullscreen mode

Pemisahan ini penting:

  • L1 digunakan untuk tindakan berisiko tinggi: membuktikan identitas dan kontrol dompet.
  • L2 digunakan untuk tindakan berulang: mengautentikasi permintaan perdagangan berfrekuensi tinggi.

Secara umum, pola ini dapat diterapkan di luar kripto:

L1 → “Buktikan Anda adalah pemilik identitas ini.”
L2 → “Buktikan permintaan ini dibuat oleh sesi atau kredensial yang sah.”
Enter fullscreen mode Exit fullscreen mode

Langkah implementasi:

  1. Identifikasi tindakan yang memerlukan verifikasi dengan kredensial terkuat.
  2. Buat token atau kredensial turunan untuk operasi rutin.
  3. Tambahkan timestamp dan signature pada setiap request untuk mengurangi risiko replay attack.
  4. Terapkan masa berlaku, rotasi, dan pencabutan kredensial L2.

Jangan paksa pengguna menggunakan mekanisme keamanan paling berat untuk setiap request jika sistem juga membutuhkan throughput tinggi.


Pola 4: Perlakukan Pesanan sebagai Pesan Bertanda Tangan

Dalam desain API konvensional, POST /orders biasanya berarti:

“Server, tolong buat pesanan ini atas nama saya.”

Pada Polymarket, pesanan merupakan pesan EIP-712 yang ditandatangani secara kriptografis. Pesan tersebut adalah komitmen finansial yang dapat diverifikasi.

const response = await client.createAndPostOrder(
  {
    tokenID: "71321045679...",
    price: 0.65,
    size: 100,
    side: Side.BUY,
  },
  {
    tickSize: "0.01",
    negRisk: false,
  },
  OrderType.GTC
);
Enter fullscreen mode Exit fullscreen mode

SDK membangun struktur data bertipe, menandatanganinya dengan kunci privat, lalu mengirimkan pesanan dan tanda tangannya. Mesin pencocokan berjalan di luar rantai, sementara penyelesaian perdagangan dilakukan di Polygon berdasarkan otorisasi yang ditandatangani tersebut.

Maknanya berubah menjadi:

“Ini adalah instrumen yang ditandatangani dan mengotorisasi perdagangan ini.”

Untuk sistem berisiko tinggi, payload yang membawa otorisasi memiliki beberapa manfaat:

  • Non-penolakan (non-repudiation).
  • Verifikasi independen terhadap isi pesan.
  • Jejak audit yang lebih kuat.
  • Pengurangan ketergantungan pada kepercayaan penuh terhadap operator API.

Pola payload bertanda tangan:

type SignedOrder = {
  payload: {
    tokenId: string;
    price: number;
    size: number;
    side: "BUY" | "SELL";
    expiry: number;
    nonce: string;
  };
  signature: string;
};
Enter fullscreen mode Exit fullscreen mode

Tambahkan nonce, masa berlaku, dan domain pemisah tanda tangan agar pesan tidak dapat digunakan ulang pada konteks yang salah.


Pola 5: Modelkan Ontologi Domain Secara Eksplisit

Polymarket membedakan dua objek utama:

  • Peristiwa (Event): pertanyaan atau konteks besar.
  • Pasar (Market): hasil spesifik yang dapat diperdagangkan di dalam peristiwa tersebut.

Contohnya:

  • Peristiwa: “Siapa yang akan memenangkan pemilihan Senat AS 2026 di Pennsylvania?”
  • Pasar: “Apakah Bob Casey akan menang?”

Satu peristiwa dapat memuat beberapa pasar:

{
  "id": "501",
  "title": "2026 Pennsylvania Senate Race",
  "negRisk": true,
  "markets": [
    {
      "id": "2301",
      "question": "Will Bob Casey win?",
      "outcomePrices": "[\"0.42\", \"0.58\"]"
    },
    {
      "id": "2302",
      "question": "Will Dave McCormick win?",
      "outcomePrices": "[\"0.35\", \"0.65\"]"
    },
    {
      "id": "2303",
      "question": "Will a third candidate win?",
      "outcomePrices": "[\"0.23\", \"0.77\"]"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Model ini mengungkap hubungan konseptual yang penting bagi klien. Misalnya, harga direpresentasikan sebagai larik paralel:

outcomes[0] === outcomePrices[0]
outcomes[1] === outcomePrices[1]
Enter fullscreen mode Exit fullscreen mode

Selain itu, negRisk berada pada tingkat peristiwa karena hubungan modal berlaku untuk pasar-pasar di dalam peristiwa tersebut.

Jangan sembunyikan aturan domain penting dalam dokumentasi saja.

Jika klien harus mengetahui hubungan antarobjek untuk menghitung posisi, risiko, atau validasi pesanan, tampilkan hubungan itu secara eksplisit di respons API.


Pola 6: Jadikan Invarian Domain sebagai Field API Bertipe

negRisk menunjukkan bahwa suatu peristiwa memiliki hubungan modal khusus. Pada peristiwa multi-hasil tertentu, tepat satu hasil dapat menang.

Dalam kondisi ini:

1 token “Tidak” pada hasil A ≡ 1 token “Ya” pada setiap hasil lainnya

Contoh konversi:

Sebelum Sesudah
1× Tidak (Lainnya) 1× Ya (Casey) + 1× Ya (McCormick)

Polymarket mengekspos kondisi ini melalui negRisk: true, baik pada data pasar maupun saat membuat pesanan:

const order = await client.createAndPostOrder(
  {
    tokenID: "71321045679...",
    price: 0.65,
    size: 100,
    side: Side.BUY,
  },
  {
    tickSize: "0.01",
    negRisk: true,
  },
  OrderType.GTC
);
Enter fullscreen mode Exit fullscreen mode

Jika klien mengabaikan nilai tersebut, model posisi dapat salah dan pesanan dapat ditolak atau diproses secara tidak sesuai.

Pola yang dapat diterapkan:

{
  "marketId": "2301",
  "isMutuallyExclusive": true,
  "settlementGroupId": "501",
  "conversionRules": {
    "enabled": true
  }
}
Enter fullscreen mode Exit fullscreen mode

Gunakan field bertipe untuk aturan yang memengaruhi perilaku sistem. Jangan hanya menulis catatan seperti:

Catatan: pasar tertentu mungkin memiliki hubungan khusus.
Enter fullscreen mode Exit fullscreen mode

Aturan domain yang keras harus dapat dibaca dan divalidasi oleh mesin.


Pola 7: Perlakukan Konfigurasi Dinamis sebagai Keadaan Real-Time

Ukuran tick sering dianggap sebagai konfigurasi statis. Polymarket memperlakukannya sebagai keadaan pasar yang dapat berubah.

Saat harga berada di dekat ekstrem—di atas 0.96 atau di bawah 0.04—ukuran tick minimum berubah dari 0.01 menjadi 0.001:

{
  "event_type": "tick_size_change",
  "asset_id": "65818619657...",
  "old_tick_size": "0.01",
  "new_tick_size": "0.001",
  "timestamp": "100000000"
}
Enter fullscreen mode Exit fullscreen mode

Perubahan ini masuk akal secara finansial. Pada harga 0.04, pergeseran 0.01 ke 0.03 merepresentasikan perubahan probabilitas 25%. Tick yang lebih kecil memungkinkan penemuan harga lebih presisi, misalnya 0.973 alih-alih hanya 0.97.

Klien tidak boleh mengodekan ukuran tick secara permanen:

// Hindari hardcode seperti ini
const tickSize = 0.01;
Enter fullscreen mode Exit fullscreen mode

Simpan keadaan tick per aset dan perbarui dari event real-time:

const tickSizeByAsset = new Map<string, string>();

function onTickSizeChange(event: {
  asset_id: string;
  new_tick_size: string;
}) {
  tickSizeByAsset.set(event.asset_id, event.new_tick_size);
}
Enter fullscreen mode Exit fullscreen mode

Sebelum membuat pesanan, ambil nilai terbaru:

const tickSize = tickSizeByAsset.get(tokenID) ?? "0.01";
Enter fullscreen mode Exit fullscreen mode

Prinsipnya: jika parameter dapat berubah dan memengaruhi validitas request, parameter tersebut adalah state, bukan konstanta.


Pola 8: Pisahkan WebSocket Berdasarkan Profil Konsumen

Polymarket menjalankan dua sistem WebSocket dengan target penggunaan berbeda.

Market Channel

Market Channel:

wss://ws-subscriptions-clob.polymarket.com/ws/market
Enter fullscreen mode Exit fullscreen mode

Channel ini ditujukan untuk kebutuhan perdagangan. Klien berlangganan berdasarkan ID token dan menerima data seperti:

  • Snapshot buku pesanan.
  • Perubahan harga.
  • Eksekusi perdagangan.
  • Perubahan ukuran tick.
{
  "assets_ids": [
    "65818619657568813474341868652308942079804919287380422192892211131408793125422"
  ],
  "type": "market"
}
Enter fullscreen mode Exit fullscreen mode

Real-Time Data Socket

Socket data real-time:

wss://ws-live-data.polymarket.com
Enter fullscreen mode Exit fullscreen mode

Socket ini melayani kebutuhan berbeda, seperti komentar, harga kripto dari Binance dan Chainlink, harga ekuitas, serta peristiwa interaksi sosial.

{
  "action": "subscribe",
  "subscriptions": [
    {
      "topic": "crypto_prices",
      "type": "update",
      "filters": "btcusdt,ethusd"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Jangan paksa satu koneksi WebSocket untuk melayani semua kebutuhan real-time.

Kebutuhan Karakteristik
Bot perdagangan Latensi rendah, delta buku pesanan, reliabilitas tinggi
UI sosial atau dashboard Volume event beragam, toleransi latensi lebih besar
Feed harga eksternal Langganan berbasis topik dan filter

Langkah implementasi:

  1. Kelompokkan konsumen berdasarkan kebutuhan latensi, volume, dan keandalan.
  2. Pisahkan channel atau topik jika kontrak datanya berbeda jauh.
  3. Hindari mengirim event sosial ke klien yang hanya membutuhkan order book.
  4. Dokumentasikan strategi reconnect, snapshot awal, dan pemrosesan event yang datang tidak berurutan.

Endpoint WebSocket bersama yang menangani terlalu banyak tujuan biasanya menjadi lebih kompleks dan kurang optimal untuk semua konsumen.


Ringkasan: Buat Struktur Domain Terlihat di API

Pola desain API Polymarket berpusat pada satu prinsip: API harus merepresentasikan struktur domain yang sebenarnya, bukan menyembunyikannya di balik abstraksi generik.

Penerapannya terlihat pada:

  • API terpisah untuk domain penemuan, perdagangan, dan data.
  • Data pasar publik, tetapi operasi tulis yang terautentikasi.
  • Otentikasi bertingkat untuk tindakan dengan tingkat risiko berbeda.
  • Pesanan sebagai pesan bertanda tangan.
  • Hierarki Peristiwa dan Pasar yang eksplisit.
  • negRisk sebagai aturan domain yang dapat diproses mesin.
  • Ukuran tick sebagai state real-time.
  • WebSocket terpisah untuk profil konsumen berbeda.

Ergonomi API tetap penting: penamaan konsisten, endpoint mudah dipanggil, dan error dapat diprediksi. Namun, untuk domain kompleks seperti sistem perdagangan atau keuangan, ergonomi saja tidak cukup.

Jika domain memiliki batasan, tampilkan batasan tersebut. Jika domain memiliki state yang berubah, siarkan perubahannya. Jika entitas memiliki hubungan penting, modelkan hubungan itu secara eksplisit.

Dengan begitu, klien yang berhasil mengintegrasikan API Anda bukan hanya dapat memanggil endpoint—mereka benar-benar memahami sistem yang sedang mereka gunakan.

Top comments (0)