Ana içeriğe geç
Version: Peki

Web sitesi sohbeti API'si

Web sitesi sohbeti API'si, Peki sohbet balonunun sitenizde kullandığı API'dir. Bilerek herkese açıktır: API anahtarı olmadan, ziyaretçilerinizin tarayıcısında çalışır. Hazır widget tasarımınıza uymuyorsa bu uç noktalar üzerine kendi sohbet arayüzünüzü kurabilirsiniz. Çoğu site için kod parçacığını kullanmak daha iyidir; bkz. Web sitesi sohbeti.

Temel adres: https://peki.ai/api/widget/{key} Kimlik doğrulama: yok. Yoldaki widget anahtarı ve bir x-visitor-id başlığı.

warning

Bir web sayfasına asla API anahtarı (psk_…) koymayın. Web sitesi sohbeti API'si anahtar gerektirmez. Sayfanızın bir ziyaretçinin kendi sohbetinden fazlasına ihtiyacı varsa, sunucunuzdan Sessions API'yi çağırın.

Başlamadan önce​

  1. Agent için web sitesi sohbetini açın: Channels → Web sitesi sohbeti bölümünde Sohbeti web sitenizde göster seçeneğini açın.

  2. Kod parçacığından widget anahtarını kopyalayın. Şu parçacıkta

    <script src="https://peki.ai/widget.js" data-key="pw_Xk3n9QeR7tLm2vBc" async></script>

    anahtar pw_Xk3n9QeR7tLm2vBc'dir.

  3. Sitenize izin verin. Sitenizin adresini, ör. https://magaza.example.com, İzin verilen web siteleri altına Site ekle ile ekleyin. Liste boşsa her web sitesi sohbeti kullanabilir.

  4. Agent'ı yayınlayın. O zamana kadar sohbet 409 This assistant is not available yet cevabını verir.

Ziyaretçi kimliği​

Her istek bir x-visitor-id başlığı ister: ziyaretçinin tarayıcısında bir kez oluşturup sakladığınız rastgele bir kimlik, ör. localStorage içinde. Bu, ziyaretçinin tek kimlik bilgisidir: ona sahip olan, o ziyaretçinin konuşmasını okuyabilir, başka hiçbir şeyi değil.

  • 16 ile 64 karakter arası: harfler, rakamlar, - ve _.
  • Rastgele ve tahmin edilemez olsun, ör. tireleri atılmış bir UUID.
  • Her tarayıcı için ayrı tutun. Yeni bir kimlik yeni, boş bir sohbet demektir.
function visitorId() {
let id = localStorage.getItem('peki-visitor');
if (!id) {
id = crypto.randomUUID().replaceAll('-', '');
localStorage.setItem('peki-visitor', id);
}
return id;
}

Kimlik yoksa ya da biçimi bozuksa 400 Missing or invalid visitor id döner.

İzin verilen siteler (CORS)​

Tarayıcı sayfanızın adresini Origin başlığında gönderir. Widget'ta İzin verilen web siteleri tanımlıysa yalnızca bu adresler birebir eşleştiğinde (şema, alan adı ve port, ör. https://magaza.example.com) geçer; diğer her şey şunu alır:

{ "statusCode": 403, "message": "This website may not use this chat" }

Sohbetin çalıştığı her adresi ekleyin; https://www. sürümleri ve test siteleri dahil. En fazla 20.

İzin verilen yöntemler GET, POST ve OPTIONS; izin verilen istek başlıkları content-type ve x-visitor-id'dir.

Uç noktalar​

YöntemYolNe yapar
GET/configSohbetin adı, rengi, karşılama metni ve kullanılabilir olup olmadığı
GET/messagesZiyaretçinin mevcut konuşması
POST/messagesMesaj gönderir
POST/filesDosya yükler
GET/files/{id}Ziyaretçinin kendi konuşmasındaki bir dosyayı indirir
POST/sessionsYeni bir konuşma başlatır
GET/feedbackŞimdi puan istenip istenmeyeceği
POST/feedbackKonuşmayı puanlar

Kapalı bir widget ya da bilinmeyen bir anahtar her uç noktaya 404 This chat is not available ile cevap verir.

Yapılandırmayı alma​

GET /config
curl https://peki.ai/api/widget/pw_Xk3n9QeR7tLm2vBc/config
{
"name": "Gülüş Diş Kliniği",
"color": "#1C1A17",
"welcome": { "en": "Hi! How can we help you today?", "tr": "Merhaba! Size nasıl yardımcı olabiliriz?" },
"available": true,
"layout": "bubble"
}
AlanAçıklama
nameAgent'ın adı.
colorSohbetin rengi, #RRGGBB biçiminde.
welcomeDile göre karşılama metni (en, tr). Ziyaretçinize uyanı gösterin.
availableAgent yayınlanana kadar false.
layoutbubble (köşede bir düğme) ya da inline (sayfa içinde bir sohbet kutusu).

/config ziyaretçi kimliği gerektirmez.

Konuşmayı okuma​

GET /messages
x-visitor-id: {visitorId}

Ziyaretçinin mevcut konuşmasını en eskiden başlayarak döner. Yeni konuşma sonrasında ya da bir konuşma bitecek kadar uzun süre sessiz kaldıktan sonra liste boş başlar.

[
{ "id": "671ca0a1a1b2c3d4e5f60720", "from": "visitor", "text": "Yarın için boş randevunuz var mı?", "at": "2026-10-26T14:05:40.102Z" },
{ "id": "671ca0b3a1b2c3d4e5f60722", "from": "agent", "text": "", "at": "2026-10-26T14:05:40.230Z", "pending": true }
]
AlanAçıklama
idMesaj kimliği.
fromvisitor, agent ya da team (Inbox'ta devralan bir kişi).
textMetin. pending iken boştur.
atYazıldığı an.
pendingAgent hâlâ yazarken true. Bir "yazıyor" göstergesi gösterin.
authorteam mesajlarında ekip üyesinin adı.
attachmentsDosyalar: { fileId, name, contentType, size }.

Cevaplar yoklama (polling) ile gelir. Peki widget'ı bir cevap beklerken 1,2 saniyede bir, diğer zamanlarda 4 saniyede bir kontrol eder; siz de aynısını yapın.

Mesaj gönderme​

POST /messages
x-visitor-id: {visitorId}
Content-Type: application/json
AlanTürZorunluKurallar
textstringİkisinden biriEn fazla 2.000 karakter.
attachmentsstring[]İkisinden biriDosya yükleme ile alınmış en fazla 5 farklı dosya kimliği.
const KEY = 'pw_Xk3n9QeR7tLm2vBc';
const API = `https://peki.ai/api/widget/${KEY}`;

async function send(text) {
const res = await fetch(`${API}/messages`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'x-visitor-id': visitorId() },
body: JSON.stringify({ text }),
});
if (!res.ok) throw new Error((await res.json()).message);
}

Yanıt 202 { "ok": true }. Ardından cevap için GET /messages uç noktasını yoklayın.

İlk mesaj bir konuşma başlatır; sonrakiler, konuşma çözüldü olarak kapatılana ya da agent'ın yeni oturum süresi boyunca sessiz kalana kadar onu sürdürür.

Dosya yükleme​

POST /files
x-visitor-id: {visitorId}
Content-Type: multipart/form-data

file adlı tek bir parça. Fotoğraflar (JPEG, PNG, WebP, GIF) ve belgeler (PDF, TXT, Markdown, CSV), en fazla 10 MB. Tür içerikten kontrol edilir. Ardından dönen id değerini 24 saat içinde bir mesajın attachments alanında gönderin.

const form = new FormData();
form.append('file', input.files[0]);
const res = await fetch(`${API}/files`, { method: 'POST', headers: { 'x-visitor-id': visitorId() }, body: form });
const file = await res.json(); // { id, name, contentType, size, kind: "chat" }

Dosya indirme​

GET /files/{id}
x-visitor-id: {visitorId}

Ziyaretçinin kendi konuşmalarındaki bir dosyayı döner: kendi yüklemeleri ve ekibinizin ona gönderdiği dosyalar. Diğer her şey, var olsun ya da olmasın, 404 File not found (file_missing) döner. Başlık gerektiği için dosyaları düz bir <img src> ile değil, fetch ile yükleyip bir blob'dan gösterin.

Yeni konuşma başlatma​

POST /sessions
x-visitor-id: {visitorId}

Ziyaretçinin sonraki mesajları yeni bir konuşmaya gider. Eskisi Inbox'unuzda kalır. Yanıt { "ok": true }.

Puanlar​

GET /feedback
x-visitor-id: {visitorId}
{ "ask": true, "rating": null }

Beğen ve beğenme düğmelerini göstermek mantıklıysa ask değeri true olur: agent cevap vermiştir ve konuşma çözüldü olarak kapatılmıştır ya da 2 dakikadır sessizdir. rating, varsa daha önce verilmiş puandır.

POST /feedback
x-visitor-id: {visitorId}
Content-Type: application/json
AlanTürZorunluKurallar
ratingstringEvetup ya da down.
commentstringHayırEn fazla 500 karakter.

Başka alana izin verilmez. Yanıt { "ok": true }. Son verilen puan geçerlidir. Son 24 saatte cevaplanmış bir konuşma yoksa 409 Nothing to rate yet.

Sınırlar​

Sohbet kendini aşırı yüke karşı korur. Sınır aşıldığında istek, ziyaretçiye gösterebileceğiniz bir mesajla 429 alır.

NeSınırMesaj
Ziyaretçi başına mesajdakikada 20You are sending messages too fast. Please wait a moment.
Tek bir ağdan tek bir sohbete mesajsaatte 200Too many messages from this network. Please try again later.
Tek bir sohbete toplam mesajdakikada 120This chat is very busy right now. Please try again in a minute.
Tek bir ağdan yeni konuşmasaatte 20Too many new chats from this network. Please try again later.
Ziyaretçi başına dosyasaatte 20file_rate
Tek bir ağdan dosyasohbet başına saatte 60, toplamda saatte 150file_rate
Dosya indirmeziyaretçi başına dakikada 60, ağ başına dakikada 600Too many files opened. Please wait a moment.
Puanlarziyaretçi başına dakikada 10, ağ başına saatte 100, sohbet başına dakikada 120Too many taps. Please wait a moment.

Dosyalar ayrıca mesaj başına 5 ve konuşma başına 30 ile sınırlıdır; çalışma alanının da günlük bir yayındaki cevap sınırı vardır.

Hatalar​

DurumMesaj ya da codeNeden
400Missing or invalid visitor idx-visitor-id yok ya da 16–64 harf, rakam, -, _ değil.
400Write a message or attach a fileBoş mesaj.
400file_count, file_type, conversation_fullÇok fazla dosya, kabul edilmeyen bir tür ya da zaten 30 dosya var.
403This website may not use this chatSiteniz İzin verilen web siteleri arasında değil.
404This chat is not availableBilinmeyen anahtar ya da sohbet kapalı.
409This assistant is not available yetAgent yayınlanmamış.
409file_takenBir dosya zaten eklenmiş ya da bulunamıyor.
413file_sizeDosya 10 MB'tan büyük.
429bkz. SınırlarÇok fazla istek.