> ## 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.

# Mesajlar

> Sohbette mesaj göndermeyi, medya eklemeyi ve mesaj düzenleme, silme ve tepki vermeyi anlatır.

Mesajlar, bir [sohbetin](/api/kaynaklar/sohbetler) içindeki yazışmanın satırlarıdır. Bu sayfa, entegrasyonunuzun bir sohbete metin, medya ve sesli not göndermesini, gönderilmiş mesajı düzenleyip silmesini ve mesaja tepki vermesini anlatır. Tüm endpoint'ler `/api/v1/conversations/{id}` altındadır. Gönderim kanalları için [Kanallar](/api/kaynaklar/kanallar) sayfasına bakın.

## Endpoint özeti

Tüm istekler `Authorization: Bearer <access_token>` ve `X-Tenant: <tenant_id>` başlıklarını gerektirir. Ortak başlıklar için [İstek başlıkları](/api/istekler/basliklar) sayfasına bakın.

| Metot | Endpoint | Açıklama | Scope | İzin |
| - | - | - | - | - |
| GET | `/conversations/{id}/messages` | Mesajları listeler (en yeni önce). | `conversations:read` | `View:Conversation` |
| POST | `/conversations/{id}/messages` | Metin mesajı gönderir. | `conversations:write` | `Send:Message` |
| POST | `/conversations/{id}/messages/media` | Görsel, video, ses veya belge gönderir. | `conversations:write` | `Send:Message` |
| POST | `/conversations/{id}/messages/voice` | Sesli not gönderir. | `conversations:write` | `Send:Message` |
| POST | `/conversations/{id}/messages/quick-reply` | Kayıtlı bir Hızlı Yanıt gönderir. | `conversations:write` | `Send:Message` |
| PUT | `/conversations/{id}/messages/{messageId}` | Gönderilmiş metni düzenler. | `conversations:write` | `Update:Message` |
| DELETE | `/conversations/{id}/messages/{messageId}` | Mesajı herkesten siler. | `conversations:write` | `Delete:Message` |
| POST | `/conversations/{id}/messages/{messageId}/reactions` | Tepki ekler, değiştirir veya kaldırır. | `conversations:write` | `Send:Message` |

İzinlerin rol editöründeki karşılıkları **Mesajlar → Gönder**, **Mesajlar → Güncelle** ve **Mesajlar → Sil** etiketleridir. Hızlı Yanıt gönderimi için bkz. [Hızlı Yanıtlar](/api/kaynaklar/hizli-yanitlar).

<Info>
  Görünmeyen veya başka kliniğe ait bir sohbet `404 RESOURCE_NOT_FOUND` döner. Satış temsilcisi rolünde `ViewAllConversations` izni olmayan bir kullanıcı yalnızca kendisine atanmış lead'lerin sohbetlerini görür. Ayrıntı için [İzinler ve görünürlük](/api/izinler-ve-gorunurluk) sayfasına bakın.
</Info>

## Mesaj nesnesi

Liste ve düzenleme/tepki yanıtları aynı nesneyi döner.

| Alan | Tür | Açıklama |
| - | - | - |
| `id` | integer | Mesaj kimliği. Yol parametresindeki `{messageId}` budur. |
| `conversation_id` | integer | Mesajın sohbeti. |
| `channel_id` | integer | Mesajın geçtiği hat. `all_lines` ile birden çok hat birleştiğinde hangi hattan geldiğini gösterir. |
| `channel_message_id` | string | Kanal sağlayıcısının mesaj kimliği. Gönderim yanıtındaki geçici `message_id` ile aynı değildir. |
| `user_id`, `user_name` | integer, string | Gönderen personel. Hasta, AI ve sistem mesajlarında boştur. |
| `is_customer` | boolean | `true` ise mesaj hastadan gelmiştir. |
| `message_type` | string | `text`, `audio`, `video`, `document`, `image`, `sticker`, `location`, `contact`, `system`. Bilinmeyen bir değeri genel mesaj olarak gösterin. |
| `media_type` | string | `audio`, `video`, `gif`, `document`, `image`, `sticker` veya `null`. |
| `message`, `message_format` | string | Metin veya medya açıklaması; `plain` ya da `markdown`. Silinmiş mesajda `message` `null` döner. |
| `quoted_text` | string | Alıntılanan mesajın metni. |
| `transcript`, `transcript_status` | string | Sesli mesajın yazıya çevirisi ve durumu: `pending`, `completed`, `failed`. |
| `is_deleted`, `is_edited` | boolean | Silinme ve düzenlenme durumu. |
| `edited_by_user_name`, `deleted_by_user_name` | string | İşlemi yapan personel. |
| `read_at` | string | Hasta mesajında personelin okuduğu zaman. WhatsApp'a giden mesajda hastanın okuduğu zaman. |
| `delivery_status` | string | WhatsApp için `sent`, `delivered`, `read`; mesaj kanala hiç iletilemediyse `failed`; aksi hâlde `null`. |
| `metadata` | object | Konum için `latitude`, `longitude`, `location_name`, `location_address`; kişi için `contacts`; GIF için `is_gif`. Diğerlerinde `null`. |
| `file`, `file_temporary_url` | object, string | Medya dosyası ve geçici indirme adresi. |
| `media_group_id`, `media_group_index` | string, integer | Albüm bilgisi. |
| `reactions[]` | array | `id`, `emoji`, `is_customer`, `user_id`, `user_name`, `reacted_at`. |
| `created_at` | string | Gönderim zamanı, klinik saat diliminde (`2026-10-12T14:30:00+03:00`). |

`GET /messages` için `per_page` (1–100, varsayılan 50), `page`, `search` (en çok 255 karakter; mesaj metninde ve sesli not yazıya çevirisinde arar), `message_type[]` ve `all_lines` parametreleri vardır. Sonuçlar `created_at` azalan sırayla gelir.

## Metin mesajı gönderme

`POST /conversations/{id}/messages` isteğinin gövdesi:

| Alan | Zorunlu | Kural |
| - | - | - |
| `message` | Evet | En çok 5000 karakter. Kanalın kendi sınırı daha düşükse o geçerlidir. |
| `message_format` | Hayır | `plain` veya `markdown`. Başka değer `422` döner. |
| `quoted_message_id` | Hayır | Aynı sohbetteki bir mesajın `id` değeri. Kanalda yanıt olarak gönderilir. Bilinmeyen kimlik sessizce yok sayılır. |

Kanal başına en çok uzunluk: WhatsApp 65536, Telegram 4096, Instagram 1000, web sitesi için sınır yok. Aşılırsa `422 MESSAGE_TOO_LONG` döner.

`markdown` metni olduğu gibi saklanır ve kanala göre dönüştürülür: WhatsApp'ta `*kalın*`, `_italik_`, `~üstü çizili~`; Telegram'da HTML; Instagram ve web sitesinde düz metin.

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST "https://app.flextell.ai/api/v1/conversations/123/messages" \
    -H "Authorization: Bearer <access_token>" \
    -H "X-Tenant: <tenant_id>" \
    -H "Content-Type: application/json" \
    -d '{"message": "Merhaba Ayşe Hanım, randevunuz yarın 14:30'\''da.", "message_format": "plain"}'
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch("https://app.flextell.ai/api/v1/conversations/123/messages", {
    method: "POST",
    headers: {
      Authorization: "Bearer <access_token>",
      "X-Tenant": "<tenant_id>",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ message: "Merhaba Ayşe Hanım, randevunuz yarın 14:30'da." }),
  });
  ```
</CodeGroup>

Yanıt `202 Accepted` olur. Mesaj kuyruğa alınmıştır, henüz kanala iletilmemiş olabilir:

```json theme={null}
{
  "status": "queued",
  "message_id": "manual_...",
  "conversation_id": 123
}
```

<Note>
  `message_id` geçici bir kimliktir. Kanal mesajı kabul ettiğinde gerçek mesaj oluşur ve `channel_message_id` sağlayıcının kimliğini taşır. Gönderim yanıtı mesajın iletildiğini garanti etmez; durumu `GET /messages` ile veya [gerçek zamanlı olaylarla](/api/gercek-zamanli/kanallar-ve-olaylar) izleyin.
</Note>

Gönderimde sık görülen hatalar:

| Kod | HTTP | Ne zaman |
| - | - | - |
| `CONVERSATION_CHANNEL_MISSING` | 422 | Sohbetin kanalı artık yok. |
| `CHANNEL_INACTIVE` | 422 | Sohbetin kanalı pasif (kanalda **Aktif** kapalı). Mesaj kuyruğa alınmaz ve saklanmaz. |
| `MESSAGE_TOO_LONG` | 422 | Metin kanalın karakter sınırını aşıyor. |
| `QUOTA_EXHAUSTED` | 422 | Dönemlik WhatsApp mesaj hakkı bitti (`data.billing_type: "whatsapp"`). |
| `SUBSCRIPTION_REQUIRED` | 402 | Abonelik sona ermiş. |
| `CUSTOMER_ERASED` | 409 | Hastanın verileri imha edilmiş; sohbet salt okunurdur. |
| `LEAD_NOT_ASSIGNED` | 403 | Lead başka bir satış temsilcisine atanmış (`data.assigned_user`). |

`CHANNEL_INACTIVE`, kanalı sizin kapattığınız durumdur; kanalı yeniden etkinleştirmeden gönderim yapılamaz. Yanıtın `message` metni `Bu sohbetin kanalı pasif. Mesaj göndermek için kanalı yeniden etkinleştirin.` olur. Sağlayıcı bağlantısının kopuk olduğu durum bundan farklıdır ve `CHANNEL_NOT_CONNECTED` koduyla ayrılır. Kontrol, istek kuyruğa alınmadan önce yapılır; metin, medya, sesli not, Hızlı Yanıt, tepki ve AI önerisi gönderimi için geçerlidir.

<Note>
  İstek kabul edildikten (`202`) sonra hat kapatılırsa mesaj saklanır, ancak kanala iletilmez: mesajın `delivery_status` değeri `failed` olur ve güncel mesajla bir `ChatLogUpdated` olayı yayınlanır. `202` yanıtına güvenmeyin; durumu `GET /messages` veya gerçek zamanlı olaylarla doğrulayın.
</Note>

WhatsApp dışındaki kanallar için mesaj hakkı sayılmaz. WhatsApp'ta iletilen her mesaj bir birim harcar; sağlayıcı hatasında birim iade edilir.

<Tip>
  AI asistan o sohbette çalışıyorsa, API'den gönderilen metin, medya, sesli not veya Hızlı Yanıt asistanı 30 dakika duraklatır.
</Tip>

## Medya gönderme

`POST /conversations/{id}/messages/media` isteği `multipart/form-data` olmalıdır.

| Alan | Zorunlu | Kural |
| - | - | - |
| `file` | Evet | En çok 50 MB. Dosya türü kanalın desteklediği listede olmalıdır. |
| `message` | Hayır | Açıklama metni, en çok 5000 karakter. |
| `message_format` | Hayır | `plain` veya `markdown`. |
| `media_group_id` | Albümde | UUID. `media_group_index` ile birlikte verilir. |
| `media_group_index` | Albümde | 0–99. `media_group_id` ile birlikte verilir. |

Mesaj türü dosyanın MIME önekinden belirlenir: `image/` görsel, `audio/` ses, `video/` video, diğerleri belge. Yükleme kliniğin depolama alanından düşer; üst sınır aşılırsa `422 STORAGE_HARD_LIMIT_EXCEEDED` döner. Dosya yükleme kuralları için [Dosya yükleme](/api/istekler/dosya-yukleme) sayfasına bakın.

Kanalların gönderim için desteklediği dosya türleri:

| Kanal | Görsel | Video | Ses | Belge |
| - | - | - | - | - |
| WhatsApp | jpeg, png, gif, webp | mp4, 3gpp | mpeg, mp4, ogg, aac | pdf, doc, docx, xls, xlsx |
| Telegram | jpeg, png, gif | mp4 | mpeg, mp4, ogg | pdf |
| Instagram | jpeg, png, gif | mp4 | desteklenmez | desteklenmez |
| Web sitesi | jpeg, png, gif, webp | mp4, webm, quicktime | mpeg, mp4, ogg, webm, wav | pdf, txt, csv, doc, docx, xls, xlsx |

Desteklenmeyen tür `422 UNSUPPORTED_FILE_TYPE` döner.

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST "https://app.flextell.ai/api/v1/conversations/123/messages/media" \
    -H "Authorization: Bearer <access_token>" \
    -H "X-Tenant: <tenant_id>" \
    -F "file=@onay-formu.pdf" \
    -F "message=Onay formunuz ektedir."
  ```
</CodeGroup>

### Sesli not

`POST /conversations/{id}/messages/voice` yalnızca `file` alanını (`audio/*`, en çok 50 MB) alır ve dosyayı sesli not olarak gönderir. Açıklama metni yoktur. Instagram sesli notu desteklemez; `422 UNSUPPORTED_FILE_TYPE` döner.

### Albüm gönderme

Bir albüm için her görseli ayrı bir istekle, aynı `media_group_id` ve kendi `media_group_index` değeriyle gönderin. `media_group_id` değerini istemcinizde üretin.

<Warning>
  Aynı `media_group_id` başka bir sohbette veya başka bir kullanıcıyla kullanılırsa `422 MEDIA_GROUP_CONFLICT` döner. Albüm alanı olmayan tek medya gönderimleri izlenmez; aynı isteği tekrarlarsanız ikinci bir mesaj gider.
</Warning>

## Düzenleme, silme ve tepki

Üç işlem de yalnızca kliniğin gönderdiği (giden) mesajlarda çalışır. Hastanın mesajı hiçbir kanalda düzenlenemez veya silinemez. Kanal önce güncellenir; sağlayıcı reddederse kayıt değişmez.

| Kanal | Düzenleme | Silme (herkesten) | Tepki |
| - | - | - | - |
| WhatsApp | Yalnız metin, 15 dakika içinde | 48 saat içinde | Evet, bağlantı türüne göre desteklenmeyebilir |
| Telegram | Yalnız metin, 48 saat içinde | 48 saat içinde | Evet |
| Web sitesi | Yalnız metin, widget'ta `allow_message_editing` açıksa | Widget'ta `allow_message_deletion` açıksa; sistem mesajları silinemez | Hayır |
| Instagram | Hayır | Hayır | Hayır |

### Düzenleme

`PUT /conversations/{id}/messages/{messageId}` gövdesinde `message` (zorunlu, en çok 5000 karakter) ve isteğe bağlı `message_format` alır; biçim verilmezse mesajın mevcut biçimi korunur. Yanıt, `is_edited: true` olan güncel mesaj nesnesidir. `Update:Message` izni olan her kullanıcı, AI tarafından gönderilenler dahil, giden bir metni düzenleyebilir.

### Silme

`DELETE /conversations/{id}/messages/{messageId}` mesajı kanalda herkesten siler ve kayıtta gizler. Mesaj kaydı kalır; `is_deleted` `true` olur, `message`, `quoted_text` ve `transcript` alanları `null` döner. Sohbet listesindeki önizleme `Bu mesaj silindi` yazar. Sağlayıcı kimliği olmayan bir mesaj yalnızca Flextell'de gizlenir.

### Tepki

`POST /conversations/{id}/messages/{messageId}/reactions` gövdesinde `emoji` alanı bulunmalıdır. Değer `👍`, `❤️`, `😂`, `😮`, `😢`, `🙏` emojilerinden biridir; tepkiyi kaldırmak için `null` gönderin. Boş gövde reddedilir.

Bir mesajda klinik tarafından en fazla bir tepki bulunur. Başka bir personelin tepkisi öncekinin yerine geçer. Hastanın tepkisi ayrı tutulur.

<CodeGroup>
  ```bash Düzenleme theme={null}
  curl -X PUT "https://app.flextell.ai/api/v1/conversations/123/messages/456" \
    -H "Authorization: Bearer <access_token>" \
    -H "X-Tenant: <tenant_id>" \
    -H "Content-Type: application/json" \
    -d '{"message": "Randevunuz yarın 15:00'\''da."}'
  ```

  ```bash Tepki theme={null}
  curl -X POST "https://app.flextell.ai/api/v1/conversations/123/messages/456/reactions" \
    -H "Authorization: Bearer <access_token>" \
    -H "X-Tenant: <tenant_id>" \
    -H "Content-Type: application/json" \
    -d '{"emoji": "👍"}'
  ```
</CodeGroup>

| Kod | HTTP | Ne zaman |
| - | - | - |
| `MESSAGE_EDIT_BLOCKED` | 422 | Mesaj silinmiş, hastadan gelmiş, metin değil, kanal desteklemiyor veya süre dolmuş. |
| `MESSAGE_EDIT_FAILED` | 422 | Kanal kullanılamıyor, sağlayıcı kimliği yok veya sağlayıcı düzenlemeyi reddetti. |
| `MESSAGE_ALREADY_DELETED` | 422 | Mesaj zaten silinmiş. |
| `MESSAGE_DELETE_BLOCKED` | 422 | Hasta mesajı, süre dolmuş, Instagram veya web sitesi widget ayarı kapalı. |
| `MESSAGE_DELETE_FAILED` | 422 | Sağlayıcı silmeyi reddetti. |
| `MESSAGE_REACTION_BLOCKED` | 422 | Kanal tepkiyi desteklemiyor, mesaj silinmiş veya sağlayıcı kimliği yok. |
| `MESSAGE_REACTION_FAILED` | 422 | Sağlayıcı tepkiyi reddetti; hiçbir şey kaydedilmez. |
| `CHANNEL_INACTIVE` | 422 | Sohbetin kanalı pasif. Tepki gönderilmez. |

<Note>
  `MESSAGE_EDIT_BLOCKED` ve `MESSAGE_EDIT_FAILED` yanıtlarındaki `message` metni İngilizce gelebilir. Kodu esas alın, metni kullanıcıya olduğu gibi göstermeyin.
</Note>

## Sıralama ve tekrar deneme

Gönderim uçları asenkrondur ve yanıt `202` döner. Sıra ve tekrar için şunları bilin:

* Aynı sohbete art arda yapılan gönderimler en az 2 saniye arayla iletilir; mesajlar istek sırasıyla gider.
* Albümde teslim sırası `media_group_index` değerini izler. Bir öğe, düşük indeksli öğeleri bekler: kuyrukta veya gönderimde olanlar için en çok 120 saniye, hiç ulaşmayan bir indeks için en çok 15 saniye.
* Albüm öğesini aynı `media_group_id` ve `media_group_index` ile yeniden gönderirseniz yeni mesaj oluşmaz; ilk isteğin `message_id` değeri döner ve dosya yeniden yüklenmez.
* Önceki deneme başarısız olduysa veya 10 dakikadan uzun süredir kuyrukta ya da gönderimde takılı kaldıysa, yeniden deneme mesajı tekrar gönderir.
* Bu tekrar koruması 7 gün geçerlidir.
* Düz metin, albümsüz tek medya ve sesli not gönderimlerinde tekrar koruması yoktur. Ağ hatasında isteği hemen tekrarlamayın; önce `GET /messages` ile mesajın oluşup oluşmadığına bakın.
* Her yeni mesaj (hasta, personel, AI veya sistem) sohbeti listede yukarı taşır. İçe aktarılan eski mesajlar sohbeti geriye almaz.

Hata ve genel yanıt biçimleri için [Hatalar](/api/istekler/hatalar) ve [Hata kodları](/api/istekler/hata-kodlari), istek sınırları için [Oran sınırları](/api/istekler/oran-sinirlari) sayfasına bakın. Adım adım bir akış için [Mesaj gönderme rehberi](/api/rehberler/mesaj-gonderme) sayfasını izleyin.


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