Olay Gönderimi
events/batch sözleşmesi, sınırlar ve yanıtlar
Olay toplu gönderim ucu, widget'ın ve mobil SDK'nın ölçümünü Selwise'a taşıyan tek yoldur. Widget'ı kullanıyorsanız bunu çağırmazsınız; sunucu tarafı ya da kendi istemcinizi yazıyorsanız bu sayfa sözleşmedir. Olay adları ve her olayın alanları için Event Referansı sayfasına bakın.
Uç nokta
POST /api/v1/public/sites/:siteKey/events/batch
Content-Type: application/json
- Kimlik: Yok. Yalnızca site anahtarının var olması ve kanalın doğrulanmış olması denetlenir;
Originya da API anahtarı aranmaz. Ayrıntı: Kimlik Doğrulama ve Erişim. - Sınır: IP başına dakikada 1000 istek (
X-RateLimit-*başlıkları); ayrıca bir ziyaretçi ya da oturum (gövdedekivisitorId, yoksasessionId) başına dakikada 120 istek ve aynı kanalda bir IP için dakikada 1200 istek. Aşılırsa429veRetry-Afterdöner. - Gövde sınırı: İstek başına en çok 200 olay, olay başına en çok 2 KB
metadata.
İstek
curl -X POST https://api.selwise.com/api/v1/public/sites/SITE_KEY/events/batch \
-H "Content-Type: application/json" \
-d '{
"requestId": "rid_lz3k1p_9f2a4c1d8e7b6a50",
"sessionId": "SESSION_ID",
"visitorId": "VISITOR_ID",
"siteUserId": "MUSTERI-1001",
"journeyId": "journey_VISITOR_ID_1767312000000",
"pageUrl": "https://magaza.com/urun/sku-123",
"referrer": "https://google.com",
"consentSnapshot": { "granted": true, "categories": { "necessary": true, "analytics": true, "marketing": false, "preferences": true }, "timestamp": 1767312000000, "source": "banner" },
"events": [
{
"eventId": "evt_8c1f2d",
"entityType": "product",
"name": "product_view",
"productItemCode": "SKU-123",
"metadata": { "price": 149.9, "currency": "TRY" },
"eventTs": 1767312000123,
"journeySequence": 3
}
]
}'
Üst düzey alanlar
| Alan | Zorunlu | Açıklama |
|---|---|---|
requestId | Evet | İstemcinin ürettiği, istek başına benzersiz kimlik. Kaydedilir; boş olamaz |
sessionId | Evet | Oturum kimliği |
consentSnapshot | Evet | O anki onay durumunun anlık görüntüsü; aşağıda |
events | Evet | En az 1, en çok 200 olay |
visitorId | Hayır | Kalıcı anonim ziyaretçi kimliği. Hız sınırı bu alana göre sayılır |
siteUserId | Hayır | identify ile verdiğiniz müşteri kimliği; en çok 64 karakter olmalıdır |
journeyId | Hayır | Bu olayları bir yolculuğa bağlar. Olay düzeyindeki journeyId bunu ezer |
pageUrl, referrer | Hayır | pageUrl verilmezse Referer başlığı kullanılır |
testMode | Hayır | true ise yalnızca test modundaki senaryoların girişi buna bakar; başka hiçbir davranış değişmez |
consentSnapshot
| Alan | Zorunlu | Açıklama |
|---|---|---|
granted | Evet | boolean. Ziyaretçi bir cevap verdiyse (reddetmek dahil) ya da kanalda onay denetimi kapalıysa true; cevap hâlâ bekleniyorsa false |
categories | Hayır | necessary, analytics, marketing, preferences anahtarlarıyla boolean değerler |
timestamp | Hayır | Milisaniye cinsinden epoch. Verilmezse sunucu zamanı |
source | Hayır | banner, api gibi bir etiket. Verilmezse client |
granted: false olan batch hiçbir şey kaydetmez
consentSnapshot.granted false ise olaylar doğrulanır ama saklanmaz ve yanıt HTTP 200 ile success: false döner. false "henüz sorulmadı" demektir; bir ret granted: true ve categories içinde analytics: false olarak taşınır. Kategori bazında süzme (hangi olayın hangi kategoriye girdiği) istemcinin işidir: sunucu categories değerini kaydeder ama olayları buna göre elemez. Sunucudan olay gönderiyorsanız ziyaretçinin gerçek kararını taşıyın ve izin vermemiş bir ziyaretçi için analitik olay göndermeyin; izin sorumluluğu sizdedir. Bkz. Onay Yönetimi.
Olay alanları
| Alan | Zorunlu | Açıklama |
|---|---|---|
name | Evet | Olay adı. Küçük harfe çevrilir. Bilinen bir kanonik ad değilse custom_event olarak kaydedilir ve uyarı döner |
entityType | Evet | Genelde page, product, basket, checkout, user, search, campaign, recommendation, script ya da custom. Boşsa custom olarak kaydedilir |
eventId | Önerilir | Olay başına benzersiz kimlik; tekilleştirme anahtarıdır. Verilmezse sunucu üretir ve uyarı döner, ama bu durumda yeniden gönderim çift kayıt yaratır |
entityId | Hayır | Kampanya ve öneri olaylarında varlığın kimliği (UUID); ürün olaylarında ürün kodu |
productItemCode | Ürün olaylarında | Ürün beslemenizdeki item_code ile birebir aynı olmalı |
metadata | Hayır | En çok 2 KB (JSON olarak). Fiyat, para birimi, miktar gibi olaya özel alanlar |
eventTs | Hayır | Olayın gerçekleştiği an, milisaniye epoch. Yoksa timestamp, yoksa sunucu zamanı |
journeyId, journeySequence | Hayır | Yolculuk içindeki sıra (1, 2, 3 ...). Sıra geri giderse uyarı günlüğe yazılır; olay yine kaydedilir |
correlationId, parentEventId | Hayır | Atıf için olayları birbirine bağlar |
eventSchemaVersion | Hayır | Tam sayı, varsayılan 1 |
name içinde <script, javascript:, onclick= gibi kalıplar ve <iframe, <embed, <object bulunması tüm isteği 400 yapar. Eski adlar kanonik karşılıklarına çevrilir (checkout_start → checkout_begin, order_completed → purchase, login → user_login, sign_up → user_signup ...) ve uyarı döner.
Ürün olayları (product_view, product_click, product_impression, product_dwell_time, add_to_cart, remove_from_cart, purchase, wishlist) için ürün kodu yoksa olay yine kaydedilir ama degraded işaretlenir. metadata içinde productId, productSku, sku ve olayda type, campaignId, widgetId kullanımdan kalkmıştır; kabul edilir ama uyarı döner.
Yanıt
{
"success": true,
"accepted": 2,
"degraded": 1,
"rejected": 0,
"processed": 2,
"failed": 0,
"queued_for_forwarding": 0,
"results": [
{ "eventId": "evt_8c1f2d", "success": true, "validationStatus": "valid" },
{
"eventId": "evt_a91b07",
"success": true,
"degraded": true,
"validationStatus": "degraded",
"warning": "Missing productItemCode for event: add_to_cart",
"warnings": ["Missing productItemCode for event: add_to_cart"]
}
]
}
| Alan | Anlamı |
|---|---|
success | Hiçbir olay reddedilmediyse true |
accepted ve processed | Kaydedilen olay sayısı (ikisi aynı değeri taşır) |
degraded | Kaydedilen ama uyarı taşıyan olay sayısı |
rejected ve failed | Kaydedilmeyen olay sayısı (ikisi aynı değeri taşır) |
queued_for_forwarding | Etkin entegrasyonlara ve webhook'lara iletilmek üzere sıraya alınan kayıt sayısı |
results[] | Olay başına sonuç |
results[] içinde bir olay için şunlar olabilir:
| Alan | Ne zaman |
|---|---|
success: true | Kaydedildi |
duplicate: true | Aynı eventId son 6 saat içinde zaten işlendi; yeniden kaydedilmedi. Yeniden gönderim güvenlidir |
degraded: true, warning, warnings[] | Kaydedildi ama bir şey düzeltildi (bilinmeyen ad, eksik ürün kodu, eksik eventId ...) |
success: false, error | Kaydedilmedi; error nedeni söyler |
HTTP 200 ama success: false
Aşağıdaki durumların hepsi HTTP 200 döner. Ağ sekmesinde yalnızca durum koduna bakmak bunları başarı gösterir:
| Durum | Gövde |
|---|---|
| Site anahtarı yok ya da kanal doğrulanmamış | { "success": false } |
consentSnapshot.granted false | { "success": false, "accepted": 0, "rejected": N, "results": [ { "eventId": "...", "success": false, "error": "consent not granted: event dropped" } ] } |
| Bir olay yazılamadı | O olayın results satırı success: false ve error taşır; diğerleri kaydedilir |
Hatalar
| Durum | Ne zaman |
|---|---|
400 | Gövde geçersiz: message: "Validation failed" ve errors[] (her biri events.0.name: ... gibi alan yolu). Zorunlu alan eksik, bilinmeyen alan var, metadata 2 KB'tan büyük, consentSnapshot.granted boolean değil |
400 | Batch must contain at least one event ya da Batch size exceeds maximum of 200 events |
429 | Hız sınırı. Gövde { "error": "Too Many Requests", "message": "Rate limit exceeded. Please try again later.", "retryAfter": 12 }, başlık Retry-After saniyedir |
503 | Veritabanı bağlantı havuzu dolu; Retry-After ile aynı isteği yeniden deneyin |
Tek bir olayın hatası tüm isteği 400 yaptığı için (sınıf doğrulaması), şüpheli bir olayı ayırmak için errors[] içindeki indeksi (events.2.metadata) kullanın.
Yeniden deneme ve tekilleştirme
- Her olaya kalıcı bir
eventIdverin. Ağ hatasında aynı batch'i aynıeventId'lerle yeniden gönderin; son 6 saat içinde işlenmiş olaylarduplicate: truedöner ve çift sayılmaz. 429ve503'teRetry-Afterkadar bekleyin, sonra yeniden deneyin.400'ü yeniden denemek bir işe yaramaz; gövdeyi düzeltin.- Gönderimi 50-200 olayluk gruplara toplayın; olayları tek tek göndermek hız sınırına çarpar. Widget'ın kendisi de olayları toplayıp tek istekte gönderir ve sayfa kapanırken kalanını
sendBeaconile yollar.
Sunucudan olay gönderirken
Bu uç Origin istemediği için sunucudan doğrudan çağrılabilir. Dikkat edin:
visitorIdvesessionIdtarayıcıda üretilenlerdir. Sunucudan gönderdiğiniz olayı bir ziyaretçiye bağlamak istiyorsanız bunları sipariş sırasında oturumdan taşıyın; yoksa her çağrı yeni bir ziyaretçi sayılır.- Gelir ve satın alma sayıları için olay yerine Sipariş API'si kullanın; sipariş ucu tek doğru kaynaktır.
- Satın alma olayı (
purchase) ile sipariş aynı alışverişi ikinci kez saymasın:ordersucundaskipPurchaseEvent: trueya da yalnızca birini kullanın.
İstemci sağlık sayaçları: metrics
POST /api/v1/public/sites/:siteKey/metrics
Widget'ın kendi sağlık sayaçlarını (düşen olay, başarısız batch, sendBeacon hataları) gönderdiği uçtur. Gövde { "name": "...", "value": 1 } ya da { "metrics": { "eventsDropped": 0, "batchesFailed": 0 } } biçimindedir. Yanıt { "success": true } ya da { "success": false } döner. Kalıcı bir yere yazılmaz: sayaçlar yalnızca sunucu günlüğüne düşer, panelde görünmez. Normal entegrasyonda elle çağırmanız gerekmez.
Sırada ne var
- Event Referansı — olay adları ve alanları
- Sipariş API'si
- Takip Sorunları — "olaylarım gelmiyor" teşhisi
Son güncelleme: 10 Ekim 2026