DEV Community

Cover image for Polymarket'ten API Tasarım Kalıpları: Dünyanın En Büyük Tahmin Piyasası
Tobias Hoffmann
Tobias Hoffmann

Posted on • Originally published at apidog.com

Polymarket'ten API Tasarım Kalıpları: Dünyanın En Büyük Tahmin Piyasası

Tahmin piyasaları için API tasarlamak; süresi dolan finansal enstrümanlar, gerçek zamanlı olasılık fiyatları, çok sonuçlu olaylardaki sermaye ilişkileri ve hem insan kullanıcıları hem de arbitraj botlarını desteklemek anlamına gelir. Bu nedenle API tasarımındaki her karar; gecikme, güvenlik, veri tutarlılığı ve istemci davranışı açısından hızla stres testine girer.

Apidog'u bugün deneyin

Hacim açısından dünyanın en büyük tahmin piyasası platformu olan Polymarket, bu problemlere karşı katmanlı bir API mimarisi kullanır. Bu mimari yalnızca CRUD uç noktalarından oluşmaz; genel veri erişimi, imzalı emirler, gerçek zamanlı durum güncellemeleri ve farklı tüketiciler için ayrılmış akışlar içerir.

Bu yazıda, Polymarket'in API ekosisteminden çıkarılabilecek sekiz uygulanabilir tasarım modelini inceleyeceğiz.


Model 1: API'leri Kaynağa Değil, Alan Sorumluluğuna Göre Ayırın

Polymarket üç ayrı API sunar:

  • Gamma API (gamma-api.polymarket.com) — piyasa keşfi, olaylar, etiketler ve arama
  • CLOB API (clob.polymarket.com) — emir defterleri, fiyatlar ve emir oluşturma
  • Veri API'si (data-api.polymarket.com) — kullanıcı pozisyonları, işlemler, analizler ve liderlik tabloları

Bu ayrım yalnızca URL organizasyonu değildir. Her katmanın farklı tüketicileri ve gereksinimleri vardır:

API Ana kullanım Kimlik doğrulama Gecikme beklentisi
Gamma Keşif ve listeleme Genel Orta
CLOB Emir defteri ve ticaret Okuma genel, yazma kimlik doğrulamalı Düşük
Veri API'si Pozisyon ve işlem analizi Genel, cüzdan adresi bazlı Orta

Tek bir /markets, /orders ve /users API'si oluşturmak yerine şu soruyu sorun:

Bu API hangi işi yapmak için var?

Örneğin keşif ve ticaret aynı veri modelini paylaşsa bile aynı erişim modelini paylaşmaz:

  • Keşif uç noktaları cache dostu, genel ve yüksek hacimli olabilir.
  • Ticaret uç noktaları düşük gecikmeli, imzalı ve sıkı doğrulamalı olmalıdır.
  • Analitik uç noktaları tarihsel sorgular ve cüzdan tabanlı filtreler için optimize edilmelidir.

Bu ayrım, servislerin bağımsız olarak ölçeklenmesini, sürümlenmesini ve güvenlik politikası uygulamasını kolaylaştırır.


Model 2: Okuma ve Yazma Erişimini Ayrı Tasarlayın

Polymarket'te fiyatlar, emir defterleri, olay meta verileri ve geçmiş işlemler gibi piyasa verileri herkese açıktır:

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

Bu istek için API anahtarı veya OAuth akışı gerekmez.

Bu yaklaşımı uygularken erişim politikanızı iki temel sınıfa ayırın:

  1. Okuma erişimi: Keşif, fiyat görüntüleme, halka açık olay verileri
  2. Yazma erişimi: Emir oluşturma, iptal etme, kullanıcı bakiyesi veya yetkili işlemler

Örnek bir politika matrisi:

GET /events              -> Genel erişim
GET /markets/:id         -> Genel erişim
GET /book                -> Genel erişim
POST /orders             -> İmzalı ve kimlik doğrulamalı
DELETE /orders/:id       -> İmzalı ve kimlik doğrulamalı
GET /positions?user=...  -> Genel, adres tabanlı sorgu
Enter fullscreen mode Exit fullscreen mode

Bu model özellikle veri tüketiminin, veri üretiminden çok daha yüksek olduğu sistemlerde faydalıdır. Kullanıcıların fiyatları görmek için hesap açması veya anahtar üretmesi gerekiyorsa, entegrasyon maliyetini gereksiz yere artırırsınız.

Sürtünmeyi yalnızca riskli eylemlerde ekleyin:

  • Emir oluşturma
  • Para transferi
  • Pozisyon kapatma
  • Hesap veya API kimliği yönetimi

Model 3: Kimlik Kanıtlama ile İstek Yetkilendirmesini Ayırın

Polymarket'in CLOB ticaret akışı iki seviyeli kimlik doğrulama kullanır.

L1: Cüzdan sahipliğini kanıtlama

L1 kimlik doğrulama, kullanıcının özel anahtarıyla oluşturduğu EIP-712 imzasına dayanır. Amaç, cüzdan sahipliğini kanıtlamak ve API kimlik bilgilerini türetmektir.

// L1: API kimlik bilgilerini türetmek için özel anahtarınızı kullanın
const credentials = await client.createOrDeriveApiKey();

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

Bu işlem yüksek risklidir; çünkü API anahtarı üretme veya türetme yetkisi sağlar. Bu nedenle güçlü kimlik kanıtı gerektirir.

L2: Her isteği yetkilendirme

L2 aşamasında türetilen kimlik bilgileri kullanılır. Her ticaret isteğine HMAC-SHA256 tabanlı imza başlıkları eklenir:

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

Bu modeli kendi API'nize uyarlamak için:

  1. Yüksek güven gerektiren işlemlerde güçlü bir kimlik kanıtı isteyin.
  2. Bu doğrulama sonucunda sınırlı veya döndürülebilir oturum/API kimlik bilgileri üretin.
  3. Rutin istekleri daha hafif bir imza mekanizmasıyla doğrulayın.
  4. Zaman damgası kullanarak replay attack riskini azaltın.
  5. API anahtarlarının iptal ve yenileme akışlarını destekleyin.

Temel ayrım şudur:

  • L1: “Bu kişinin gerçekten siz olduğunu kanıtlayın.”
  • L2: “Bu isteğin yetkili bir oturumdan geldiğini kanıtlayın.”

Bu yaklaşım yalnızca kripto sistemleri için değil; ödeme API'leri, yüksek riskli yönetim işlemleri ve imzalı iş akışları için de uygulanabilir.


Model 4: Emirleri Sıradan POST Gövdeleri Değil, İmzalı Taahhütler Olarak Modelleyin

Polymarket'te emir oluşturmak yalnızca sunucuya veri göndermek değildir. Emir, kriptografik olarak imzalanmış ve uygulanabilir bir finansal taahhüttür.

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'nin yaptığı işlem özetle şöyledir:

  1. Emir verisini yapılandırır.
  2. EIP-712 tipli veri oluşturur.
  3. Veriyi kullanıcının özel anahtarıyla imzalar.
  4. İmzayı emir verisiyle birlikte eşleştirme motoruna gönderir.
  5. İşlem eşleştiğinde imza, Polygon üzerinden zincir içi sonuçlandırma için yetkilendirme olarak kullanılır.

Bu yaklaşımda API'nin anlamı değişir:

Klasik POST /orders:
"Lütfen benim adıma bu emri oluşturun."

İmzalı emir:
"Bu emri yetkilendiren doğrulanabilir imzalı belge budur."
Enter fullscreen mode Exit fullscreen mode

Bu modelin avantajı, yetkilendirmenin doğrudan yükte taşınmasıdır. Böylece:

  • Emir sahibinin kimliği doğrulanabilir.
  • Emir içeriği sonradan değiştirilemez.
  • İmza, belirli bir işlem niyetine bağlıdır.
  • Operatör, kullanıcı adına keyfi işlem üretemez.

Bu yaklaşım özellikle aşağıdaki alanlarda değerlidir:

  • Finansal talimatlar
  • Sözleşme onayları
  • Yüksek değerli işlem akışları
  • Denetlenebilir yetkilendirme gerektiren sistemler

Model 5: Alan Modelindeki Kavramsal İlişkileri API'de Görünür Yapın

Polymarket verileri iki temel nesne etrafında düzenlenir:

  • Olay (Event): Genel soru veya bağlam
  • Piyasa (Market): Olay içindeki belirli ve alınıp satılabilir sonuç

Örneğin:

  • Olay: “2026 Pennsylvania Senato yarışını kim kazanacak?”
  • Piyasa: “Bob Casey kazanacak mı?”

Bir olay birden fazla piyasa içerebilir:

{
  "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

Bu veri modelinde önemli olan, API'nin yalnızca kayıt döndürmemesidir. Aynı zamanda alanın kavramsal yapısını da taşır.

Örneğin paralel dizilerde indeks ilişkisini istemci kodunda açıkça ele alın:

const outcomes = ["Yes", "No"];
const prices = ["0.42", "0.58"];

const normalized = outcomes.map((outcome, index) => ({
  outcome,
  price: Number(prices[index]),
}));
Enter fullscreen mode Exit fullscreen mode

Sonuç:

[
  { outcome: "Yes", price: 0.42 },
  { outcome: "No", price: 0.58 }
]
Enter fullscreen mode Exit fullscreen mode

İstemci tarafında şu kontrolleri ekleyin:

if (outcomes.length !== prices.length) {
  throw new Error("Outcome ve fiyat dizileri eşleşmiyor.");
}
Enter fullscreen mode Exit fullscreen mode

Ayrıca negRisk gibi alan kurallarını yok saymayın. Bu bayrak, piyasalardaki pozisyonların bağımsız olmadığını belirtir. Bir ticaret botu bu ilişkiyi hesaba katmazsa yanlış risk modeli oluşturabilir.


Model 6: Alan Değişmezlerini Dokümantasyona Değil, Şemaya Koyun

negRisk bayrağı, çok sonuçlu olaylarda sermaye ilişkilerini ifade eder.

NegRisk olaylarında yalnızca bir sonuç kazanabilir. Bu nedenle sonuçlar arasında matematiksel eşdeğerlikler bulunur:

A sonucundaki 1 “Hayır” token'ı, diğer her sonuçtaki 1 “Evet” token'ına eşdeğerdir.

Örnek dönüşüm:

Önce Sonra
1× Hayır (Diğer) 1× Evet (Casey) + 1× Evet (McCormick)

Bu ilişki API'de açıkça belirtilir:

{
  "negRisk": true
}
Enter fullscreen mode Exit fullscreen mode

Ve emir oluşturulurken de gönderilmelidir:

const orderOptions = {
  tickSize: "0.01",
  negRisk: true,
};
Enter fullscreen mode Exit fullscreen mode

Bunu kendi API tasarımınızda uygulamak için alan değişmezlerini belirleyin:

  • Aynı anda yalnızca bir sonuç kazanabilir mi?
  • Bir kaynağın toplamı sabit mi?
  • Bazı durum geçişleri yasak mı?
  • Bir nesnenin başka bir nesneyle zorunlu ilişkisi var mı?
  • Yanlış varsayım finansal veya operasyonel hataya yol açar mı?

Bu kuralları yalnızca dokümantasyonda açıklamak yerine API sözleşmesine ekleyin:

{
  "type": "exclusive_outcome_event",
  "requiresCapitalRelationshipHandling": true,
  "negRisk": true
}
Enter fullscreen mode Exit fullscreen mode

Böylece istemci geliştiricileri bu bilgiyi görmezden geldiğinde sessizce yanlış davranmak yerine, bilinçli olarak ele almak zorunda kalır.


Model 7: Dinamik Piyasa Parametrelerini Gerçek Zamanlı Durum Olarak Yayınlayın

Polymarket'te tick boyutu sabit bir yapılandırma değildir. Piyasa fiyatı aşırı uçlara yaklaştığında değişebilir.

Fiyat 0.96 üzerinde veya 0.04 altında olduğunda minimum tick boyutu 0.01 değerinden 0.001 değerine düşebilir:

{
  "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

Bu değişiklik neden gereklidir?

0.04 → 0.03 = %25 göreli fiyat hareketi
Enter fullscreen mode Exit fullscreen mode

Fiyatlar uç değerlerdeyken 0.01 hassasiyeti, anlamlı olasılık farklarını ifade etmek için fazla kaba olabilir. 0.001 tick boyutu daha hassas fiyat keşfi sağlar.

İstemci uygulamasında tick boyutunu sabit kodlamayın:

let currentTickSize = "0.01";

function onTickSizeChange(event: {
  asset_id: string;
  new_tick_size: string;
}) {
  currentTickSize = event.new_tick_size;
}
Enter fullscreen mode Exit fullscreen mode

Emir göndermeden önce fiyatı güncel tick boyutuna göre doğrulayın:

function isValidPrice(price: number, tickSize: number) {
  const steps = price / tickSize;
  return Number.isInteger(Number(steps.toFixed(10)));
}

const valid = isValidPrice(0.973, Number(currentTickSize));
Enter fullscreen mode Exit fullscreen mode

Aksi halde istemciniz geçersiz fiyat adımlarıyla emir gönderebilir ve emir reddedilebilir.

Genel prensip şudur:

Değişebilen bir parametre, yalnızca yapılandırma değildir; istemcilerin takip etmesi gereken bir durumdur.

Bu nedenle API'niz, durum geçişlerini açık olaylar olarak yayınlamalıdır.


Model 8: Farklı Gerçek Zamanlı Tüketiciler İçin Ayrı WebSocket Katmanları Kullanın

Polymarket iki ayrı WebSocket sistemi kullanır.

Piyasa kanalı

Piyasa kanalı, ticaret odaklı tüketiciler içindir:

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

Token kimliğine göre abone olunur:

{
  "assets_ids": [
    "65818619657568813474341868652308942079804919287380422192892211131408793125422"
  ],
  "type": "market"
}
Enter fullscreen mode Exit fullscreen mode

Bu kanal; emir defteri anlık görüntüleri, fiyat değişimleri, işlem gerçekleşmeleri ve tick boyutu değişiklikleri gibi veriler taşır.

Gerçek zamanlı veri soketi

Diğer kanal, sosyal ve genel veri tüketicilerine yöneliktir:

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

Konu bazlı abonelik kullanır:

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

Bu akış; yorumlar, Binance ve Chainlink kaynaklı kripto fiyatları, hisse senedi fiyatları ve sosyal etkileşim olayları gibi farklı veri türlerini taşır.

Bu ayrım önemlidir çünkü tüketici ihtiyaçları farklıdır:

Tüketici Veri ihtiyacı Gecikme hassasiyeti
Piyasa yapıcı Emir defteri ve işlem güncellemeleri Çok yüksek
Ticaret botu Fiyat, likidite ve tick değişimi Yüksek
Kullanıcı arayüzü Yorumlar, sosyal etkinlik, özet veri Orta
Analitik ekranı Fiyat akışları ve olay güncellemeleri Orta

Tek bir WebSocket uç noktasına her şeyi yüklemek genellikle iki soruna yol açar:

  1. Sosyal veya genel veri akışını gereksiz düşük gecikme gereksinimleriyle aşırı karmaşık hale getirmek
  2. Ticaret verisini, genel amaçlı akışların hata ve ölçek varsayımlarına mahkûm etmek

Gerçek zamanlı sistem tasarlarken şu soruları sorun:

  • Tüm aboneler aynı gecikme hedefini mi paylaşıyor?
  • Tüm veri türleri aynı güvenilirlik seviyesini mi gerektiriyor?
  • Tüm mesajlar aynı hacimde mi akıyor?
  • Bir kanalın gecikmesi diğer kanalın işlevini etkiler mi?

Yanıt “hayır” ise, ayrı akışlar ve ayrı altyapılar düşünün.


Uygulanabilir Tasarım Kontrol Listesi

Tahmin piyasası veya finansal işlem API'si tasarlarken bu kontrol listesini kullanın:

  • [ ] API'leri kaynaklara göre değil, iş alanlarına göre ayırdım mı?
  • [ ] Genel okuma erişimi ile yetkili yazma erişimini ayırdım mı?
  • [ ] Kimlik kanıtlama ve rutin istek yetkilendirmesi farklı katmanlarda mı?
  • [ ] Yüksek riskli işlemler doğrulanabilir veya imzalı yük taşıyor mu?
  • [ ] Alan modelindeki kritik ilişkiler API şemasında görünür mü?
  • [ ] İş kuralları yalnızca dokümantasyonda değil, alanlarda ve doğrulamalarda da tanımlı mı?
  • [ ] Değişebilen piyasa parametreleri gerçek zamanlı olay olarak yayınlanıyor mu?
  • [ ] Farklı gecikme ve veri hacmi ihtiyaçları olan tüketiciler için ayrı akışlar var mı?

Sonuç

Polymarket'in API tasarımı, alanın gerçek yapısını gizlemek yerine görünür kılmaya dayanır.

  • Üç API katmanı gerçek sorumluluk sınırlarını yansıtır.
  • Genel veri erişimi keşfi ve likiditeyi destekler.
  • İki seviyeli kimlik doğrulama, kimliği kanıtlama ile istek yetkilendirmesini ayırır.
  • İmzalı emirler, API çağrılarını doğrulanabilir finansal taahhütlere dönüştürür.
  • Olay/piyasa hiyerarşisi ve negRisk, sermaye ilişkilerini açık hale getirir.
  • Dinamik tick boyutları istemci durumunun piyasa durumuyla senkron kalmasını sağlar.
  • Ayrı WebSocket katmanları farklı tüketicilerin gerçek ihtiyaçlarına hizmet eder.

İyi API tasarımı yalnızca ergonomi, tutarlı isimlendirme veya tahmin edilebilir hata mesajları değildir. Özellikle finansal sistemlerde API, alanın kısıtlamalarını, durum geçişlerini ve yetkilendirme modelini doğrudan sözleşmesine yansıtmalıdır.

Top comments (0)