API Dokümantasyonu
Planlanan genel REST API'nin taslak sözleşmesi
Aşağıdaki uçlar bugün çalışan sözleşmedir. API Enterprise planına dahildir ve anahtarı panelden siz üretirsiniz: Ayarlar → API anahtarları. Sunucudan sunucuya kullanılır; tarayıcıdan çağrılamaz.
Panelden anahtar oluşturunKapsam: Bu API okur ve mesaj gönderir. Bot oluşturma ve silme bilerek yoktur; ikisi de plan bot limitine ve faturanıza dokunur.
🚀 Başlangıç
Sunucudan sunucuya bir REST API. İstekler HTTPS üzerinden yapılır, gövde ve yanıt JSON'dur. Enterprise planına dahildir; anahtarı panelden siz üretirsiniz.
Base URL
https://idgugvpofiqyaupkwtbs.supabase.co/functions/v1/public-api/v2
Adres bugün budur. İleride özel bir alan adı eklenirse yollar ve sözleşme aynı kalacak; yalnızca kök adres değişecektir. Adresi kodunuzda tek bir yerde tutun.
Hızlı Başlangıç
curl "https://idgugvpofiqyaupkwtbs.supabase.co/functions/v1/public-api/v2/chatbots" \
-H "Authorization: Bearer sk_live_YOUR_KEY"
🔐 Kimlik Doğrulama
Her istek bir Bearer anahtarı taşır. Anahtarı panelden alırsınız: Ayarlar → API anahtarları → Anahtar oluştur. Anahtar hesabınızın tamamına erişir; botlarınızı ve konuşmalarınızı okur, mesaj gönderirken aylık mesaj hakkınızı harcar.
Authorization: Bearer sk_live_YOUR_KEY
📄 Sayfalama
Liste uçları hiçbir zaman sınırsız küme döndürmez. İki parametre alırlar: limit (varsayılan 25, en fazla 100) ve cursor — bir önceki yanıtın next_cursor değeri. İmleç kapalı bir dizedir; ayrıştırmayın.
{
"limit": 25,
"returned": 25,
"total": 143,
"has_more": true,
"next_cursor": "b2ZmOjI1"
}
🤖 Chatbots
Hesabınızdaki botları listeler. Yeniden eskiye doğru sıralanır. Sorgu parametreleri: limit, cursor.
Response
{
"success": true,
"data": [
{
"id": "6f1c9a52-...",
"name": "Destek Botu",
"description": null,
"model": "flash",
"active": true,
"messages_used": 1240,
"created_at": "2026-01-15T10:30:00Z",
"updated_at": "2026-09-02T08:11:00Z"
}
],
"pagination": {
"limit": 25,
"returned": 1,
"total": 1,
"has_more": false,
"next_cursor": null
}
}
Tek bir botu döndürür. Alanlar listedekiyle aynıdır ve yanıt data içinde tek nesnedir. Hesabınıza ait olmayan bir kimlik 404 chatbot_not_found döner.
💬 Messages
Bota bir mesaj gönderir ve yanıtı döndürür. Kabul edilen gövde alanları tam olarak dörttür.
Request Body
{
"chatbot_id": "6f1c9a52-...",
"message": "Merhaba, kargom nerede?",
"user_id": "musteri-4821",
"language": "tr"
}
chatbot_id ve message zorunludur; message en fazla 4000 karakter olabilir. user_id ve language isteğe bağlıdır. language gerçekten uygulanır: verildiğinde otomatik dil algılamanın önüne geçer.
Response
{
"success": true,
"data": {
"chatbot_id": "6f1c9a52-...",
"user_id": "musteri-4821",
"session_id": "api:musteri-4821",
"channel": "api",
"message": "Merhaba, kargom nerede?",
"reply": "Sipariş numaranızı paylaşırsanız hemen bakayım.",
"created_at": "2026-09-02T14:30:00.000Z"
}
}
🗂️ Conversations
Botlarınızın konuşmalarını listeler; en son mesaj alanına göre yeniden eskiye sıralanır. Sorgu parametreleri: limit, cursor, chatbot_id ve channel. Liste mesaj gövdelerini taşımaz — bir konuşmanın mesajları için detay ucunu kullanın.
Response
{
"success": true,
"data": [
{
"id": "0b7d41e8-...",
"chatbot_id": "6f1c9a52-...",
"channel": "whatsapp",
"user_id": "905xxxxxxxxx",
"session_id": "whatsapp:905xxxxxxxxx",
"visitor_name": null,
"visitor_email": null,
"last_message_at": "2026-09-02T13:58:00",
"created_at": "2026-08-30T09:12:00",
"updated_at": "2026-09-02T13:58:00"
}
],
"pagination": { "limit": 25, "returned": 1, "total": 1, "has_more": false, "next_cursor": null }
}
Buradaki user_id, kanalın ucundaki kişidir — sizin hesap kimliğiniz değil. POST /v2/messages ile gönderdiğiniz user_id ile aynı alandır, o yüzden API'den açtığınız konuşmaları bu alandan eşleyebilirsiniz.
Tek bir konuşmayı, mesaj geçmişiyle döndürür. Liste alanlarına ek olarak message_count, messages ve messages_truncated taşır.
message_limit parametresi kaç mesaj döneceğini belirler: varsayılan 100, en fazla 500 ve her zaman EN YENİ mesajlar. Geçmişin tamamı dönmediyse messages_truncated true olur; message_count gerçek toplamı verir.
📊 Analytics
Hesabın kullanım özeti. Tek sorgu parametresi days: varsayılan 30, en fazla 90. Yanıt üç bloktan oluşur: account, chatbots ve usage.
Response
{
"success": true,
"data": {
"account": {
"plan": "enterprise",
"plan_version": 2,
"subscription_status": "active",
"messages_used": 4120,
"messages_limit": 25000,
"plan_message_limit": 20000,
"plan_bot_limit": 20,
"message_credits": 0
},
"chatbots": [
{
"id": "6f1c9a52-...",
"name": "Destek Botu",
"active": true,
"messages_used_total": 1240,
"messages_in_window": 310
}
],
"usage": {
"window_days": 30,
"from": "2026-08-03T14:30:00.000Z",
"to": "2026-09-02T14:30:00.000Z",
"covers_from": "2026-08-03T14:30:00.000Z",
"truncated": false,
"row_cap": 5000,
"total_messages": 310,
"total_tokens": 184320,
"total_cost_usd": 1.284213,
"by_day": [
{ "day": "2026-08-03", "messages": 12 }
]
}
}
}
🔔 Giden webhook’lar
Sayfanın geri kalanı taslaktır; buradaki sözleşme bugün çalışan koddur. Business ve Enterprise planlarında kullanılabilir ve panelden, botun webhook ayarından kurulur — kurulum için çağırabileceğiniz bir REST ucu yoktur.
Botunuz bir talep ya da randevu yakaladığında, sizin belirlediğiniz https adresine imzalı bir JSON POST gönderiyoruz. Bağlantı tek yönlüdür: çağrıyı biz yaparız, siz bize çağrı yapmazsınız.
Gönderilen olaylar
request.created— bot bir talep yakaladıktan ve kayıt yazıldıktan sonra gönderilir.appointment.created— bot bir randevu yakaladıktan ve kayıt yazıldıktan sonra gönderilir.webhook.test— panelden test gönderimini siz başlattığınızda gönderilir. Abone olunacak bir olay değildir; gövdesi gerçek bir request.created ile aynı biçimdedir ve is_test alanı taşır.
Başlıklar
POST https://example.com/synaptix
Content-Type: application/json
User-Agent: Synaptix-Webhooks/1.0
X-Synaptix-Event: request.created
X-Synaptix-Delivery: 6d0f1c2e-6a1f-4f4a-9a8d-2f7c5b1ea91b
X-Synaptix-Signature: sha256=<lowercase hex>
X-Synaptix-Delivery her deneme için yeniden üretilir ve gövdedeki delivery_id ile aynı değerdir. Tekilleştirme yapacaksanız bu değeri değil data.id alanını kullanın: aynı kayıt yeniden gönderilirse teslimat kimliği değişir, kayıt kimliği değişmez.
Webhook Payload
Zarf her olayda aynıdır; olaya göre değişen tek alan data’dır. Aşağıda bir request.created gövdesi var.
{
"event": "request.created",
"delivery_id": "6d0f1c2e-6a1f-4f4a-9a8d-2f7c5b1ea91b",
"created_at": "2026-09-09T12:04:11.482Z",
"bot_id": "1f0b6d5e-2a44-4c9f-8b21-9e6a2f3c7d10",
"data": {
"id": "9c1a7f22-4d63-4b0e-9d61-3a8f5c2b7e04",
"request_type": "lead_collection",
"status": "new",
"message": "Fiyat listesi alabilir miyim?",
"visitor_name": "Ada Yılmaz",
"visitor_email": "ada@example.com",
"visitor_phone": null,
"source_page_host": "example.com",
"created_at": "2026-09-09T12:04:11.101Z"
}
}
appointment.created olayında zarf aynı kalır, data alanı ise şu alanları taşır:
{
"id": "2b7d4f10-9c33-4a6e-8f52-71c0d9ab3e64",
"request_id": "9c1a7f22-4d63-4b0e-9d61-3a8f5c2b7e04",
"status": "pending",
"message": "Cuma 14:30 için randevu",
"visitor_name": "Ada Yılmaz",
"visitor_email": "ada@example.com",
"visitor_phone": "+90 555 000 00 00",
"appointment_date": "2026-09-11",
"appointment_time": "14:30",
"appointment_at": "2026-09-11T11:30:00Z",
"source_page_host": "example.com",
"created_at": "2026-09-09T12:04:11.101Z"
}
İmzayı doğrulama
İmza şudur: HMAC-SHA256(imza anahtarınız, gövdenin ham baytları), küçük harfli hex. Başlıkta “sha256=” önekiyle taşınır. Aşağıdaki iki örnek doğrudan kendi ucunuza yapıştırılabilir.
Ham gövde şarttır. Gövdeyi ayrıştırıp yeniden JSON’a çevirirseniz anahtar sırası ve boşluklar değişir; imza o an tutmaz. Doğrulamayı ayrıştırmadan önce, aldığınız baytların üzerinde yapın.
const crypto = require('crypto');
const express = require('express');
const app = express();
// express.raw: the signature covers the bytes we sent, so the handler
// must see the raw body and not a re-serialised object.
app.post('/synaptix', express.raw({ type: 'application/json' }), (req, res) => {
const expected = 'sha256=' + crypto
.createHmac('sha256', process.env.SYNAPTIX_WEBHOOK_SECRET)
.update(req.body)
.digest('hex');
const received = req.get('X-Synaptix-Signature') || '';
const a = Buffer.from(expected, 'utf8');
const b = Buffer.from(received, 'utf8');
// timingSafeEqual throws when the lengths differ, so length is checked
// first - and it is checked in constant time for equal-length input.
if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
return res.status(401).send('invalid signature');
}
const payload = JSON.parse(req.body.toString('utf8'));
// payload.event, payload.delivery_id, payload.bot_id, payload.data
res.sendStatus(200);
});
import hashlib
import hmac
import os
from flask import Flask, request
app = Flask(__name__)
SECRET = os.environ["SYNAPTIX_WEBHOOK_SECRET"].encode("utf-8")
@app.post("/synaptix")
def synaptix():
raw = request.get_data() # bytes, exactly as received
expected = "sha256=" + hmac.new(SECRET, raw, hashlib.sha256).hexdigest()
received = request.headers.get("X-Synaptix-Signature", "")
# compare_digest is constant time and safe on unequal lengths.
if not hmac.compare_digest(expected, received):
return "invalid signature", 401
payload = request.get_json()
# payload["event"], payload["delivery_id"], payload["bot_id"], payload["data"]
return "", 200
Adres kuralları
Adres https olmalı ve genel internetten erişilebilen bir konağı göstermelidir. İsteği biz gönderdiğimiz için adres bizim ağ bağlamımızdan çözülür; bu yüzden localhost ve IPv6 karşılığı, 10.x, 172.16–31.x, 192.168.x, 169.254.x, IPv4’e eşlenmiş geri döngü adresleri, Synaptix’in kendi sunucuları ve içinde kullanıcı adı ya da parola taşıyan adresler kabul edilmez. Kendi ağınızın içindeki bir uca ulaşamayız.
Teslimat başarısız olursa
Uç noktanız 2xx dönmelidir. 3xx de başarısızlık sayılır: yönlendirmeyi takip etmiyoruz, çünkü https bir adresten özel bir adrese yapılan yönlendirme yukarıdaki konak kurallarını anlamsız kılardı. Her deneme sınırlı bir zaman aşımına tabidir; önce 2xx dönün, ağır işi sonra yapın. Başarılı da başarısız da her deneme kaydedilir ve panelde görünür; başarısız bir teslimat otomatik olarak tekrarlanmaz. Hiçbir durumda ziyaretçinin sohbeti bundan etkilenmez.
İmza anahtarı bir kez gösterilir
⚠️ Error Handling
Hata zarfı her uçta aynıdır ve DÜZDÜR — iç içe bir error nesnesi yoktur. error alanı makine tarafından okunacak kodu, message Türkçe ve message_en İngilizce açıklamayı taşır.
{
"success": false,
"error": "message_too_long",
"message": "Mesaj en fazla 4000 karakter olabilir.",
"message_en": "A message may be at most 4000 characters.",
"max_chars": 4000
}
Bazı hatalar zarfa ek üst düzey alanlar koyar; yukarıdaki max_chars bunlardan biridir. Diğerleri: required_plan / feature / plan (403), limit ve window_seconds (429), max_offset (400 cursor_out_of_range), chatbot_id (409), allow (405), method / path / supported_endpoints (404 unknown_endpoint), reason (402 ve 502).
Hata kodları
| Kod | Status Code | Açıklama |
|---|---|---|
missing_api_key | 401 | Authorization başlığı yok. Yanıt ayrıca WWW-Authenticate başlığı taşır. |
invalid_api_key | 401 | Anahtar tanınmadı, biçimi hatalı ya da iptal edilmiş. |
account_not_found | 401 | Anahtar geçerli ama bağlı olduğu hesap artık yok. |
plan_required | 403 | Hesabın aktif bir planı yok. Gereken plan adı required_plan alanında döner. |
plan_upgrade_required | 403 | Mevcut plan REST API'yi içermiyor. Gereken plan adı required_plan alanında döner. |
rate_limit_exceeded | 429 | Dakikalık istek sınırı aşıldı. Retry-After başlığı kaç saniye bekleneceğini söyler. |
unknown_endpoint | 404 | Böyle bir yol yok. Yanıt desteklenen uçların listesini de taşır. |
method_not_allowed | 405 | Yol doğru, yöntem yanlış. Allow başlığı kabul edilen yöntemleri verir. |
invalid_json | 400 | İstek gövdesi geçerli JSON değil. |
missing_chatbot_id | 400 | chatbot_id alanı gönderilmedi. |
missing_message | 400 | message alanı gönderilmedi ya da boş. |
message_too_long | 400 | Mesaj 4000 karakter sınırını aştı. |
invalid_cursor | 400 | Sayfalama imleci okunamadı. Yalnızca next_cursor değerini geri gönderin. |
cursor_out_of_range | 400 | 10.000 kayıt derinliğinin ötesine sayfalanamaz. Daha dar bir filtre kullanın. |
chatbot_not_found | 404 | Bu kimlikte bir bot hesabınızda yok. |
conversation_not_found | 404 | Bu kimlikte bir konuşma hesabınızda yok. |
chatbot_inactive | 409 | Bot pasif durumda ve mesaj kabul etmiyor. |
message_quota_exceeded | 402 | Aylık mesaj hakkı bitti ya da abonelik aktif değil. |
assistant_unavailable | 502 | Yanıt üretilemedi. Tekrar denenebilir. |
assistant_empty_reply | 502 | Model boş bir yanıt döndürdü. Mesaj gönderilmiş sayılmaz. |
auth_backend_unavailable | 503 | Anahtar doğrulanamadı. İstek güvenli tarafta reddedildi; tekrar deneyin. |
rate_limit_unavailable | 503 | Hız sınırı sayacı çalışmıyor. Sayamadığımız için geçirmiyoruz; tekrar deneyin. |
service_unavailable | 503 | Servis geçici olarak yanıt veremiyor. |
internal_error | 500 | Beklenmeyen bir hata. Sürerse destek ekibine bildirin. |
⏱️ Rate Limits
Sınır ANAHTAR BAŞINA dakikada 120 istektir. Pencere sabittir ve 60 saniyede bir sıfırlanır.
Rate Limit Headers
X-RateLimit-Limit: 120X-RateLimit-Remaining: 45X-RateLimit-Reset: 1789200000Retry-After: 17
İlk üç başlık BAŞARILI yanıtlarda da gönderilir; görülemeyen bir sınır, ancak 429 yediğinizde öğrendiğiniz bir tuzaktır. Retry-After yalnızca 429 yanıtında bulunur.
Bugün kullanabileceğiniz yol
Yayımlanmış bir SDK paketimiz yok. Botunuzu sitenize bağlamak için kurulum sihirbazının verdiği gömme kodunu kullanın. WhatsApp, Instagram ve Messenger bağlantısı ise yakında açılacak; o zamana kadar panelden kurulamıyor.
Web widget
Kurulum sihirbazı size tek satırlık bir script etiketi verir; sayfanıza yapıştırmanız yeterlidir.
Kurulum rehberiMeta kanalları
WhatsApp, Instagram ve Messenger tek bir bağlantıyla kurulacak ve kod yazmanız gerekmeyecek. Bu bağlantı yakında kullanıma açılacak.
Entegrasyon rehberi