Webhook’lar (Tetikleyiciler)
Bir arama tamamlandığında, yeni bir kontak oluştuğunda ya da biri “beni aramayın” dediğinde — Purvisor’ı sürekli sorgulamak yerine, olay olur olmaz Purvisor sizin belirlediğiniz adrese bir HTTP POST gönderir. Buna outbound webhook (giden webhook) denir ve Zapier “Trigger” adımlarının, Make “Watch” modüllerinin altında çalışan mekanizma tam olarak budur. Sonuç: bir Zap’ı açtığınız anda Purvisor arka planda otomatik abone olur, kapattığınız anda aboneliği düşer — tek satır kod yazmadan.
Webhook’lar çıkış yönündedir: Purvisor → sizin sisteminiz. API’ye çağrı yapmak (kontak oluşturma, arama başlatma) için Kontaklar ve Arama Başlatma sayfalarına bakın. Kimlik doğrulama ve pk_live_ API anahtarı için Kimlik Doğrulama’yı okuyun.
REST-hook yaşam döngüsü
Zapier ve Make “REST hook” modelini kullanır: platform, aboneliği sizin adınıza otomatik yönetir. Bir “abonelik” (subscription), tek bir olayı (event) tek bir hedef URL’e (targetUrl) bağlayan kayıttır — Purvisor’ın telefon rehberindeki “şu olay olursa şu numarayı ara” satırı gibi düşünün.
Zap / senaryo AÇILIR
↓
Platform → POST /api/v1/hooks (abone ol; secret'ı saklar)
↓
Olay gerçekleşir (örn. call.completed)
↓
Purvisor → POST targetUrl (imzalı JSON zarfı)
↓
Zap / senaryo KAPANIR
↓
Platform → DELETE /api/v1/hooks/{id} (aboneliği kaldır)Bir olay için birden çok aboneliğiniz olabilir (örneğin aynı call.completed’ı hem Zapier’e hem kendi sunucunuza gönderin). Her abonelik bağımsız çalışır ve kendi imza secret’ına sahiptir.
Abone ol — POST /api/v1/hooks
Bir olayı bir hedef URL’e bağlar. Zapier/Make bunu Zap açıldığında otomatik çağırır; kendi entegrasyonunuzu kuruyorsanız elle çağırırsınız.
İstek gövdesi
| Alan | Zorunlu | Kural |
|---|---|---|
event | Evet | Aşağıdaki 9 olaydan biri olmalı. |
targetUrl | Evet | Geçerli bir URL, https:// ile başlamak zorunda, en fazla 1000 karakter. |
source | Hayır | zapier | make | n8n | custom — varsayılan custom. Sadece köken etiketi; davranışı değiştirmez. |
curl -X POST https://app.purvisor.ai/api/v1/hooks \
-H "X-API-Key: pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"event": "call.completed",
"targetUrl": "https://ornek.com/purvisor/webhook",
"source": "custom"
}'Başarılı yanıt — HTTP 201
{
"id": "42",
"event": "call.completed",
"targetUrl": "https://ornek.com/purvisor/webhook",
"secret": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"
}secret (32 hex karakter) bu aboneliğin HMAC imza anahtarıdır ve yalnızca burada, bir kez gösterilir. GET /api/v1/hooks listesi secret’ı döndürmez. Şimdi saklayın — gelen teslimatların gerçekten Purvisor’dan geldiğini bu secret ile doğrularsınız. Kaybederseniz aboneliği silip yeniden oluşturmanız gerekir. İmza doğrulaması için: İmza Doğrulama.
Geçersiz gövde (örn.
http://URL veya tanınmayan olay) → HTTP 400{"error":"validation_error","details":[...]}.
Abonelikleri listele — GET /api/v1/hooks
Hesabınızın tüm aktif ve pasif aboneliklerini döndürür. Secret asla listede yer almaz.
curl https://app.purvisor.ai/api/v1/hooks \
-H "X-API-Key: pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"{
"data": [
{
"id": "42",
"event": "call.completed",
"targetUrl": "https://ornek.com/purvisor/webhook",
"source": "custom",
"isActive": true,
"failCount": 0,
"lastDeliveryAt": "2026-07-12T09:14:03.000Z",
"createdAt": "2026-07-10T11:02:55.000Z"
}
]
}| Alan | Anlamı |
|---|---|
isActive | Abonelik canlı mı? Üst üste 10 başarısız teslimat sonrası otomatik false olur. |
failCount | Ardışık başarısız teslimat sayacı; başarılı teslimatta 0’a döner. |
lastDeliveryAt | Son başarılı teslimatın ISO zaman damgası (null = henüz teslimat yok). |
Aboneliği kaldır — DELETE /api/v1/hooks/{id}
Zapier/Make bunu Zap kapatıldığında otomatik çağırır.
curl -X DELETE https://app.purvisor.ai/api/v1/hooks/42 \
-H "X-API-Key: pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"Başarılı yanıt → {"success": true}
Silme yalnızca kendi aboneliklerinizi kapsar. Size ait olmayan ya da var olmayan bir id için yanıt her zaman HTTP 404 {"error":"not_found"} olur — böylece başka bir hesabın abonelik varlığı sızdırılmaz. Sayısal olmayan id de 404 döner.
Örnek payload’lar — GET /api/v1/samples
Zapier/Make, Zap kurulumunda alan eşleştirme ekranını çizebilmek için gerçekçi bir örnek payload’a ihtiyaç duyar. Bu uç, istenen olay için statik, sabit bir örnek döndürür — canlı kiracı verisi sızdırmaz.
curl "https://app.purvisor.ai/api/v1/samples?event=call.completed" \
-H "X-API-Key: pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"{
"data": [
{
"callId": "9f3c2a1e-7b4d-4e8a-b2c5-1d6f8a9e0b3c",
"phoneNumber": "+905321234567",
"direction": "outbound",
"durationSeconds": 184,
"outcome": "interested",
"sentiment": "positive",
"summary": "Ahmet Bey ürünle ilgilendi, fiyat bilgisi istedi. Salı günü saat 14:00 için takip araması planlandı.",
"contactId": "1042"
}
]
}
eventparametresi zorunludur ve 9 olaydan biri olmalıdır; aksi halde HTTP 400{"error":"invalid_event","validEvents":[...]}. Her olayın alan seti farklıdır.
Webhook olayları
Abonelik oluştururken event için kullanabileceğiniz 6 ad şunlardır:
| Olay | Ne zaman tetiklenir | Durum |
|---|---|---|
call.completed | Bir arama bitip analiz kaydedildiğinde | ✅ Yayında |
contact.created | Yeni bir kontak oluştuğunda (API, panel veya lead akışı) | ✅ Yayında |
dnc.requested | Biri “aramayın / verimi silin” talep ettiğinde | ✅ Yayında |
lead.hot | Bir lead “sıcak” eşiğine ulaştığında | ✅ Yayında |
appointment.booked | Bir randevu oluşturulduğunda | ✅ Yayında |
campaign.finished | Bir kampanya tamamlandığında | ✅ Yayında |
call.failed | Aramaya ulaşılamadığında (cevapsız, meşgul, reddedildi, terk edildi) | ✅ Yayında |
appointment.cancelled | Bir randevu iptal edildiğinde | ✅ Yayında |
appointment.rescheduled | Bir randevu ertelendiğinde | ✅ Yayında |
Dokuz olayın tamamı canlı yayınlanmaktadır. lead.hot yalnızca kişi o aramada “sıcak” eşiğine geçtiğinde tetiklenir (her sıcak aramada tekrar tetiklenmez); campaign.finished kampanya birden çok yoldan bitebildiği için atomik bir geçiş kontrolüyle tam bir kez yayınlanır.
Teslimat zarfı
Purvisor sizin targetUrl’inize her zaman şu şekilde bir gövde POST eder:
{
"id": "call.completed:9f3c2a1e-7b4d-4e8a-b2c5-1d6f8a9e0b3c",
"event": "call.completed",
"timestamp": "2026-07-12T09:14:03.128Z",
"data": { }
}id, olayın deterministik kimliğidir: <olay adı>:<varlığın doğal anahtarı> biçimindedir ve aynı varlık için olay tekrar yayınlanırsa aynı değeri alır. Tüketici tarafında mükerrer işlemi elemek için bu alanı kullanın.
GET /samples ucu, örnek kaydı bu zarfın aynısıyla döndürür — Zap kurulumunda gördüğünüz alan yapısı canlıda geleceklerle birebir aynıdır.
data içeriği olaya göre değişir (yukarıdaki örnek payload’lar gerçek data bloğudur). Teslimat ayrıca şu başlıkları taşır:
| Başlık | Değer |
|---|---|
Content-Type | application/json |
X-Purvisor-Event | Olay adı (örn. call.completed) |
X-Purvisor-Signature | Ham gövdenin abonelik secret’ı ile HMAC-SHA256’sı (hex) — bkz. İmza Doğrulama |
Purvisor bir teslimatı 5 kez dener (üstel geri çekilme, 15 sn taban, istek başına 10 sn zaman aşımı). 2xx dışı her yanıt yeniden denenir; 10 ardışık başarısızlık sonrası abonelik otomatik isActive=false yapılır. Başarılı teslimat failCount’u sıfırlar.
KVKK notu: Webhook payload’ları telefon numarası, ad-soyad ve görüşme özeti gibi kişisel veri taşır.
targetUrlher zamanhttps://olmak zorundadır (Purvisorhttp://kabul etmez), ancak alıcı uçta da bu veriyi güvenli saklamak, erişimi sınırlamak ve saklama sürelerini KVKK’ya uygun yönetmek sizin sorumluluğunuzdadır.
Sorun giderme
| Belirti | Olası neden / çözüm |
|---|---|
POST /hooks → 400 validation_error | targetUrl https:// ile başlamıyor, 1000 karakteri aşıyor veya event 6 addan biri değil. |
| Abone oldum ama hiç veri gelmiyor | Dokuz olay da canlıdır; olay henüz gerçekleşmemiş olabilir. lead.hot yalnızca kişi sıcak eşiğine geçtiğinde, appointment.booked randevu kurulduğunda, campaign.finished kampanya bittiğinde tetiklenir. |
403 premium_required alıyorum | Public API Pro ve üzeri planlarda kullanılabilir; kontrol her istekte yapılır. Bkz. Limitler ve Hatalar. |
Teslimatlar duruyor, isActive:false görünüyor | 10 ardışık başarısız teslimat → otomatik devre dışı. Alıcı ucun 2xx döndürdüğünü doğrulayıp aboneliği yeniden oluşturun. |
| İmza doğrulaması tutmuyor | Ham (parse edilmemiş) gövdeyi ve doğru aboneliğin secret’ını kullandığınızdan emin olun. Detay: İmza Doğrulama. |
| Secret’ı kaybettim | Secret yeniden gösterilemez; DELETE edip yeni bir abonelik oluşturun. |
DELETE → 404 not_found | id size ait değil, mevcut değil veya sayısal değil. |
401 invalid_api_key | API anahtarı eksik/geçersiz. Bkz. Kimlik Doğrulama. |