Ana içeriğe geç

Kampanyalar API

Sunucu anahtarı. Mutasyonlar için campaigns:write, istatistik için campaigns:read.

POST /v1/campaigns — taslak oluştur

Idempotency-Key kabul eder.

{
"name": "Hafta sonu indirimi",
"content": { "tr": { "title": "…", "body": "…" }, "en": { "title": "…", "body": "…" }, "_default": "tr" },
"segment": { "field": "tags.marketingOptIn", "op": "eq", "value": true },
"schedule": { "type": "at", "at": "2026-10-03T07:00:00Z" },
"data": { "screen": "sale" },
"ttl": 259200, "collapseId": "weekend-sale", "priority": "high",
"presentation": { "sound": "default", "threadId": "promotions" },
"bypass": { "frequencyCap": false },
"experiment": {
"sampleRate": 0.5,
"variants": [
{ "id": "a", "name": "Kontrol", "weight": 1, "content": { "tr": { "title": "…", "body": "…" }, "_default": "tr" } },
{ "id": "b", "name": "Emoji", "weight": 1, "content": { "tr": { "title": "… ⚡", "body": "…" }, "_default": "tr" } }
]
}
}
AlanNotlar
name1–200 karakter, içsel
contenttemplateId ya da silent: true verilmediyse zorunlu; deneyde yedek
templateIdbir şablondan başla; istek alanları şablonunkileri ezer
segmentherkes için atlayın
segmentIdbir kayıtlı segment; segment ile birlikte değil. Gönderim anında kopyalanır.
schedule{type:"now"} (varsayılan) · {type:"at", at} · {type:"user_timezone", localTime:"HH:MM"} · {type:"recurring", every:"day"|"week", daysOfWeek?, localTime, timezone, until?}
silentarka plan push'u, içerik gerekmez; web atlanır. Bkz. Sessiz push
experiment2–4 varyant; bkz. A/B testi. silent ile değil.
gerisiBildirimler'deki gibi

201 { "id": "66f3…", "status": "draft" }. Henüz hiçbir şey gönderilmedi.

POST /v1/campaigns/:id/send

Gövde yok. draft ya da scheduled'dan:

  • zamanlama now202 { "status": "sending" }, fan-out kuyrukta;
  • at / user_timezone202 { "status": "scheduled" }, gecikmeli iş olarak tutulur;
  • recurring202 { "status": "active" }, bir job scheduler kurulur ve her tetiklenme bir gönderim (recurringOf taşıyan alt kampanya) üretir. Bkz. Zamanlama.

Kampanyanın segmentId'si varsa kayıtlı segmentin tanımı şimdi kopyalanır (segment silindiyse 404).

Kampanya başka durumdaysa ya da içeriği yoksa (metni bitmemiş panel taslağı) 409 invalid_state.

POST /v1/campaigns/:id/cancel

draft, scheduled ya da active'den → 200 { "status": "cancelled" }; gecikmeli iş ya da tekrarlayan scheduler kaldırılır. Fan-out başladıysa 409 invalid_state. Tekrarlayan kampanyanın önceden ürettiği gönderimler ayrı kampanyalardır, etkilenmez.

POST /v1/campaigns/:id/experiment/winner

{ "variant": "b" }

202 { "id": "<takip kampanyası>", "status": "sending" }. Kazanan içeriği tutulan kalana, remainderOf ile geri bağlı yeni bir kampanya olarak gönderir. Hatalar: 409 (deney değil / kalan yok / zaten gönderildi / hâlâ gönderiliyor), 422 (bilinmeyen varyant). Bkz. A/B testi.

GET /v1/campaigns/:id/stats

{
"id": "66f3…",
"status": "sent",
"stats": {
"queued": 1650, "sent": 1534, "failed": 49, "skipped": 67,
"delivered": 1396, "opened": 433, "clicked": 173,
"variants": {
"a": { "sent": 770, "failed": 24, "skipped": 30, "delivered": 700, "opened": 180, "clicked": 70 },
"b": { "sent": 764, "failed": 25, "skipped": 37, "delivered": 696, "opened": 253, "clicked": 103 }
}
},
"rates": { "delivery": 0.91, "open": 0.3102, "click": 0.1239 }
}

rates.open ve rates.click ulaşana göredir; payda 0 ise null. variants yalnızca deneylerde bulunur. Cihazlar açılma bildirdikçe sayaçlar status sent olduktan sonra da hareket eder.

Yaşam döngüsü

Public API'de GET /v1/campaigns listesi ya da DELETE yoktur; panel ikisine de admin yüzeyinden sahiptir. Oluşturduğunuz id'lerin kaydını kendiniz tutun.