> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flextell.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# WhatsApp

> WhatsApp kanalını API ile oluşturmayı, QR ile eşleştirmeyi, bağlantı durumunu sorgulamayı ve geçmiş mesajları eşitlemeyi anlatır.

Klinik numarası, WhatsApp'a **bağlı cihaz** olarak eşleştirilir. Eşleşen kanalın mesajları Flextell'e düşer, AI asistan yanıt verebilir ve personel mesaj gönderebilir. Bu sayfa, kanalı panele girmeden API ile kurmak isteyen entegratörler içindir. Panel karşılığı için [WhatsApp bağlantısı](/panel/baglantilar/whatsapp) sayfasına bakın.

Kanal kaynağının genel alanları ve diğer kanal türleri [Kanallar](/api/kaynaklar/kanallar) sayfasındadır. Tüm istekler `Authorization: Bearer <access_token>` ve `X-Tenant: <tenant_id>` başlıklarıyla yapılır; ayrıntı için [Klinikler ve X-Tenant](/api/klinikler-ve-x-tenant) sayfasına bakın.

## Uç noktalar

| Metot | Endpoint | Açıklama | Scope | İzin |
| - | - | - | - | - |
| `POST` | `/v1/channels` | Kanal oluşturur. | `channels:write` | `Create:Channel` |
| `POST` | `/v1/channels/{id}/whatsapp/connect` | Bağlantıyı başlatır, QR kodu döndürür. | `channels:write` | `Update:Channel` |
| `GET` | `/v1/channels/{id}/whatsapp/connection-state` | Bağlantı durumunu sorgular. | `channels:read` | `QueryStatus:Channel` veya `Update:Channel` |
| `GET` | `/v1/channels/{id}/whatsapp/webhook` | Webhook ayarlarını okur. | `channels:read` | `View:Channel` |
| `PUT` | `/v1/channels/{id}/whatsapp/webhook` | Webhook ayarlarını günceller. | `channels:write` | `Update:Channel` |
| `GET` | `/v1/channels/whatsapp/history-syncs` | Eşitleme çalıştırmalarını listeler. | `conversations:read` veya `channels:read` | `View:Conversation` veya `View:Channel` |
| `GET` | `/v1/channels/{id}/whatsapp/history-sync` | Hattın eşitleme ayarlarını ve son çalıştırmayı verir. | `channels:read` | `View:Channel` |
| `PUT` | `/v1/channels/{id}/whatsapp/history-sync` | Eşitleme ayarlarını kaydeder. | `channels:write` | `Update:Channel` |
| `POST` | `/v1/channels/{id}/whatsapp/history-sync/start` | Eşitlemeyi hemen başlatır. | `channels:write` | `Update:Channel` |

`/whatsapp/*` uç noktaları yalnızca `type` değeri `whatsapp` ve `provider` değeri `evolution_api` olan kanallarda çalışır. Başka bir klinikteki kanal kimliği `404` döner.

## Kanal oluşturma

`POST /v1/channels` ile `type: "whatsapp"` kanalı açın.

| Alan | Zorunlu | Açıklama |
| - | - | - |
| `name` | Evet | En çok 255 karakter. Klinik içinde benzersizdir. Büyük harfe çevrilerek saklanır (`klinik sitesi` → `KLINIK SITESI`). |
| `type` | Evet | `whatsapp`. Oluşturulduktan sonra değişmez; güncellemede gönderilse bile yok sayılır. |
| `address` | Evet | Kanalın telefon numarası. Flextell numarayı yalnızca rakamlara çevirir (`+` ve boşluklar atılır): `+90 (543) 736 44 00` değeri `905437364400` olur. Numarayı her zaman ülke koduyla gönderin. |
| | | |
| `is_active` | Hayır | Varsayılan `true`. Pasif kanal canlı mesaj almaz. |
| `ai_reply_mode` | Hayır | `auto`, `semi_auto`, `closed` veya `null`. `null`, kliniğin AI yanıt programını izler. |

<Warning>
  `address`, QR kodu okutacak telefonun numarasıyla birebir aynı olmalıdır. Aksi hâlde bağlantı kapatılır (bkz. [Bağlantı durumu](#bağlantı-durumu)).
</Warning>

Yanıt `201` ve kanal nesnesidir. Kanal `closed` durumda başlar.
&#x20;Yanıtta QR kodu **yoktur**; QR için sonraki bölümdeki `connect` çağrısını yapın.

<ResponseField name="data" type="object">
  <Expandable title="kanal nesnesi" defaultOpen>
    <ResponseField name="id" type="integer">Kanal kimliği.</ResponseField>
    <ResponseField name="name" type="string">Büyük harfli kanal adı.</ResponseField>
    <ResponseField name="type" type="string">`whatsapp`</ResponseField>
    <ResponseField name="provider" type="string">`evolution_api`</ResponseField>
    <ResponseField name="address" type="string">Rakamlardan oluşan telefon numarası.</ResponseField>
    <ResponseField name="status" type="string">`closed`, `waiting` veya `open`. Yalnızca `open` kanal mesaj iletebilir.</ResponseField>
    <ResponseField name="is_active" type="boolean">Kanalın etkin olup olmadığı.</ResponseField>
    <ResponseField name="ai_reply_mode" type="string | null">AI yanıt modu.</ResponseField>
    <ResponseField name="connection_error" type="object | null">Bağlantı reddedildiyse `code`, `expected_address`, `connected_address`, `message`, `detected_at`.</ResponseField>
  </Expandable>
</ResponseField>

## QR ile eşleştirme

<Steps>
  <Step title="Bağlantıyı başlatın">
    `POST /v1/channels/{id}/whatsapp/connect` çağrısı kanalı `waiting` durumuna alır ve önceki `connection_error` değerini temizler. Gövde göndermeniz gerekmez.
  </Step>

  <Step title="QR kodunu gösterin">
    Yanıttaki `qr_code` değerini `<img src="…">` içinde olduğu gibi kullanın; değer `data:image/png;base64,…` biçimindedir. QR gelmezse `null` olabilir.
  </Step>

  <Step title="Alternatifi sunun">
    QR okutulamıyorsa `pairing_code` değerini gösterin. Kullanıcı WhatsApp'ta **Bunun yerine telefon numarasıyla bağla**'ya dokunup bu kodu girer.
  </Step>

  <Step title="Durumu izleyin">
    `connection-state` uç noktasını yaklaşık 3 saniyede bir sorgulayın; `state` değeri `open` olunca eşleşme tamamdır.
  </Step>
</Steps>

Kullanıcının telefonda izleyeceği yol: **WhatsApp → Bağlı Cihazlar → Cihaz Bağla**, ardından kamerayı QR koduna doğrultmak.

<CodeGroup>
  ```bash Kanal oluştur theme={null}
  curl -X POST https://app.flextell.ai/api/v1/channels \
    -H "Authorization: Bearer <access_token>" \
    -H "X-Tenant: <tenant_id>" \
    -H "Content-Type: application/json" \
    -d '{"type": "whatsapp", "name": "Satış", "address": "+90 5xx xxx xx xx"}'
  ```

  ```bash QR al theme={null}
  curl -X POST https://app.flextell.ai/api/v1/channels/123/whatsapp/connect \
    -H "Authorization: Bearer <access_token>" \
    -H "X-Tenant: <tenant_id>"
  ```
</CodeGroup>

```json Yanıt (kısaltılmış) theme={null}
{
  "success": true,
  "data": {
    "channel": { "id": 123, "status": "waiting", "connection_error": null },
    "qr_code": "data:image/png;base64,iVBORw0KGgo...",
    "pairing_code": null
  }
}
```

## Bağlantı durumu

`GET /v1/channels/{id}/whatsapp/connection-state` yanıtı `{channel, state, qr_code, pairing_code}` biçimindedir. Çağrı, WhatsApp tarafındaki gerçek durumla Flextell'deki kanal durumunu eşitler.

| `state` | Kanal `status` | Anlamı |
| - | - | - |
| `open` | `open` | Bağlı. |
| `connecting` | `waiting` | Eşleşme bekleniyor. |
| `close` | `closed` | Bağlı değil. |
| `refused` | `closed` | Bağlantı reddedildi. |

* `state` değeri `connecting` iken yanıt, o an geçerli `qr_code` ve `pairing_code` değerlerini de taşır. QR yaklaşık 45 saniyede bir yenilenir; her sorguda gelen yeni kodu gösterin.
* `open` ve `close` durumlarında QR istenmez.
* Bağlantı `open` göründüğünde Flextell eşleşen numarayı doğrular. Numara henüz doğrulanmadıysa kanal kısa süre `waiting` kalır.
* Panel, üst üste 3 sorguda `close` veya `refused` gelirse QR'ı süresi dolmuş sayar. Siz de bu durumda yeniden `connect` çağırıp yeni QR alın.

### Numara uyuşmazlığı

QR, `address` alanındaki numaradan farklı bir telefonla okutulursa Flextell eşleşmeyi sonlandırır. Kanal `closed` olur, `state` değeri `close` döner ve `connection_error.message` nedeni açıklar. Örnek mesaj: `Bu kanal +90 555 111 22 33 numarası için tanımlı, ancak QR kodu +90 555 999 88 77 numarasıyla okutulduğu için bağlantı kapatıldı. …`

İki çözüm vardır: QR'ı doğru numaralı telefonla yeniden okutun ya da numara gerçekten değiştiyse önce `PUT /v1/channels/{id}` ile `address` değerini güncelleyip sonra `connect` çağırın.

<Note>
  Telefon cihaz bağlantısını kaldırırsa veya oturum düşerse kanal `closed` olur. Yeniden `connect` çağırarak yeni QR alabilirsiniz.
</Note>

## Geçmiş eşitleme

Geçmiş eşitleme, telefondaki eski WhatsApp mesajlarını Flextell'e aktarır. Her hattın ayarı ve çalıştırmaları ayrıdır. Bir kişi iki hatla yazışmışsa tek hasta kaydı ve her hat için ayrı sohbet oluşur.

### Ayarlar

`PUT /v1/channels/{id}/whatsapp/history-sync` gövdesinde beş alanın tamamı zorunludur.

| Alan | Değerler | Varsayılan | Açıklama |
| - | - | - | - |
| `enabled` | `true`, `false` | `false` | Eşitlemeyi açar. |
| `period_days` | `30`, `90`, `365` | `90` | Kaç günlük mesaj aktarılacağı. |
| `contact_scope` | `known`, `all` | `known` | `known`: yalnızca sistemde kayıtlı kişiler. `all`: tüm sohbetler. |
| `new_contact_type` | `patient`, `lead` | `patient` | Sistemde olmayan numaranın kayıt türü. Yalnızca `contact_scope` değeri `all` iken geçerlidir. |
| `name_strategy` | `fill_blank`, `keep` | `fill_blank` | `fill_blank`: kayıtlı kişilerin boş adlarını WhatsApp adıyla doldurur. `keep`: kayıtlara dokunmaz. |
| `start_now` | `true`, `false` | — | İsteğe bağlı. `enabled` ve `start_now` doğruysa ve hat bağlıysa eşitleme hemen başlar. |

Yanıt `{configured, settings, latest}` biçimindedir. Ayar hiç kaydedilmediyse `configured` değeri `false` olur. Hat bağlı değilken `start_now` gönderirseniz eşitleme, hat bir sonraki bağlanışında kendiliğinden başlar.

Eşitleme şu zamanlarda çalışır:

* Hat ilk eşleştiğinde, ayar açıksa (`trigger: initial`).
* Bağlantı kopup geri geldiğinde; arada kaçan mesajlar aktarılır (`trigger: reconnect`).
* `start_now` veya `/start` çağrısıyla (`trigger: manual`).

Dönem, ilk ve elle çalıştırmalarda `period_days` kadar geriye gider. Yeniden bağlanmada kopma anından 15 dakika öncesine gider.

### Hemen başlatma

`POST /v1/channels/{id}/whatsapp/history-sync/start` bir çalıştırma başlatır. Zaten bekleyen veya süren bir çalıştırma varsa yenisini açmaz, onu döndürür.

### Çalıştırma nesnesi

`GET /v1/channels/whatsapp/history-syncs` en yeni 50 çalıştırmayı verir (sayfalama yok). `active=1` yalnızca `pending` ve `running` olanları getirir.

| Alan | Tür | Açıklama |
| - | - | - |
| `id`, `channel_id` | integer | Çalıştırma ve kanal kimliği. |
| `trigger` | string | `initial`, `reconnect` veya `manual`. |
| `status` | string | `pending`, `running`, `completed`, `failed` veya `cancelled`. |
| `since` | string | Aktarımın başladığı tarih. |
| `progress_percent` | integer \| null | Tamamlanınca 100. WhatsApp toplamı bildirene kadar `null`. |
| `provider_total` | integer | WhatsApp'ın bildirdiği toplam. |
| `processed`, `imported` | integer | İşlenen ve aktarılan mesaj sayısı. |
| `skipped` | object | Atlananlar: `unknown_contact`, `deleted_contact`, `lid_unresolved`, `group`, `failed`. |
| `settings` | object | Çalıştırma anındaki ayarlar. |
| `started_at`, `finished_at`, `created_at` | string | ISO 8601 zaman damgaları. |

### Aktarım kuralları

* Aktarım sessizdir: AI yanıt vermez, bildirim gitmez, sohbetler arşivden çıkmaz. Mesajlar özgün zamanıyla kaydedilir ve müşteri mesajları okundu sayılır.
* Lead yalnızca `new_contact_type` değeri `lead` iken oluşur.
* Medya yalnızca 30 günden yeni ve WhatsApp'ta hâlâ erişilebilir mesajlar için indirilir.
* Gruplar, yayın listeleri ve bültenler atlanır.
* Silinmiş bir hasta eski mesajlarla geri gelmez; bu mesajlar `deleted_contact` altında sayılır.
* Aynı WhatsApp mesajı, hat ve yön bazında bir kez saklanır; tekrar çalıştırmak kopya üretmez.
* Çalıştırma sırasında hat koparsa çalıştırma `pending` olur ve hat yeniden bağlanınca devam eder.

<Info>
  İlerlemeyi gerçek zamanlı izlemek için `WhatsappHistorySyncProgressed` olayını `private-chat-log.{tenantId}` kanalında dinleyebilirsiniz. Bu kanala yalnızca tüm sohbetleri görebilen kullanıcılar abone olabilir; diğerleri için `history-syncs?active=1` uç noktasını sorgulayın. Ayrıntı: [Kanallar ve olaylar](/api/gercek-zamanli/kanallar-ve-olaylar).
</Info>

## Webhook ayarları

Bu ayar, WhatsApp'tan gelen olayların Flextell'e hangi adresten ve hangi olay türleriyle ulaşacağını belirler. Çoğu entegrasyonda değiştirmeniz gerekmez.

| Alan | Zorunlu | Açıklama |
| - | - | - |
| `url` | Evet | `http` veya `https` adres, en çok 2048 karakter. Flextell adresin sonuna `/webhook/whatsapp` ekler. |
| `enabled` | Evet | `true` veya `false`. |
| `events` | Evet | Olay adları dizisi; her ad benzersiz ve en çok 64 karakter. Alan istekte bulunmalıdır. |

`GET` yanıtı `{url, enabled, events}` biçimindedir. Ayar hiç yapılmamışsa `enabled: true` ve varsayılan olaylar döner: `CONNECTION_UPDATE`, `MESSAGES_UPSERT`, `MESSAGES_EDITED`, `MESSAGES_UPDATE`, `MESSAGES_DELETE`, `PRESENCE_UPDATE`.

<Warning>
  Adresi Flextell dışına yönlendirirseniz kanalın gelen mesajları Flextell'e ulaşmaz. Flextell yalnızca bağlantı güncellemelerini, yeni, düzenlenen, güncellenen ve silinen mesajları, durum güncellemelerini ve yazıyor göstergesini işler. Bu olayları `events` listesinden çıkarmayın.
</Warning>

<Accordion title="Seçilebilir olay adları">
  `APPLICATION_STARTUP`, `QRCODE_UPDATED`, `CONNECTION_UPDATE`, `MESSAGES_SET`, `MESSAGES_UPSERT`, `MESSAGES_EDITED`, `MESSAGES_UPDATE`, `MESSAGES_DELETE`, `SEND_MESSAGE`, `CONTACTS_SET`, `CONTACTS_UPSERT`, `CONTACTS_UPDATE`, `PRESENCE_UPDATE`, `CHATS_SET`, `CHATS_UPDATE`, `CHATS_UPSERT`, `CHATS_DELETE`, `GROUPS_UPSERT`, `GROUPS_UPDATE`, `GROUP_PARTICIPANTS_UPDATE`, `NEW_TOKEN`, `TYPEBOT_START`, `TYPEBOT_CHANGE_STATUS`
</Accordion>

## Hatalar

Hata gövdesi `{"success": false, "error_code", "message", "errors"?}` biçimindedir. Genel kurallar için [Hata kodları](/api/istekler/hata-kodlari) sayfasına bakın.

| Kod | HTTP | Ne zaman |
| - | - | - |
| `CHANNEL_NOT_WHATSAPP` | 422 | `/whatsapp/*` uç noktası WhatsApp olmayan kanalda çağrıldı. |
| `CHANNEL_PROVIDER_UNSUPPORTED` | 422 | Kanalın sağlayıcısı `evolution_api` değil. |
| `CHANNEL_PROVIDER_UNAVAILABLE` | 502 | WhatsApp sağlayıcısına ulaşılamadı. `connect`, `connection-state` ve webhook çağrılarında görülebilir; bir süre sonra yeniden deneyin. |
| `CHANNEL_NOT_CONNECTED` | 422 | Hat `open` değilken `history-sync/start` çağrıldı. |
| `CHANNEL_INACTIVE` | 422 | Sohbetin kanalı pasif (`is_active` değeri `false`) iken mesaj gönderildi. Mesaj: `Bu sohbetin kanalı pasif. Mesaj göndermek için kanalı yeniden etkinleştirin.` |
| `CHANNEL_HISTORY_SYNC_DISABLED` | 422 | `enabled` değeri `false` iken `history-sync/start` çağrıldı. Önce ayarı açın. |
| `RESOURCE_NOT_FOUND` | 404 | Kanal bu klinikte yok (`Kanal bulunamadı`). |
| `VALIDATION_FAILED` | 422 | Alan doğrulaması başarısız; `errors` hangi alanın hatalı olduğunu söyler. |

`CHANNEL_NOT_CONNECTED` ile `CHANNEL_INACTIVE` farklı durumlardır: `CHANNEL_NOT_CONNECTED` hattın WhatsApp bağlantısı kopukken, `CHANNEL_INACTIVE` kanalın `is_active` anahtarı kapalıyken döner. Sohbette metin, medya, sesli mesaj, hızlı yanıt, tepki veya AI önerisi göndermeyi kanalı pasif bir sohbette denerseniz istek kuyruğa alınmadan `422 CHANNEL_INACTIVE` ile reddedilir; mesaj saklanmaz. Ayrıntı: [Mesaj gönderme](/api/rehberler/mesaj-gonderme).

Gönderim kabul edildikten sonra hat kapatılırsa mesaj saklanır ve `metadata.delivery_status` değeri `failed` olur; aynı anda `ChatLogUpdated` olayı yayınlanır ([Kanallar ve olaylar](/api/gercek-zamanli/kanallar-ve-olaylar)).

Gerekli izin yoksa istek `403` ile reddedilir. WhatsApp tarafındaki hazırlık kanal kaydedildikten sonra yapılır; hazırlık başarısız olsa bile `POST /v1/channels` `201` döner. Bu durumda `connect` çağrısını yeniden deneyin.

## İlgili sayfalar

<CardGroup cols={2}>
  <Card title="Kanallar" icon="plug" href="/api/kaynaklar/kanallar">
    Kanal kaynağının tüm alanları ve diğer kanal türleri.
  </Card>

  <Card title="Telegram" icon="send" href="/api/entegrasyonlar/telegram">
    Bot token ile Telegram kanalı kurma.
  </Card>

  <Card title="WhatsApp sorun giderme" icon="wrench" href="/panel/sorun-giderme/whatsapp">
    Bağlantı kopması ve numara uyuşmazlığı çözümleri.
  </Card>

  <Card title="İzinler ve görünürlük" icon="shield" href="/api/izinler-ve-gorunurluk">
    Kanal izinleri ve scope eşleşmeleri.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.