Ana içeriğe geç
Version: Peki

Sessions API

Sessions API, agent'ınızı kendi ürününüzün içine koyar: uygulamanızdaki bir sohbet ekranı, SaaS panelinizdeki bir destek alanı ya da her kullanıcı için ChatGPT tarzı bir sohbet listesi. Yeni bir sohbetin ne zaman başlayacağına uygulamanız karar verir; her sohbet bir oturumdur (session). Oturumlar Inbox'ta diğer kanallardaki konuşmalar gibi API kanalıyla görünür; böylece ekibiniz takip edip devralabilir.

Temel adres: https://peki.ai/api Kimlik doğrulama: Authorization: Bearer psk_… (Kimlik doğrulama)

Nasıl çalışır​

  1. Sunucunuz kullanıcılarınızdan biri için, kendi kullanıcı kimliğinizle tanımlanan bir oturum başlatır.
  2. O kullanıcının mesajlarını oturuma gönderirsiniz.
  3. Agent'ın cevabını mesajları yoklayarak (polling) ya da yazıldıkça akış olarak alırsınız.

Oturumlar her zaman agent'ın yayındaki sürümüyle konuşur. Taslaktaki değişiklikler API'ye ancak yayınladıktan sonra ulaşır.

Uç noktalar​

YöntemYolErişimNe yapar
POST/agents/{agentId}/sessionsOkuma ve yazmaOturum başlatır
GET/agents/{agentId}/sessionsYalnızca okumaOturumları listeler
GET/sessions/{id}Yalnızca okumaBir oturumu getirir
PATCH/sessions/{id}Okuma ve yazmaOturumu yeniden adlandırır
GET/sessions/{id}/messagesYalnızca okumaMesajları listeler
POST/sessions/{id}/messagesOkuma ve yazmaMesaj gönderir (JSON ya da akış)
POST/sessions/{id}/filesOkuma ve yazmaDosya yükler
POST/sessions/{id}/feedbackOkuma ve yazmaOturumu puanlar
POST/sessions/{id}/resolveOkuma ve yazmaOturumu çözüldü olarak kapatır

Bir mesajdaki dosyayı indirmek için GET /files/{id} kullanın.

Nesneler​

Oturum​

{
"id": "671c9f20a1b2c3d4e5f60718",
"agentId": "66f1c2a9e4b0a1d2c3e4f567",
"channel": "api",
"status": "open",
"title": "Siparişim nerede?",
"preview": "10482 numaralı sipariş hâlâ gelmedi",
"customer": { "id": "user-1042", "name": "Ayşe Yılmaz" },
"createdAt": "2026-10-26T14:03:11.520Z",
"lastMessageAt": "2026-10-26T14:05:40.102Z",
"feedback": "up"
}
AlanTürAçıklama
idstringOturum kimliği.
agentIdstringOturumun konuştuğu agent.
channelstringBurada başlatılan oturumlar için api. Diğer kanallar (webchat, telegram) yalnızca onların bir konuşmasını kimliğiyle okuduğunuzda görünür.
statusstringopen ya da resolved.
titlestringVerdiğiniz başlık ya da ilk mesajın ilk 60 karakteri. Başlık oluşana kadar yer almaz.
previewstringSon müşteri mesajının başı (en fazla 200 karakter).
customer.idstringOturumu başlatırken gönderdiğiniz kendi kullanıcı kimliğiniz.
customer.namestringBiliniyorsa müşterinin adı.
createdAtstringOturumun başladığı an.
lastMessageAtstringOturumdaki son hareketin zamanı.
feedbackstringSon puan, up ya da down. Puan verilene kadar yer almaz.

Mesaj​

{
"id": "671ca0b3a1b2c3d4e5f60722",
"role": "agent",
"text": "10482 numaralı siparişiniz dün depomuzdan çıktı, perşembe günü elinizde olur.",
"status": "done",
"createdAt": "2026-10-26T14:05:43.871Z"
}
AlanTürAçıklama
idstringMesaj kimliği.
rolestringcustomer (kullanıcınız), agent (yapay zekâ) ya da team (Inbox'ta devralan ekip üyeniz).
textstringMesaj metni. Agent cevabı pending iken ya da failed olduğunda boştur.
statusstringpending (agent hâlâ yazıyor), done ya da failed.
createdAtstringMesajın oluşturulduğu an.
authorstringteam mesajlarında ekip üyesinin adı.
attachmentsarrayMesajdaki dosyalar: { id, name, contentType, size }. GET /files/{id} ile indirin.

Oturum başlatma​

POST /agents/{agentId}/sessions

Kullanıcılarınızdan biri için yeni, boş bir oturum başlatır. Uygulamanız her yeni sohbet açtığında yeni bir oturum başlatın; her mesaj için ayrı oturum gerekmez.

Gövde

AlanTürZorunluKurallar
customer.idstringEvetBu kullanıcı için kendi kimliğiniz. 1–128 karakter. Aynı kimlik Peki'de her zaman aynı müşteri demektir.
customer.namestringHayır1–120 karakter. Peki bu müşteri kimliğini ilk gördüğünde kaydedilir; sonraki oturumlar onu değiştirmez.
titlestringHayır1–120 karakter. Verilmezse ilk mesaj başlık olur.
curl -X POST https://peki.ai/api/agents/66f1c2a9e4b0a1d2c3e4f567/sessions \
-H "Authorization: Bearer $PEKI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"customer": {"id": "user-1042", "name": "Ayşe Yılmaz"}, "title": "Sipariş sorusu"}'
const res = await fetch(`https://peki.ai/api/agents/${agentId}/sessions`, {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.PEKI_API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ customer: { id: 'user-1042', name: 'Ayşe Yılmaz' } }),
});
const session = await res.json(); // { id, agentId, channel: "api", status: "open", ... }

Yanıt 201, oturum nesnesiyle.

Hatalar

DurumMesajNeden
400Invalid bodycustomer.id eksik ya da bir alan çok uzun.
404Agent not foundAgent kimliği yanlış ya da başka bir çalışma alanına ait.
409Publish the agent firstAgent'ın henüz yayınlanmış bir sürümü yok.
not

API'den gelen müşteriler Peki'de ayrı müşterilerdir; aynı kişi olsalar bile web sitesi sohbeti ve Telegram müşterilerinden ayrı tutulurlar.

Oturumları listeleme​

GET /agents/{agentId}/sessions?customer={customerId}&limit={n}

Agent'ın API oturumlarını, en son hareket edene göre sıralı listeler. Bir kullanıcıya sohbet geçmişini göstermek için kullanın.

Sorgu parametreleri

ParametreZorunluAçıklama
customerHayırKullanıcı kimliğiniz. Yalnızca o kullanıcının oturumları döner. Bilinmeyen bir kimlik boş liste döner.
limitHayırKaç tane döneceği, 1–100. Varsayılan 50.

Yalnızca API üzerinden başlatılan oturumlar listelenir; web sitesi sohbeti ve Telegram konuşmaları ya da otomasyon çalıştırmaları listelenmez.

curl "https://peki.ai/api/agents/66f1c2a9e4b0a1d2c3e4f567/sessions?customer=user-1042&limit=20" \
-H "Authorization: Bearer $PEKI_API_KEY"
const url = new URL(`https://peki.ai/api/agents/${agentId}/sessions`);
url.searchParams.set('customer', 'user-1042');
const sessions = await (await fetch(url, { headers: { Authorization: `Bearer ${key}` } })).json();

Yanıt 200, oturum dizisiyle.

Sayfalama imleci yoktur: en fazla en son 100 oturumu alırsınız. Kullanıcılarınızın daha fazla oturumu varsa kendi listenizi tutun.

Bir oturumu getirme​

GET /sessions/{id}
curl https://peki.ai/api/sessions/671c9f20a1b2c3d4e5f60718 \
-H "Authorization: Bearer $PEKI_API_KEY"

Yanıt 200, oturum nesnesiyle. Oturum çalışma alanınızda yoksa 404 Session not found.

Bu, çalışma alanınızın diğer kanallarından gelen konuşma kimlikleri için de çalışır; ör. bir otomasyonda aldığınız bir kimlik. Bunları okuyabilirsiniz, ama yalnızca API oturumları mesaj kabul eder.

Oturumu yeniden adlandırma​

PATCH /sessions/{id}
AlanTürZorunluKurallar
titlestringEvet1–120 karakter.
curl -X PATCH https://peki.ai/api/sessions/671c9f20a1b2c3d4e5f60718 \
-H "Authorization: Bearer $PEKI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title": "Geciken teslimat, sipariş 10482"}'

Yanıt 200, güncellenmiş oturum nesnesiyle.

Mesajları listeleme​

GET /sessions/{id}/messages

Oturumun tüm mesajlarını en eskiden başlayarak döner: kullanıcınızın mesajları, agent'ın cevapları ve ekibinizin cevapları.

curl https://peki.ai/api/sessions/671c9f20a1b2c3d4e5f60718/messages \
-H "Authorization: Bearer $PEKI_API_KEY"

Yanıt 200:

[
{ "id": "671ca0a1a1b2c3d4e5f60720", "role": "customer", "text": "10482 numaralı sipariş hâlâ gelmedi", "status": "done", "createdAt": "2026-10-26T14:05:40.102Z" },
{ "id": "671ca0b3a1b2c3d4e5f60722", "role": "agent", "text": "", "status": "pending", "createdAt": "2026-10-26T14:05:40.230Z" }
]

Mesaj gönderme​

POST /sessions/{id}/messages

Kullanıcınızın mesajını agent'a gönderir. Agent cevabını hemen yazmaya başlar.

Gövde

AlanTürZorunluKurallar
textstringİkisinden biriEn fazla 4.000 karakter.
attachmentsstring[]İkisinden biriDosya yükleme ile bu oturuma yüklediğiniz en fazla 5 dosya kimliği.

Bir mesajda metin, dosya ya da ikisi birden olmalıdır. Çözüldü olarak kapatılmış bir oturuma mesaj göndermek onu yeniden açar.

Cevabı almanın iki yolu var.

Seçenek 1: JSON ve yoklama​

Özel bir Accept başlığı olmadan çağrı hemen 202 ile döner:

{
"message": { "id": "671ca0a1a1b2c3d4e5f60720", "role": "customer", "text": "10482 numaralı sipariş hâlâ gelmedi", "status": "done", "createdAt": "2026-10-26T14:05:40.102Z" },
"reply": { "id": "671ca0b3a1b2c3d4e5f60722", "role": "agent", "text": "", "status": "pending", "createdAt": "2026-10-26T14:05:40.230Z" }
}

Ardından reply.id kimlikli mesajın status değeri done (ya da failed) olana kadar GET /sessions/{id}/messages uç noktasını yoklayın. 1–2 saniyede bir yoklamak yeterlidir; çoğu cevap birkaç saniye sürer, agent araç çağırdığında daha uzun.

Yapay zekâdan cevap gelmeyecekse reply değeri null olur: ekibinizden biri konuşmayı Inbox'ta devralmıştır. Onun cevapları team mesajları olarak gelir.

async function ask(sessionId, text) {
const headers = { Authorization: `Bearer ${process.env.PEKI_API_KEY}`, 'Content-Type': 'application/json' };
const base = 'https://peki.ai/api';
const sent = await (await fetch(`${base}/sessions/${sessionId}/messages`, {
method: 'POST', headers, body: JSON.stringify({ text }),
})).json();
if (!sent.reply) return null; // bir ekip üyesi devraldı
for (let i = 0; i < 60; i++) {
await new Promise((r) => setTimeout(r, 1500));
const messages = await (await fetch(`${base}/sessions/${sessionId}/messages`, { headers })).json();
const reply = messages.find((m) => m.id === sent.reply.id);
if (reply && reply.status !== 'pending') return reply;
}
throw new Error('Henüz cevap yok');
}

Seçenek 2: akış​

Accept: text/event-stream gönderin; cevap aynı bağlantı üzerinden server-sent events olarak akar. Her olay, JSON nesnesi taşıyan tek bir data: satırıdır:

typeAlanlarNe zaman
acceptedmessageİlk olay: kullanıcınızın kaydedilen mesajı.
startAgent çalışmaya başladı.
toolname, state (running, ok ya da error), durationMsAgent araçlarından birini çağırıyor. "Siparişinize bakıyorum…" göstermek için kullanın.
texttextŞu ana kadarki cevap. Her text olayı yalnızca yeni kısmı değil, o ana kadarki metnin tamamını taşır: gösterdiğinizi değiştirin, sonuna eklemeyin.
messagemessageKaydedilmiş son cevap. Bunu gösterin.
donetimedOut (yalnızca true olduğunda)Son olay. Bağlantı kapanır.
curl -N -X POST https://peki.ai/api/sessions/671c9f20a1b2c3d4e5f60718/messages \
-H "Authorization: Bearer $PEKI_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: text/event-stream" \
-d '{"text": "10482 numaralı siparişim nerede?"}'
data: {"type":"accepted","message":{"id":"671ca0a1a1b2c3d4e5f60720","role":"customer","text":"10482 numaralı siparişim nerede?","status":"done","createdAt":"2026-10-26T14:05:40.102Z"}}

data: {"type":"start"}

data: {"type":"tool","name":"get_order_status","state":"running"}

data: {"type":"tool","name":"get_order_status","state":"ok","durationMs":412}

data: {"type":"text","text":"10482 numaralı siparişiniz"}

data: {"type":"text","text":"10482 numaralı siparişiniz dün depomuzdan çıktı"}

data: {"type":"message","message":{"id":"671ca0b3a1b2c3d4e5f60722","role":"agent","text":"10482 numaralı siparişiniz dün depomuzdan çıktı, perşembe günü elinizde olur.","status":"done","createdAt":"2026-10-26T14:05:40.230Z"}}

data: {"type":"done"}
const res = await fetch(`https://peki.ai/api/sessions/${sessionId}/messages`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.PEKI_API_KEY}`,
'Content-Type': 'application/json',
Accept: 'text/event-stream',
},
body: JSON.stringify({ text: '10482 numaralı siparişim nerede?' }),
});
if (!res.ok) throw new Error(`Peki API ${res.status}: ${await res.text()}`);

const reader = res.body.pipeThrough(new TextDecoderStream()).getReader();
let buffer = '';
for (;;) {
const { value, done } = await reader.read();
if (done) break;
buffer += value;
const events = buffer.split('\n\n');
buffer = events.pop();
for (const e of events) {
if (!e.startsWith('data: ')) continue;
const event = JSON.parse(e.slice(6));
if (event.type === 'text') render(event.text); // şu ana kadarki cevabın tamamı
if (event.type === 'message') render(event.message.text); // son metin
}
}

Akış hakkında bilmeniz gerekenler:

  • Sızıntı guardrail'i açıkken text olayı gelmez. Agent'ın Guardrails ayarları cevapları gönderilmeden önce sızıntıya karşı kontrol ediyorsa metin akamaz: start, tool olaylarını ve ardından kontrol edilmiş message olayını alırsınız. Bkz. Guardrails ve gizlilik.
  • Son text olayını değil, message olayını gösterin. Guardrails ve kişisel veri işleme son cevabı değiştirebilir. message olayı kaydedilen ve ekibinizin Inbox'ta gördüğü cevaptır.
  • Ekip devralırsa akış accepted olayından hemen sonra done ile biter.
  • En fazla iki dakika. Cevap 120 saniye içinde bitmezse {"type":"done","timedOut":true} alırsınız ve akış kapanır. Cevap yine de tamamlanır; onu Mesajları listeleme ile alın.
  • Bağlantınız koparsa cevap yine tamamlanır. Onu Mesajları listeleme ile alın.
  • Agent'ın akıl yürütmesi (reasoning) asla akışa gönderilmez.

Hatalar​

DurumMesaj ya da codeNedenNe yapmalı
400Write a message or attach a filetext boş ve attachments yok.Metin ya da dosya gönderin.
400Invalid bodytext 4.000 karakteri aşıyor, 5'ten fazla ek var ya da bir kimlik dosya kimliği değil.Gövdeyi kısaltın ya da düzeltin.
404Session not foundKimlik yanlış.Kimliği kontrol edin.
409Only sessions started through the API take messages hereKimlik bir web sitesi sohbeti ya da Telegram konuşmasına ait.Bir API oturumu başlatın.
409file_takenBir ek kimliği yok, başka bir mesaja zaten eklenmiş, başka bir oturuma ait, başka bir anahtarla yüklenmiş ya da 24 saatten eski.Aynı anahtarla yeniden yükleyin.
429This assistant is very busy right now. Please try again later.Çalışma alanı günlük yayındaki cevap sınırına ulaştı.Daha sonra tekrar deneyin.
503Could not accept the message right now. Please try again.Mesaj kaydedilmedi.Tekrar deneyin.

Dosya yükleme​

POST /sessions/{id}/files
Content-Type: multipart/form-data

Kullanıcınızdan oturuma bir dosya yükler. Ardından dönen id değerini bir mesajın attachments alanına koyarak dosyayı gönderin. Agent dosyayı mesajla birlikte okur.

Form alanları: file adlı tam olarak bir parça. Başka alan yok.

Kabul edilen dosyalar

TürBiçimler
FotoğraflarJPEG, PNG, WebP, GIF
BelgelerPDF, TXT, Markdown, CSV
  • Dosya başına en fazla 10 MB, mesaj başına 5 dosya ve konuşma başına 30 dosya.
  • Tür, dosyanın adından değil içeriğinden kontrol edilir. SVG ve HTML asla kabul edilmez.
  • Aynı API anahtarıyla yükleyin ve gönderin. Bir anahtarla yüklenen dosya başka bir anahtarla gönderilemez.
  • 24 saat içinde bir mesajla gönderilmeyen dosya silinir.
curl -X POST https://peki.ai/api/sessions/671c9f20a1b2c3d4e5f60718/files \
-H "Authorization: Bearer $PEKI_API_KEY" \
-F "[email protected]"
const form = new FormData();
form.append('file', new Blob([bytes], { type: 'image/jpeg' }), 'hasarli-kutu.jpg');
const file = await (await fetch(`https://peki.ai/api/sessions/${sessionId}/files`, {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.PEKI_API_KEY}` },
body: form,
})).json();

await fetch(`https://peki.ai/api/sessions/${sessionId}/messages`, {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.PEKI_API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ text: 'Kutu hasarlı geldi', attachments: [file.id] }),
});

Yanıt 201:

{ "id": "671ca1c4a1b2c3d4e5f60730", "name": "hasarli-kutu.jpg", "contentType": "image/jpeg", "size": 284113, "kind": "chat" }

Hatalar bir code taşır:

DurumcodeMesaj
400Attach a file in the field "file"
400file_typeThis kind of file is not accepted
413file_sizeThe file is larger than 10 MB
400conversation_fullThis conversation already has 30 files
409Only sessions started through the API take messages here
ipucu

Görselleri yalnızca bazı modeller görebilir. Kullanıcılarınız fotoğraf gönderecekse agent için Görsel okur işaretli bir model seçin. Diğer modellere yalnızca bir fotoğraf gönderildiği bilgisi gider. Bkz. Dosyalar ve ekler.

Oturumu puanlama​

POST /sessions/{id}/feedback

Kullanıcınızın oturum için verdiği beğeni ya da beğenmemeyi kaydeder. Son verilen puan geçerlidir. Analytics'te müşteri memnuniyeti olarak görünür.

AlanTürZorunluKurallar
ratingstringEvetup ya da down. Başka alana izin verilmez.
curl -X POST https://peki.ai/api/sessions/671c9f20a1b2c3d4e5f60718/feedback \
-H "Authorization: Bearer $PEKI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"rating": "up"}'

Yanıt 200, feedback alanı ayarlanmış oturum nesnesiyle. Diğer kanallar için 409 Only sessions started through the API take feedback here.

Oturumu çözüldü olarak kapatma​

POST /sessions/{id}/resolve

Oturumu, Inbox'taki Çözüldü gibi çözüldü olarak işaretler. Kullanıcınız sohbeti kapattığında ya da sorunun çözüldüğünü söylediğinde çağırın. Kullanıcı aynı oturumda yeniden yazarsa oturum yeniden açılır.

Gövde yok.

curl -X POST https://peki.ai/api/sessions/671c9f20a1b2c3d4e5f60718/resolve \
-H "Authorization: Bearer $PEKI_API_KEY"

Yanıt 200, status değeri resolved olan oturum nesnesiyle.

Ekibiniz ve API oturumları​

  • API oturumları Inbox'ta API kanalıyla ve kullanıcınızın adı ya da kimliğiyle görünür.
  • Agent'ınız bir kişiye devrettiğinde ekibinizden biri Devral ile konuşmayı alıp cevap verebilir. Onun cevapları Mesajları listeleme sonucunda role değeri team ve author adıyla görünür. Oturum devralınmışken bunları yoklayın: reply değeri null olur ve yapay zekâ cevabı gelmez.
  • AI'a geri ver sonrasında agent yeniden cevap verir.

Eksiksiz bir örnek​

Uygulamanızın sohbet ekranının çağırdığı küçük bir Node.js sunucu uç noktası:

import express from 'express';

const app = express();
app.use(express.json());
const PEKI = 'https://peki.ai/api';
const AGENT_ID = process.env.PEKI_AGENT_ID;
const headers = { Authorization: `Bearer ${process.env.PEKI_API_KEY}`, 'Content-Type': 'application/json' };

// Kullanıcı yeni bir sohbet açtığında uygulamanız bunu çağırır.
app.post('/chat/sessions', async (req, res) => {
const r = await fetch(`${PEKI}/agents/${AGENT_ID}/sessions`, {
method: 'POST', headers,
body: JSON.stringify({ customer: { id: req.user.id, name: req.user.name } }),
});
res.status(r.status).json(await r.json());
});

// Uygulamanız her mesaj için bunu çağırır ve akışı okur.
app.post('/chat/sessions/:id/messages', async (req, res) => {
const r = await fetch(`${PEKI}/sessions/${req.params.id}/messages`, {
method: 'POST',
headers: { ...headers, Accept: 'text/event-stream' },
body: JSON.stringify({ text: req.body.text }),
});
res.status(r.status).set('content-type', r.headers.get('content-type'));
for await (const chunk of r.body) res.write(chunk);
res.end();
});

app.listen(3000);

İsteği iletmeden önce req.params.id değerinin giriş yapmış kullanıcıya ait olduğunu kontrol edin: API anahtarı çalışma alanınızdaki her oturuma erişebilir.