İstek ve yanıt kuralları
Tüm uç noktalarda geçerli ortak davranışlar: biçim, sayfalama, tekrar güvenliği ve hata gövdesi.
Biçim
| Konu | Kural |
|---|---|
| İçerik türü | application/json; charset=utf-8 |
| Alan adları | camelCase |
| Tarihler | ISO 8601, UTC (ör. 2026-09-17T09:15:00.000Z) |
| Kimlikler | UUID v4 |
| Para | Ondalık metin (ör. "0.080000") — kayan noktalı sayı değil |
| Tekil kaynak | { "data": { … } } |
| Liste | { "data": [ … ], "nextCursor": "…" | null } |
Sayfalama
Listeler imleç (cursor) ile sayfalanır: ?limit= (en fazla 100, varsayılan 50) ve ?cursor=.
Yanıttaki nextCursor boş gelene kadar devam edin.
İmleç opaktır; içeriğini yorumlamayın. Yalnızca değişenleri çekmek için ?updatedSince= parametresini
kullanın.
Node.js
let cursor;
do {
const url = new URL("/api/public/v1/contacts", process.env.APSILO_API_URL);
url.searchParams.set("limit", "100");
if (cursor) url.searchParams.set("cursor", cursor);
const res = await fetch(url, { headers: { authorization: `Bearer ${key}` } });
const { data, nextCursor } = await res.json();
for (const contact of data) process(contact);
cursor = nextCursor;
} while (cursor);Tekrar güvenliği (Idempotency)
Yazma isteklerinde (POST) Idempotency-Key başlığı gönderin. Aynı anahtar + aynı gövde ile gelen
ikinci istek yeni bir işlem başlatmaz, ilk isteğin yanıtını aynen döner — ağ hatasında güvenle tekrar
deneyebilirsiniz, mesaj iki kez gitmez.
| Durum | Sonuç |
|---|---|
| Aynı anahtar, aynı gövde | İlk isteğin yanıtı (yeni işlem yapılmaz) |
| Aynı anahtar, farklı gövde | 409 IDEMPOTENCY_CONFLICT |
| İlk istek hâlâ işleniyor | 409 IDEMPOTENCY_CONFLICT |
İstek
POST /api/public/v1/messages
Authorization: Bearer apsk_live_…
Idempotency-Key: siparis-4821-kargo-bildirimi
Content-Type: application/json
{ "channel": "whatsapp", "to": { "phone": "+90555…" }, "type": "text", "text": "…" }Anahtar 1–255 karakter, yazdırılabilir ASCII olmalıdır. Her mantıksal işlem için benzersiz bir değer üretin (ör. sipariş numarası + olay adı).
İstek kimliği
Her yanıtta X-Request-Id başlığı bulunur; hata gövdesinde de error.requestId olarak yer alır. Kendi
kimliğinizi göndermek isterseniz aynı başlıkla gönderin, korunur. Destek taleplerinde bu değeri
paylaşmanız sorunu saniyeler içinde bulmamızı sağlar.
Hata gövdesi ve kodlar
Hatalar her zaman aynı biçimdedir; HTTP durum koduna ek olarak makine tarafından okunabilir bir kod içerir:
{
"error": {
"code": "MESSAGING_WINDOW_CLOSED",
"message": "WhatsApp mesajlaşma penceresi kapandı: onaylı şablon kullanın.",
"details": [{ "path": "channel", "message": "Pencere dışı" }],
"requestId": "01J9Z5K2F3R7QW8N"
}
}| Kod | HTTP | Ne zaman |
|---|---|---|
VALIDATION_FAILED | 422 | Gövde veya parametreler şemaya uymuyor; details alanı hangi alanın hatalı olduğunu söyler. |
UNAUTHORIZED | 401 | Anahtar gönderilmedi ya da biçimi hatalı. |
API_KEY_INVALID | 401 | Anahtar tanınmıyor. |
API_KEY_REVOKED | 401 | Anahtar panelden iptal edilmiş. |
API_KEY_EXPIRED | 401 | Anahtarın son kullanma tarihi geçmiş. |
FORBIDDEN | 403 | Anahtarın bu işlem için kapsamı yok. |
FEATURE_NOT_LICENSED | 403 | Firma lisansında bu özellik/kanal kapalı. |
LICENSE_EXPIRED | 403 | Firmanın lisansı sona ermiş; gönderim durur. |
NOT_FOUND | 404 | Kayıt yok ya da bu firmaya ait değil. |
CONFLICT | 409 | Kaynak çakışması (ör. aynı isimde şablon). |
IDEMPOTENCY_CONFLICT | 409 | Aynı Idempotency-Key farklı bir gövdeyle kullanılmış ya da önceki istek hâlâ işleniyor. |
MESSAGING_WINDOW_CLOSED | 422 | Kanalın mesajlaşma penceresi kapalı; WhatsApp’ta onaylı şablon kullanın. |
INSUFFICIENT_BALANCE | 402 | Cüzdan bakiyesi yetersiz. |
RATE_LIMITED | 429 | Dakikalık istek sınırı aşıldı. |
PROVIDER_ERROR | 502 | Sağlayıcı hata döndürdü; genellikle tekrar denenebilir. |
Tekrar deneme önerisi
429 ve 5xx yanıtlarında üstel bekleme ile tekrar deneyin (ör. 1s, 2s, 4s, 8s; en fazla 5 deneme).
4xx yanıtları (429 hariç) isteğin kendisiyle ilgilidir; aynı gövdeyle tekrar denemek sonucu
değiştirmez.