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

# Rehber: randevu oluşturma

> Uygun saatleri sorgulayıp randevu oluşturmaya ve hastaya bildirim göndermeye kadar uçtan uca bir örnek akış sunar.

Bu rehber, harici bir yazılımdan Flextell'de randevu açmanın uçtan uca akışını gösterir: hastayı bulursunuz, doktorun tedavilerini ve boş saatlerini sorgularsınız, randevuyu oluşturursunuz ve hastaya randevu mesajının gidip gitmeyeceğini yönetirsiniz. Alan alan ayrıntı için [Randevular](/api/kaynaklar/randevular) sayfasına bakın.

## Senaryo

Bir randevu sayfası, "Ayşe Yılmaz" adlı hasta için 20 Ekim 2026'da doktor kimliği `45` olan doktora 30 dakikalık bir muayene randevusu açmak istiyor. Akış beş istekten oluşur:

```mermaid theme={null}
flowchart LR
  A[Hastayı ara] --> B[Doktorun tedavileri]
  B --> C[Uygun saatler]
  C --> D[Randevuyu oluştur]
  D --> E[Bildirim kanalını doğrula]
```

Tüm isteklerde `Authorization: Bearer <access_token>` ve `X-Tenant: <tenant_id>` başlıkları kullanılır. Bkz. [Klinikler ve X-Tenant](/api/klinikler-ve-x-tenant).

| Adım | Endpoint | Scope | İzin |
| - | - | - | - |
| Hasta arama | `GET /customers` | `customers:read` | `View:Customer` |
| Doktorun tedavileri | `GET /appointments/options/doctors/{id}/treatments` | `appointments:read` | `Create:Appointment` veya `Update:Appointment` |
| Uygun saatler | `GET /appointments/available-slots` | `appointments:read` | `Create:Appointment` veya `Update:Appointment` |
| Randevu oluşturma | `POST /appointments` | `appointments:write` | `Create:Appointment` |
| Randevuyu ve kanalları okuma | `GET /appointments/{id}` | `appointments:read` | `View:Appointment` |

Token'ınız bu scope'ları taşımalıdır. Bkz. [Scope'lar](/api/kimlik-dogrulama/scopelar).

## Hasta ve tedaviyi bulma

Önce hastayı arayın. `search` parametresi ad, soyad, e-posta ve kimlik numarasında alt dize arar; telefon numarasında da rakamları eşleştirir. Baştaki `0` atılarak da denenir, yani `0532 123` ifadesi `905321234567` ile eşleşir. Terimde en az 2 karakterlik bir sözcük ya da en az 3 rakam yoksa liste boş döner.

Yeni iş başlatan seçicilerde `exclude_erased=1` kullanın. Verileri imha edilmiş hastalar varsayılan olarak listede yer alır ve bu hastalar için yazma işlemi `409 CUSTOMER_ERASED` ile reddedilir.

<CodeGroup>
  ```bash curl theme={null}
  curl "https://app.flextell.ai/api/v1/customers?search=Ay%C5%9Fe%20Y%C4%B1lmaz&exclude_erased=1" \
    -H "Authorization: Bearer <access_token>" \
    -H "X-Tenant: <tenant_id>"
  ```
</CodeGroup>

Yanıttaki `data[].id` değeri, randevudaki `customer_id` olur (örnekte `123`). Hasta henüz yoksa `POST /customers` ile oluşturun; bkz. [Hastalar](/api/kaynaklar/hastalar). Hasta bir lead ise `customer_id` yerine `lead_id` gönderebilirsiniz; ikisini birlikte göndermeyin.

Sonra doktorun yaptığı tedavileri alın. Randevudaki her tedavi seçilen doktora atanmış olmalıdır.

<CodeGroup>
  ```bash curl theme={null}
  curl "https://app.flextell.ai/api/v1/appointments/options/doctors/45/treatments" \
    -H "Authorization: Bearer <access_token>" \
    -H "X-Tenant: <tenant_id>"
  ```
</CodeGroup>

Yanıt `data` dizisinde `{id, name, invoice_name, group}` nesneleri verir. Örnekte seçilen tedavinin kimliği `7`'dir. Doktorları listelemek için `GET /appointments/options/doctors` kullanın; bu uç nokta yalnızca aktif doktorları döner. Kimlik bir doktora ait değilse `404` (`Doktor bulunamadı`) alırsınız.

## Uygun saatleri sorgulama

`GET /appointments/available-slots` doktorun o günkü önerilen başlangıç saatlerini verir. Üç parametre de zorunludur: `date`, `user_id` (doktor) ve `duration_minutes` (5–1440).

<CodeGroup>
  ```bash curl theme={null}
  curl "https://app.flextell.ai/api/v1/appointments/available-slots?date=2026-10-20&user_id=45&duration_minutes=30" \
    -H "Authorization: Bearer <access_token>" \
    -H "X-Tenant: <tenant_id>"
  ```
</CodeGroup>

```json theme={null}
{
  "success": true,
  "data": {
    "date": "2026-10-20",
    "timezone": "Europe/Istanbul",
    "suggested_step_minutes": 15,
    "slots": [
      { "start_at": "09:00", "end_at": "09:30" },
      { "start_at": "09:15", "end_at": "09:45" }
    ],
    "appointments": [],
    "closed_periods": []
  }
}
```

Örnekteki değerler yalnızca biçimi gösterir. Yanıtı şöyle okuyun:

* `slots[].start_at` ve `end_at` `HH:mm` metnidir. Randevunun `scheduled_at` değerini, `date` ile saati birleştirip klinik saat dilimi sapmasını ekleyerek kurun: `2026-10-20T09:15:00+03:00`.
* Öneriler kapanış saatine kadar uzanır ama **çakışmalara göre elenmez**. Doktorun o günkü bekleyen ve onaylı randevularını `appointments`, tatil kapanışlarını `closed_periods` alanından okuyup kullanıcıya uyarı olarak gösterin.
* Klinik o gün haftalık çalışma düzenine göre kapalıysa hata alınmaz; `200` ile boş diziler döner.

Detaylar için [Randevu uygunluğu ve takvim](/api/kaynaklar/randevu-uygunlugu-ve-takvim) sayfasına bakın.

<Note>
  Manuel randevu; geçmiş tarih, kapalı gün, çalışma saati dışı, slot ızgarası dışı dakika, tatil veya doktorun başka randevusuyla çakışma yüzünden reddedilmez. Bu denetimler sizin uygulamanızın sorumluluğundadır.
</Note>

## Randevu oluşturma

Seçtiğiniz saatle `POST /appointments` çağırın. Başarılı yanıt `201` ve randevu nesnesidir.

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://app.flextell.ai/api/v1/appointments \
    -H "Authorization: Bearer <access_token>" \
    -H "X-Tenant: <tenant_id>" \
    -H "Content-Type: application/json" \
    -d '{
      "customer_id": 123,
      "user_id": 45,
      "treatments": [7],
      "status": "pending",
      "scheduled_at": "2026-10-20T09:15:00+03:00",
      "duration_minutes": 30,
      "description": "İlk muayene"
    }'
  ```
</CodeGroup>

Zorunlu alanlar `customer_id` (veya `lead_id`), `user_id`, `treatments[]`, `status` ve `scheduled_at`'tir. `status` olarak `cancelled` dışındaki herhangi bir değer verilebilir; yeni randevu için genellikle `pending` (Bekliyor) ya da `approved` (Onaylandı) kullanılır. `scheduled_at` sapma içermezse klinik saati olarak okunur.

Yanıtta sunucunun ürettiği `id` ve `code` (`APT-XXXXXXXXXX`) alanlarını saklayın. Tedavinin seans şablonu varsa seanslar otomatik planlanır; ilk seans bu randevuya bağlanır. Seans planı için bkz. [Randevular](/api/kaynaklar/randevular).

<Warning>
  `POST /appointments` idempotency anahtarını desteklemez. Zaman aşımı sonrası isteği körlemesine tekrarlarsanız aynı hasta için ikinci bir randevu oluşabilir. Önce `GET /appointments?customer_id=123&scheduled_at_from=2026-10-20&scheduled_at_to=2026-10-20` ile randevunun oluşup oluşmadığını kontrol edin. Bkz. [Idempotency](/api/istekler/idempotency).
</Warning>

## Hastaya bildirim

Randevu oluşturulduktan sonra hastaya bir bilgilendirme mesajı gidebilir. Bu mesaj kliniğin **Randevu Oluşturma** mesaj şablonuyla hazırlanır. Şablonu [Mesaj şablonları](/api/kaynaklar/mesaj-sablonlari) ile yönetirsiniz.

| Alan | Etkisi |
| - | - |
| `send_message` | `true` mesaj gönderilmesini ister, `false` göndermez. Boş bırakırsanız kliniğin oluşturma bildirimi ayarı (`send_on_create`, varsayılan açık) geçerlidir. Bkz. [Bildirim ve hatırlatma ayarları](/panel/sistem/ayarlar/bildirim-ve-hatirlatma). |
| `channel_id` | Mesajın gideceği kanal. Etkin ve bağlı (`status=open`) olmalıdır. |
| `channel_identifier` | Hastanın o kanaldaki adresi: WhatsApp için telefon, Telegram için sayısal sohbet kimliği, Instagram için IGSID. Hastanın kanalda kayıtlı adresi yoksa zorunludur ve hastaya iletişim kimliği olarak kaydedilir. |

`channel_id` göndermezseniz sunucu kanalı şu sırayla seçer ve randevuya yazar: hastanın en son yazdığı kanal, hastanın varsayılan kanalı, kliniğin varsayılan bildirim kanalı, ardından ulaşılabilir herhangi bir kanal. Her aday etkin, bağlı ve hastaya ulaşabilir olmalıdır.

Belirli bir kanaldan göndermek için:

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://app.flextell.ai/api/v1/appointments \
    -H "Authorization: Bearer <access_token>" \
    -H "X-Tenant: <tenant_id>" \
    -H "Content-Type: application/json" \
    -d '{
      "customer_id": 123,
      "user_id": 45,
      "treatments": [7],
      "status": "approved",
      "scheduled_at": "2026-10-20T09:15:00+03:00",
      "send_message": true,
      "channel_id": 12,
      "channel_identifier": "+90 5xx xxx xx xx"
    }'
  ```
</CodeGroup>

Hastanın hangi kanallardan ulaşılabilir olduğunu görmek için `GET /appointments/{id}` yanıtındaki `customer.notification_channels` bloğunu okuyun. `default_channel_id`, `source` ve her kanal için `type`, `address`, `status`, `is_reachable` alanlarını içerir. Randevunun kendi kanalı seçili ve ulaşılabilirse `source` değeri `preferred` olur.

<Warning>
  Mesaj sessizce atlanabilir ve API bunu hata olarak bildirmez. Mesaj şu durumlarda gönderilmez: randevunun başlangıcı geçmişteyse, ulaşılabilir bir kanal ya da alıcı yoksa, şablon boş çıkıyorsa.&#x20;
  Mesajın neden gitmediğini araştırmak için bkz. [Mesajlar ve hatırlatmalar sorun giderme](/panel/sorun-giderme/mesajlar-ve-hatirlatmalar).
</Warning>

Randevudan önceki hatırlatmalar ayrı bir akıştır; bkz. [Randevu hatırlatmaları](/api/kaynaklar/randevu-hatirlatmalari).

## Hata durumları

Hata gövdesi `{"success": false, "error_code": "...", "message": "..."}` biçimindedir; doğrulama hatalarında `errors` alanı da gelir. Ortak kodlar için [Hata kodları](/api/istekler/hata-kodlari) sayfasına bakın.

| Durum | HTTP | `error_code` | Ne yapmalı |
| - | - | - | - |
| Hasta, doktor, tedavi, oda veya asistan kliniğe ait değil | 422 | `VALIDATION_FAILED` | Kimlikleri bu rehberdeki seçenek uç noktalarından alın. |
| Tedavi seçilen doktora atanmamış | 422 | `VALIDATION_FAILED` | `Seçilen tedavi, seçilen doktora atanmamış.` Doktorun tedavilerini yeniden sorgulayın. |
| `status: "cancelled"` ile oluşturma | 422 | `VALIDATION_FAILED` | Önce `pending` veya `approved` ile oluşturun, sonra iptal edin. |
| `customer_id` ve `lead_id` birlikte gönderildi | 422 | `VALIDATION_FAILED` | Yalnızca birini gönderin. |
| Kanal bağlı değil | 422 | `VALIDATION_FAILED` | `Seçilen kanalın bağlantısı kopuk; kanalı yeniden bağlayın veya başka bir kanal seçin.` Bkz. [Kanallar](/api/kaynaklar/kanallar). |
| Hastanın kanalda adresi yok | 422 | `VALIDATION_FAILED` | `channel_identifier` da gönderin. |
| Kanal kimliği başka bir hastada kayıtlı | 422 | `VALIDATION_FAILED` | `Bu kanal kimliği başka bir hasta tarafından kullanılıyor.` Kimliği doğrulayın. |
| Hastanın verileri imha edilmiş | 409 | `CUSTOMER_ERASED` | Kayıt salt okunurdur; başka bir hasta kaydı seçin. |
| Lead size atanmamış (yalnızca kendi lead'lerini gören satış temsilcisi) | 403 | `LEAD_NOT_ASSIGNED` | `data.assigned_user` atanan kişiyi gösterir. Bkz. [İzinler ve görünürlük](/api/izinler-ve-gorunurluk). |
| `Create:Appointment` izni ya da scope eksik | 403 | `FORBIDDEN` | Token scope'larını ve kullanıcının rolünü kontrol edin. |
| `X-Tenant` başlığı eksik | 400 | `TENANT_HEADER_REQUIRED` | Bkz. [Klinikler ve X-Tenant](/api/klinikler-ve-x-tenant). |
| Oran sınırı aşıldı | 429 | `TOO_MANY_REQUESTS` | Bkz. [Oran sınırları](/api/istekler/oran-sinirlari). |

<Tip>
  Doğrulama hataları `errors` içinde alan adıyla gelir (`customer_id`, `treatments`, `channel_id` gibi). Kullanıcıya genel `message` yerine ilgili alanın mesajını gösterin.
</Tip>


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