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.
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"
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:
- Okuma erişimi: Keşif, fiyat görüntüleme, halka açık olay verileri
- 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
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: "..." }
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": "..."
}
Bu modeli kendi API'nize uyarlamak için:
- Yüksek güven gerektiren işlemlerde güçlü bir kimlik kanıtı isteyin.
- Bu doğrulama sonucunda sınırlı veya döndürülebilir oturum/API kimlik bilgileri üretin.
- Rutin istekleri daha hafif bir imza mekanizmasıyla doğrulayın.
- Zaman damgası kullanarak replay attack riskini azaltın.
- 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
);
SDK'nin yaptığı işlem özetle şöyledir:
- Emir verisini yapılandırır.
- EIP-712 tipli veri oluşturur.
- Veriyi kullanıcının özel anahtarıyla imzalar.
- İmzayı emir verisiyle birlikte eşleştirme motoruna gönderir.
- İş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."
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\"]"
}
]
}
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]),
}));
Sonuç:
[
{ outcome: "Yes", price: 0.42 },
{ outcome: "No", price: 0.58 }
]
İstemci tarafında şu kontrolleri ekleyin:
if (outcomes.length !== prices.length) {
throw new Error("Outcome ve fiyat dizileri eşleşmiyor.");
}
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
}
Ve emir oluşturulurken de gönderilmelidir:
const orderOptions = {
tickSize: "0.01",
negRisk: true,
};
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
}
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"
}
Bu değişiklik neden gereklidir?
0.04 → 0.03 = %25 göreli fiyat hareketi
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;
}
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));
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
Token kimliğine göre abone olunur:
{
"assets_ids": [
"65818619657568813474341868652308942079804919287380422192892211131408793125422"
],
"type": "market"
}
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
Konu bazlı abonelik kullanır:
{
"action": "subscribe",
"subscriptions": [
{
"topic": "crypto_prices",
"type": "update",
"filters": "btcusdt,ethusd"
}
]
}
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:
- Sosyal veya genel veri akışını gereksiz düşük gecikme gereksinimleriyle aşırı karmaşık hale getirmek
- 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)