> For the complete documentation index, see [llms.txt](https://developer.konukcrm.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.konukcrm.com/rehberler/webhooklar.md).

# Webhook'lar

Yoklama (polling) yerine KonukCRM olayları HTTPS uç noktanıza gönderir: çağrı tamamlandı, rezervasyon oluşturuldu, mesaj geldi.

## Kayıt

{{Ayarlar → Entegrasyonlar → Webhook'lar}} ekranından veya API üzerinden:

```bash
curl -X POST https://{{api.konukcrm.com}}/api/v1/{{webhooks}} \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://sizin-sisteminiz.com/hooks/konukcrm",
    "events": ["call.completed", "reservation.created"],
    "secret": "{{whsec_...}}"
  }'
```

Gereksinimler: **HTTPS**, geçerli sertifika, {{5}} saniye içinde `2xx` yanıt.

## Olay kataloğu

| Olay                    | Ne zaman tetiklenir                                   |
| ----------------------- | ----------------------------------------------------- |
| `call.started`          | Çağrı ajana bağlandı                                  |
| `call.completed`        | Çağrı kapandı ve kapanış kategorisi (wrap-up) girildi |
| `call.missed`           | Çağrı yanıtlanmadı                                    |
| `reservation.created`   | Rezervasyon oluşturuldu                               |
| `reservation.updated`   | Tarih, oda veya fiyat değişti                         |
| `reservation.cancelled` | Rezervasyon iptal edildi                              |
| `guest.created`         | Yeni misafir kaydı                                    |
| `message.received`      | WhatsApp / Instagram / web chat mesajı geldi          |
| `recording.available`   | Çağrı ses kaydı depolamaya yazıldı                    |

## Yük (payload) formatı

```json
{
  "id": "evt_{{01J9...}}",
  "type": "reservation.created",
  "createdAt": "2026-09-04T09:12:33Z",
  "tenantId": "{{tenant-uuid}}",
  "data": {
    "reservationId": "{{uuid}}",
    "hotelId": "{{uuid}}",
    "checkIn": "2026-10-01",
    "checkOut": "2026-10-04",
    "totalAmount": 12400.00,
    "currencyCode": "TRY"
  }
}
```

Yükler **büyüyebilir**: yeni alan eklenmesi kırıcı değişiklik sayılmaz.

## İmza doğrulama

Her istek imzalanır:

```http
X-KonukCRM-Signature: t=1757062353,v1=5257a869e7ec...
```

İmza tabanı `"{timestamp}.{ham gövde}"`, algoritma HMAC-SHA256, anahtar kayıt sırasında verdiğiniz `secret`.

```typescript
import { createHmac, timingSafeEqual } from "node:crypto";

export function verify(rawBody: string, header: string, secret: string) {
  const parts = Object.fromEntries(header.split(",").map(p => p.split("=")));
  const age = Math.abs(Date.now() / 1000 - Number(parts.t));
  if (age > 300) return false;                        // tekrar saldırısı (replay) koruması

  const expected = createHmac("sha256", secret)
    .update(`${parts.t}.${rawBody}`)
    .digest("hex");

  return timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}
```

> Gövdeyi **ham haliyle** doğrulayın. JSON parse edip yeniden serileştirmek imzayı bozar.

## Tekrar deneme

`2xx` dışında her yanıt veya zaman aşımı tekrar denenir: {{1dk, 5dk, 30dk, 2sa, 6sa}} — toplam {{5}} deneme. Tüm denemeler başarısız olursa uç nokta askıya alınır ve tenant yöneticisine bildirim gider.

## Idempotency

Aynı `id` ile aynı olayı **birden fazla kez alabilirsiniz** (en az bir kez teslim garantisi). İşlenmiş olay kimliklerini saklayın:

```sql
INSERT INTO processed_events (event_id) VALUES ($1)
ON CONFLICT (event_id) DO NOTHING;
```

Etkilenen satır 0 ise olay zaten işlenmiştir; sessizce `200` dönün.

## İşleyici deseni

1. İmzayı doğrula → geçersizse `401`
2. Yükü kuyruğa yaz → hemen `200` dön
3. İşi asenkron işle → yavaş iş asla istek içinde yapılmaz

{{5}} saniyeyi aşan işleyiciler zaman aşımına uğrar ve gereksiz tekrarlara yol açar.

## Yerelde test

```bash
{{ngrok http 3000}}
# Oluşan HTTPS URL'ini webhook kaydında kullanın
```

Yönetim panelindeki **Test olayı gönder** düğmesi örnek yük üretir.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developer.konukcrm.com/rehberler/webhooklar.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
