Entegrasyon
REST API
Kendi sistemleriniz, yönetim panelinde oluşturduğunuz API anahtarlarıyla Core API’yi çağırabilir. Uçların tamamı API referansında listelenir.
#Temel adres
Tüm uçlar sürümlü yol altındadır:
https://api.2people.chat/api/v1İstek ve yanıt gövdeleri JSON’dur (alan adları camelCase); dosya yükleyen birkaç uç multipart/form-data, dışa aktarma uçları CSV veya düz metin döner. Kimlikler UUID’dir. Tanımlanmamış alanlar gönderilirse istek reddedilir.
#API anahtarı oluşturma
API anahtarları sayfasını açın
Yönetim panelinde tenant’ınızın API anahtarları sayfasına gidin (
settings:writeyetkisi gerekir).Ad, son kullanma tarihi ve kapsamları seçin
Kapsamlar tenant yetkileridir (ör.
conversations:read,analytics:read). Yalnızca kendinizde olan yetkileri verebilirsiniz.members:writeveroles:writehiçbir anahtara verilemez; kişi ve rol yönetimi yalnızca panelden yapılır. Son kullanma tarihi isteğe bağlıdır.Sırrı kopyalayın
Anahtar (
tpk_…) yalnızca bir kez gösterilir; platform yalnızca özetini saklar. Listede yalnızca önek (tpk_<önek>), kapsamlar ve son kullanım zamanı görünür.
#Kimlik doğrulama
Her istekte iki başlık gönderin:
| Başlık | Değer |
|---|---|
Authorization | Bearer tpk_… |
X-Tenant-Id | Tenant kimliği (UUID). Yönetim panelinde tenant sayfasının adresinde görünür (/tenants/<id>). Tenant’ı yolda taşıyan uçlarda (ör. /tenants/{id}) gerekmez. |
curl "https://api.2people.chat/api/v1/conversations?view=open&limit=25" \
-H "Authorization: Bearer $TWOPEOPLE_API_KEY" \
-H "X-Tenant-Id: $TWOPEOPLE_TENANT_ID"- Anahtarlar yalnızca bir yetki gerektiren uçlara erişebilir; oturum ve profil uçları (
/megibi) ile platform uçları anahtarlara kapalıdır. - İptal edilen, süresi dolan veya askıya alınmış tenant’a ait anahtarlar reddedilir.
- API tarayıcıdan çağrılmak için tasarlanmamıştır (CORS yalnızca platformun kendi uygulamalarına açıktır); anahtarları yalnızca sunucuda kullanın.
#Hatalar
Hatalar application/problem+json (RFC 9457) biçimindedir. Her gövdede kararlı, BÜYÜK_HARF bir code ve isteğin correlationId’si bulunur. Kodunuzda code alanına göre karar verin; title ve detail metinleri değişebilir.
HTTP/1.1 400 Bad Request
Content-Type: application/problem+json
X-Correlation-Id: 3f2c9a7e-…
{
"type": "https://docs.2people.chat/problems/validation-failed",
"title": "Bad Request",
"status": 400,
"code": "VALIDATION_FAILED",
"correlationId": "3f2c9a7e-…",
"errors": [
{ "path": "limit", "message": "limit must not be greater than 100" }
]
}| HTTP | code | Anlamı |
|---|---|---|
| 400 | VALIDATION_FAILED | Geçersiz veya bilinmeyen alan; ayrıntılar errors[] içinde. |
| 400 | TENANT_CONTEXT_REQUIRED | X-Tenant-Id başlığı eksik. |
| 401 | UNAUTHENTICATED | Anahtar eksik, geçersiz, süresi dolmuş veya iptal edilmiş. |
| 403 | FORBIDDEN | Anahtarın bu uç için gereken kapsamı yok veya uç API anahtarlarına kapalı. |
| 404 | TENANT_NOT_FOUND | Tenant yok ya da anahtar bu tenant’a ait değil (ikisi aynı yanıtı verir). |
| 404 | ROUTE_NOT_FOUND | Böyle bir uç yok. |
| 409 | CONFLICT | Çakışma (ör. aynı değer zaten var). Bazı uçlar daha özel kodlar döner. |
| 429 | RATE_LIMITED | Hız sınırı aşıldı. |
| 500 | INTERNAL | Beklenmeyen hata; correlationId ile bize bildirin. |
İsteğe kendi X-Correlation-Id değerinizi (8–128 karakter; harf, rakam ve . _ : -) ekleyebilirsiniz; aynı değer yanıtta ve hata gövdesinde döner. Aksi hâlde platform bir kimlik üretir.
#Sayfalama
Liste uçları imleç (cursor) ile sayfalanır: limit (1–100, varsayılan 25) ve bir önceki yanıttan gelen opak cursor. Yanıt { items, nextCursor } biçimindedir; nextCursor null ise son sayfadasınız. İmleci çözümlemeye ya da üretmeye çalışmayın. Hangi uçların bu parametreleri aldığı API referansında görünür.
const BASE = 'https://api.2people.chat/api/v1';
const headers = {
Authorization: `Bearer ${process.env.TWOPEOPLE_API_KEY}`,
'X-Tenant-Id': process.env.TWOPEOPLE_TENANT_ID,
};
// Walks every page of a cursor-paginated list.
async function* listAll(path, params = {}) {
let cursor;
do {
const query = new URLSearchParams({ ...params, limit: '100', ...(cursor ? { cursor } : {}) });
const res = await fetch(`${BASE}${path}?${query}`, { headers });
if (!res.ok) {
const problem = await res.json(); // application/problem+json
throw new Error(`${problem.code}: ${problem.detail ?? problem.title} (${problem.correlationId})`);
}
const page = await res.json();
yield* page.items;
cursor = page.nextCursor;
} while (cursor);
}
for await (const conversation of listAll('/conversations', { view: 'closed' })) {
console.log(conversation.id, conversation.status);
}#Hız sınırları
Varsayılan sınır, istemci IP adresi başına dakikada 300 istektir. Sınır aşıldığında 429 ve RATE_LIMITED döner; bir süre bekleyip artan aralıklarla yeniden deneyin.
#API referansı
Her ucun yöntemi, yolu, gereken yetkisi, parametreleri, istek gövdesi ve yanıtları API referansında yer alır.