---
title: "iletiMerkezi Webhooks"
description: "Gerçek zamanlı SMS teslimat raporlarını sunucunuza POST ile alın. Kurulum, payload yapısı, durum değerleri."
slug: /docs/api/webhooks
locale: tr
audience: developer
last_updated: 2026-04-29
auth: api-key-and-hash
related: [send-sms, get-report, authentication, error-codes]
alternates:
  tr: https://www.iletimerkezi.com/docs/api/webhooks
  en: https://www.iletimerkezi.com/en/docs/api/webhooks
  toplusmsapi: https://toplusmsapi.com/sms/rapor/liste/webhook
  a2psmsapi: https://a2psmsapi.com/en/sms/rapor/liste/webhook
---

# iletiMerkezi Webhooks

Webhook, `send-sms` ile gönderdiğiniz mesajların teslimat durumunu sunucunuza gerçek zamanlı olarak iletir. iletiMerkezi panelinden URL tanımlarsınız; her bir mesajın durum güncellemesinde (kabul, teslim, başarısız) belirttiğiniz URL'ye `POST` isteği gelir. `get-report` polling'ine göre daha verimli, daha az gecikmelidir.

## Kurulum

1. `panel.iletimerkezi.com` → **Ayarlar → API → Bildirim Adresi** sekmesine gidin.
2. Webhook URL'sini girin (örn. `https://yourdomain.com/api/iletimerkezi/webhook`) ve **Ekle** ile kaydedin.
3. URL HTTPS olmalı ve dış erişime açık olmalı. iletiMerkezi sunucularından gelen `POST` isteklerini bu URL üzerinden alacaksınız.

> Hesap başına **tek webhook URL** desteklenir. Birden çok hedefe aynı raporu yönlendirmek istiyorsanız webhook handler'ınızdan kendi tarafınızda fan-out yapın.

> Webhook URL'si bir kez tanımlandığında tüm `send-sms` siparişlerinin teslimat raporları otomatik olarak buraya iletilir; ek bir API çağrısı gerekmez.

## İstek

iletiMerkezi her bir mesaj durum güncellemesinde sizin URL'nize aşağıdaki yapıda `POST` atar:

```http
POST https://yourdomain.com/api/iletimerkezi/webhook
Content-Type: application/json
```

```json
{
  "report": {
    "id": 1599558518,
    "packet_id": 104525848,
    "status": "accepted",
    "to": "+905XXXXXXXXX",
    "body": "Mesaj metni"
  }
}
```

### Alanlar

- `report.id` (integer): Sipariş içindeki tek bir mesajın eşsiz ID'si. Bireysel mesajı tanımlar.
- `report.packet_id` (integer): Mesajın ait olduğu siparişin ID'si. `send-sms` yanıtındaki `order.id` ile eşleşir; aynı siparişten gelen tüm webhook olayları aynı `packet_id`'yi taşır.
- `report.status` (string): Mesaj durumu (aşağıdaki tabloya bakın).
- `report.to` (string): Alıcı numara, `+90` prefix'i ile.
- `report.body` (string): Gönderilen mesaj metni.

### Durum değerleri (`report.status`)

| Değer | Anlam |
|---|---|
| `accepted` | Mesaj kabul edildi, gönderim için kuyruğa alındı |
| `delivered` | Mesaj alıcıya başarıyla iletildi |
| `undelivered` | Mesaj iletilemedi (kapalı hat, kara liste, format vb.) |

> `get-report` numerik kodlar (`110`, `111`, `112`) döndürürken webhook string değerler (`accepted`, `delivered`, `undelivered`) gönderir. Tek bir mesajın yaşam döngüsünde tipik olarak önce `accepted`, ardından `delivered` ya da `undelivered` webhook'u gelir.

## Yanıt

Webhook isteğine `2xx` (örneğin `200 OK`) yanıt vermeniz beklenir. `2xx` dışı bir yanıt iletiMerkezi tarafının webhook'u "başarısız" olarak işaretlemesine yol açabilir; idempotent kabul ve hızlı `200` dönmek standart pattern'dir.

```http
HTTP/1.1 200 OK
Content-Type: application/json

{"received": true}
```

## Güvenlik

iletiMerkezi webhook'ları şu an **HMAC imzası veya `X-Signature` benzeri bir header göndermez**; payload doğrudan `report` objesidir. Üretimde alıcı tarafında en az bir doğrulama katmanı uygulamak zorundasınız.

**Önerilen pattern: URL içinde gizli token.** Webhook URL'sini panelde bir `token` query parametresiyle tanımlayın; handler'ınız bu token'ı sabit bir değerle eşleştirip uyuşmayan istekleri `401` ile reddetsin. Bu, iletiMerkezi DLR'lerini tüketen iç servislerimizde de aynı şekilde uygulanan pattern'dir.

```http
POST https://yourdomain.com/api/iletimerkezi/webhook?token=GIZLI_DEGER
```

```js
// Handler örneği (Node/Express)
app.post('/api/iletimerkezi/webhook', (req, res) => {
  if (req.query.token !== process.env.WEBHOOK_TOKEN) {
    return res.status(401).end();
  }
  // ... payload işle
  res.status(200).json({ received: true });
});
```

**Ek savunma:**
- Webhook URL'sini paylaşmayın, repo'ya commit etmeyin (yalnızca env var olarak tutun).
- HTTPS zaten zorunlu — panel HTTP URL'lerini kabul etmez.
- Şüphe varsa istemcide alınan `report.packet_id`'yi kendi DB'nizdeki siparişle eşleştirin; eşleşmeyen DLR'leri sessizce yok sayın (aşağıdaki "Multi-app filtering" pitfall'ına bakın).

> Native HMAC signature desteği yol haritasında bir aday özelliktir; mevcut sistemde yoktur. URL-token convention'ı bugünün gerçek koruma katmanıdır.

## Common Pitfalls

- **Hesabın tüm SMS'leri tek webhook URL'sine düşer (multi-app filtering).** Aynı iletiMerkezi hesabını birden fazla uygulama paylaşıyorsa, uygulamanıza ait olmayan DLR'ler de webhook'unuza gelir. Alıcı tarafta `report.body` içinde uygulamanıza özgü bir marker (örn. kısa link domain'i `iim.to/...`, bir kampanya tag'i veya sipariş ID prefix'i) arayıp uyuşmayanları `200 OK` ile sessizce yok sayın. Yoksa kendi mesajınız sandığınız orphan DLR'leri DB'nize yazarsınız.

  ```js
  // Pratik örnek: kısa link domain'i marker olarak
  if (!report.body.includes('iim.to')) {
    return new Response('OK', { status: 200 });  // bizim değil, sessiz drop
  }
  ```

- **Aynı `report.id` birden çok kez gelebilir; idempotent yazın.** Operatör retry'leri veya iletiMerkezi sunucu retry'i nedeniyle aynı durum güncellemesi tekrarlanabilir. Pratik pattern: ilk callback'te `delivery_received_at` + status yazın, sonraki callback'lerde sadece status'u güncelleyin (timestamp dokunulmaz). İdempotency anahtarı: `report.id + report.status`.
- **`packet_id` ile `send-sms` `order.id` aynıdır.** Webhook'ları siparişle eşleştirmek için bu alanı kullanın; aynı siparişten gelen birden çok mesajın webhook'u aynı `packet_id`'yi taşır.
- **`accepted` "iletildi" demek değildir.** Sadece "kabul edildi, kuyruğa alındı" demek. Gerçek teslim için `delivered` webhook'u beklenir.
- **Webhook URL'iniz hızlı yanıt vermelidir.** Uzun süren işlemleri (DB write, üçüncü parti API çağrısı) arka plan kuyruğuna gönderip webhook handler'da hemen `200` dönün; yoksa iletiMerkezi tarafı timeout görüp retry yapabilir.
- **HTTPS zorunlu.** HTTP URL'ler kabul edilmez veya iletilmez (panele girilemez). Lokal geliştirmede ngrok veya cloudflared tunnel kullanılır.
- **Webhook tanımlanmamışsa polling.** Webhook URL boşsa teslimat durumu sadece `get-report` ile çekilebilir. Üretimde webhook tercih edilir; polling'e fallback ekleyebilirsiniz.

## Related

- [SMS gönderme (send-sms)](./send-sms.md)
- [Sipariş raporu (get-report)](./get-report.md)
- [Kimlik doğrulama (authentication)](./authentication.md)
- [Hata kodları tablosu](./error-codes.md)
