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

# Form şablonları ve hasta formları

> Form şablonlarını, soruları, seçenekleri, görünürlük kurallarını, form linklerini ve doldurulan formları anlatır.

Bir **Form Şablonu**, kliniğin hastaya doldurttuğu formun taslağıdır: başlık, açıklama ve sıralı sorular. Şablondan bir form linki oluşturduğunuzda, hastanın dolduracağı bir **hasta formu** doğar. Hasta linki açıp formu gönderdiğinde form `completed` durumuna geçer ve yanıtlar kaydedilir.

Bu sayfa, entegrasyon geliştiricisi olarak şablonları yönetmeyi, link üretmeyi ve doldurulan formları okumayı anlatır. Hastanın linki açtığı herkese açık uçlar (`/public/forms/{token}`) için [herkese açık hasta formları](/api/webhooklar/herkese-acik-hasta-formlari) sayfasına bakın. Uçtan uca akış için [hasta formu gönderme](/api/rehberler/hasta-formu-gonderme) rehberini izleyin. Panelde şablonlar için [Form Şablonları](/panel/iletisim/form-sablonlari), doldurulan formların listesi için [Doldurulan Formlar](/panel/iletisim/doldurulan-formlar) sayfaları vardır; panelde link üretme ve yanıtları görüntüleme henüz çalışmaz.

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

## Endpoint özeti

Taban adres `https://app.flextell.ai/api/v1` şeklindedir.

| Metot | Endpoint | Açıklama | Scope | İzin |
| - | - | - | - | - |
| `GET` | `/form-templates` | Şablonları listeler | `form_templates:read` | `View:FormTemplate` |
| `POST` | `/form-templates` | Şablon oluşturur | `form_templates:write` | `Create:FormTemplate` |
| `GET` | `/form-templates/{id}` | Şablonu soruları, seçenekleri ve kurallarıyla getirir | `form_templates:read` | `View:FormTemplate` |
| `PUT` | `/form-templates/{id}` | Şablonu kısmi günceller | `form_templates:write` | `Update:FormTemplate` |
| `DELETE` | `/form-templates/{id}` | Şablonu siler | `form_templates:write` | `Delete:FormTemplate` |
| `POST` | `/form-templates/{id}/links` | Form linki oluşturur | `form_templates:write` | `GenerateLink:FormTemplate` |
| `POST` | `/form-templates/{id}/questions` | Şablona soru ekler | `form_templates:write` | `Update:FormTemplate` |
| `PUT` | `/form-templates/{id}/questions/{questionId}` | Soruyu günceller | `form_templates:write` | `Update:FormTemplate` |
| `DELETE` | `/form-templates/{id}/questions/{questionId}` | Soruyu siler | `form_templates:write` | `Update:FormTemplate` |
| `GET` | `/customer-forms` | Kliniğin tüm hasta formlarını listeler | `customer_forms:read` | `View:CustomerForm` |
| `GET` | `/customers/{customerId}/form` | Bir hastanın formlarını listeler | `customer_forms:read` ve `customers:read` | `View:Customer` ve `View:CustomerForm` |
| `GET` | `/customers/{customerId}/form/{customerFormId}` | Doldurulmuş formu yanıtlarıyla getirir | `customer_forms:read` ve `customers:read` | `View:Customer` ve `View:CustomerForm` |

<Note>
  `customer_forms:write` adlı bir scope yoktur. Link oluşturma `form_templates:write`, form okuma `customer_forms:read` scope'u ile yapılır. Soru ekleme, düzenleme ve silme için ayrı bir izin yoktur; hepsi `Update:FormTemplate` ister.
</Note>

## Form şablonları

### Şablon nesnesi

| Alan | Tür | Açıklama |
| - | - | - |
| `id` | integer | Şablon kimliği. |
| `name` | string | Şablon adı. En fazla 255 karakter. Klinikte, silinmemiş şablonlar arasında benzersizdir. |
| `system_name` | string | Adın slug hâli. Yalnızca şablon oluşturulurken üretilir; ad sonradan değişse de aynı kalır. |
| `description` | string, HTML | Hastaya gösterilen açıklama. Hastaya sunulurken güvenli HTML öğelerine indirgenir. |
| `is_active` | boolean | Şablon aktif mi. |
| `questions` | array | Yalnızca `GET /form-templates/{id}` yanıtında gelir. |
| `created_at`, `updated_at`, `deleted_at` | datetime | Zaman damgaları. |

### Listeleme

`GET /form-templates` sayfalı bir koleksiyon döndürür; liste satırlarında `questions` yoktur. Genel sayfalama kuralları için [sayfalama](/api/istekler/sayfalama) sayfasına bakın.

| Parametre | Açıklama |
| - | - |
| `search` | Ad ve açıklamada tam metin (önek) araması. |
| `is_active` | `0`, `1`, `true` veya `false`. |
| `sort_by` | `name`, `created_at`, `updated_at`, `is_active`. Varsayılan `created_at`, azalan. |
| `sort_order` | `asc` veya `desc`. |
| `per_page` | 1–100. |

### Oluşturma, güncelleme, silme

`POST /form-templates` gövdesinde `name` ve `is_active` zorunludur; `description` isteğe bağlıdır. `PUT` kısmi çalışır: yalnızca gönderdiğiniz alanlar değişir.

```bash theme={null}
curl -X POST "https://app.flextell.ai/api/v1/form-templates" \
  -H "Authorization: Bearer <access_token>" \
  -H "X-Tenant: <tenant_id>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Anamnez formu",
    "description": "<p>Randevunuzdan önce lütfen doldurun.</p>",
    "is_active": true
  }'
```

Başarılı yanıt `201` ile oluşan şablonu döndürür. Silme yumuşaktır ve şablonun doldurulmuş formları olsa bile çalışır; yanıt `{"success": true, "data": {"message": "Form şablonu başarıyla silindi"}}` biçimindedir. Silinen şablondan üretilmiş linkler açılmaz (`404`).

<Info>
  `is_active` bu uçlarda link oluşturmayı veya formu doldurmayı engellemez. Pasif şablondan da link üretebilirsiniz. Aktiflik, AI asistanın ve randevu öncesi form ayarlarının kullanabileceği şablonları belirlemek için denetlenir.
</Info>

## Sorular ve seçenekler

Bir şablonun soruları `questions` dizisinde `order` alanına göre sıralı gelir. Soru ekleme ve güncelleme ayrı uçlardan yapılır; şablon güncellemesi soruları değiştirmez.

### Soru nesnesi

| Alan | Tür | Açıklama |
| - | - | - |
| `id` | integer | Soru kimliği. |
| `order` | integer | Görüntüleme sırası, 0 veya büyük. |
| `label` | string | Soru metni, en fazla 255 karakter. |
| `helper_text` | string veya null | Sorunun altında gösterilen yardımcı metin. |
| `question_type` | string | Aşağıdaki tür değerlerinden biri. |
| `required` | boolean | Hasta bu soruyu yanıtlamak zorunda mı. |
| `options` | array | `{id, label, order}` nesneleri. |
| `visibility_rules` | array | Görünürlük kuralları. |
| `visibility_match_type` | string | Kuralların nasıl birleştiği: `all` veya `any`. |

### Soru türleri

| `question_type` | Arayüz adı | Hasta yanıtı |
| - | - | - |
| `text` | Metin | Metin, en fazla 1000 karakter. |
| `textarea` | Çok Satırlı Metin | Metin, en fazla 10000 karakter. |
| `select` | Seçim Listesi | Sorunun bir seçeneğinin `id`'si. |
| `radio` | Radyo Buton | Sorunun bir seçeneğinin `id`'si. |
| `checkbox` | Onay Kutusu | Sorunun seçenek `id`'lerinden oluşan dizi. |
| `number` | Sayı | Sayısal değer. |
| `date` | Tarih | `YYYY-MM-DD`. |
| `boolean` | Evet/Hayır | `true`, `false`, `0` veya `1`. |

### Soru ekleme

`POST /form-templates/{id}/questions` gövdesinde `label`, `question_type`, `required` ve `order` zorunludur. `options` içindeki her öğede `label` ve `order` bulunur. Tüm soru, seçenekleri ve kurallarıyla tek işlemde oluşturulur.

```bash theme={null}
curl -X POST "https://app.flextell.ai/api/v1/form-templates/123/questions" \
  -H "Authorization: Bearer <access_token>" \
  -H "X-Tenant: <tenant_id>" \
  -H "Content-Type: application/json" \
  -d '{
    "label": "Kronik rahatsızlığınız var mı?",
    "question_type": "radio",
    "required": true,
    "order": 1,
    "options": [
      { "label": "Evet", "order": 0 },
      { "label": "Hayır", "order": 1 }
    ]
  }'
```

### Soru güncelleme ve silme

`PUT` kısmi çalışır. Seçenek ve kural alanları gönderildiğinde şöyle davranır:

| Gönderilen alan | Davranış |
| - | - |
| `options` | Seçenekleri eşitler. Listede `id`'si olan öğe güncellenir, `id`'siz öğe eklenir, listede olmayan mevcut seçenek kalıcı olarak silinir. |
| `visibility_rules` | Sorunun tüm kurallarını gönderdiğiniz listeyle değiştirir. |

<Warning>
  Güncellemede `options` göndermeniz, listede olmayan seçenekleri siler. Mevcut seçenekleri korumak istiyorsanız hepsini `id`'leriyle birlikte gönderin.
</Warning>

`DELETE` soruyu siler. Daha önce kaydedilmiş yanıtlar korunur.

## Görünürlük kuralları

Bir soru, başka bir sorunun yanıtına göre gösterilip gizlenebilir. Kuralı olmayan soru her zaman görünür.

| Alan | Açıklama |
| - | - |
| `depends_on_question_id` | Yanıtı denetlenecek soru. Aynı şablonda, silinmemiş bir soru olmalı; bir soru kendine bağlanamaz. |
| `operator` | Karşılaştırma işleci. |
| `value` | Karşılaştırılacak değer; tek değer ya da dizi olabilir. Seçim türlerinde seçeneğin `id`'sini kullanın. |
| `match_type` | `all` veya `any`. Varsayılan `all`. |

| `operator` | Arayüz adı | Davranış |
| - | - | - |
| `equals` | Eşittir | Tek yanıtta değer listede; onay kutusunda aynı küme. |
| `not_equals` | Eşit Değildir | `equals` işlecinin tersi. |
| `in` | İçinde | Yanıt, verilen değerlerden biri. |
| `not_in` | İçinde Değil | `in` işlecinin tersi. |
| `greater_than` | Büyüktür | Yalnızca sayısal karşılaştırma. |
| `less_than` | Küçüktür | Yalnızca sayısal karşılaştırma. |
| `contains` | İçerir | Yalnızca onay kutusu yanıtlarında anlamlıdır; tek değerli yanıtta her zaman yanlıştır. |

Kurallar şu şekilde çalışır:

* Bir sorunun birden çok kuralı varsa hepsi, **ilk kuralın** `match_type` değeriyle birleştirilir. Yanıtta bu değer sorunun `visibility_match_type` alanında görünür.
* Gizli bir soru yanıtlanmamış sayılır. Gizli bir soruya bağlı soru da gizlenir.
* Gizli sorular doğrulanmaz ve gönderilen yanıtları atılır.

Aşağıdaki örnek, 456 numaralı sorunun "Evet" seçeneğine (`id` 789) bağlı bir soru ekler.

```bash theme={null}
curl -X POST "https://app.flextell.ai/api/v1/form-templates/123/questions" \
  -H "Authorization: Bearer <access_token>" \
  -H "X-Tenant: <tenant_id>" \
  -H "Content-Type: application/json" \
  -d '{
    "label": "Hangi rahatsızlık?",
    "question_type": "textarea",
    "required": true,
    "order": 2,
    "visibility_rules": [
      {
        "depends_on_question_id": 456,
        "operator": "equals",
        "value": "789",
        "match_type": "all"
      }
    ]
  }'
```

<Note>
  Kural, bağımlı olduğu sorudan önce eklenemez: `depends_on_question_id` mevcut bir soruyu göstermelidir. Önce bağımlı olunan soruyu ve seçeneklerini oluşturun, yanıtta dönen `id`'leri kuralda kullanın.
</Note>

## Form linki oluşturma

`POST /form-templates/{id}/links` şablondan bekleyen (`pending`) yeni bir form üretir ve hastanın açacağı linki döndürür. `customer_id` isteğe bağlıdır.

| Alan | Zorunlu | Açıklama |
| - | - | - |
| `customer_id` | Hayır | Klinikteki bir hastanın kimliği. Boş bırakırsanız **anonim link** oluşur; linke sahip herkes formu doldurabilir. |

```bash theme={null}
curl -X POST "https://app.flextell.ai/api/v1/form-templates/123/links" \
  -H "Authorization: Bearer <access_token>" \
  -H "X-Tenant: <tenant_id>" \
  -H "Content-Type: application/json" \
  -d '{ "customer_id": 456 }'
```

```json theme={null}
{
  "success": true,
  "data": {
    "id": 1001,
    "template_id": 123,
    "customer_id": 456,
    "status": "pending",
    "token": "A1B2C3",
    "url": "https://<form-adresi>/forms/A1B2C3",
    "created_at": "2026-10-13T10:00:00+03:00"
  }
}
```

`token`, 6 karakterlik büyük harf ve rakamdan oluşur ve herkese açık uçlarda `{token}` olarak kullanılır. `url`, hastanın açacağı formun adresidir. Linki hastaya kendiniz iletirsiniz, örneğin bir sohbet mesajıyla.

<Warning>
  Her çağrı yeni bir form ve yeni bir token üretir. Aynı hasta için tekrar çağırmak, bekleyen ilk formu yeniden kullanmaz.
</Warning>

<Info>
  Panelde **Form Şablonları** listesindeki **Bağlantı Oluştur** işlemi şu an link üretmez, yalnızca `Bağlantı oluşturma şu anda kullanılamıyor.` uyarısını gösterir. Link üretmek için bu uç noktayı kullanın.
</Info>

### Link hataları

| Kod | HTTP | Ne zaman |
| - | - | - |
| `RESOURCE_NOT_FOUND` | 404 | Şablon bulunamadı (`Form şablonu bulunamadı`). |
| `VALIDATION_FAILED` | 422 | `customer_id` klinikte yok (`Seçilen hasta bulunamadı.`). |
| `CUSTOMER_ERASED` | 409 | Hastanın verileri imha edilmiş; kayıt salt okunurdur. |
| `LEAD_NOT_ASSIGNED` | 403 | Hasta, başka bir satış temsilcisine atanmış lead aşamasında ve izniniz yalnızca kendi kayıtlarınızı kapsıyor. |

Genel hata kodları için [hata kodları](/api/istekler/hata-kodlari) sayfasına bakın.

## Doldurulan formlar

Hasta formu üç durumdan birinde olur.

| `status` | Arayüz adı | Anlamı |
| - | - | - |
| `pending` | Bekliyor | Link oluşturuldu, form henüz doldurulmadı. |
| `completed` | Tamamlandı | Form gönderildi. Tamamlanmış form yeniden doldurulamaz. |
| `reviewed` | İncelendi | Filtre ve görüntüleme değeri. |

Form hastanın kendisi, personel veya AI asistan tarafından doldurulabilir. Listelerde `filled_by_user_id` dolu ise formu bir personel doldurmuştur; `is_ai_generated` `true` ise AI asistan doldurmuştur; ikisi de boşsa hasta kendi doldurmuştur.

### Kliniğin tüm formları

`GET /customer-forms` yalnızca `customer_forms:read` scope'u ve `View:CustomerForm` izni ister. Yanıt normal bir sayfalı koleksiyondur ve yanıtları içermez.

| Parametre | Açıklama |
| - | - |
| `search` | Hasta adı, telefon, e-posta, T.C. kimlik no veya şablon adı. Aksan duyarsızdır. |
| `template_id` | Şablona göre filtre. |
| `status` | `pending`, `completed`, `reviewed`. |
| `is_ai_generated` | `0`, `1`, `true`, `false`. |
| `created_at_from`, `created_at_to` | Oluşturulma aralığı. |
| `completed_at_from`, `completed_at_to` | Tamamlanma aralığı. |
| `sort_by` | `id`, `status`, `completed_at`, `created_at`, `updated_at`. Varsayılan `created_at`, azalan. |
| `per_page`, `page` | Sayfalama. |

Her satırın alanları:

| Alan | Tür | Açıklama |
| - | - | - |
| `id` | integer | Hasta formu kimliği. |
| `record_state` | object | Salt okunur durumu; imha edilmiş hastada `is_read_only: true`. |
| `template_id`, `template` | integer, object | Şablon kimliği ve `{id, name}`. |
| `customer_id`, `customer` | integer, object | Hasta kimliği ve `{id, first_name, last_name, full_name}`. |
| `status` | string | Form durumu. |
| `token` | string | Form tokenı. |
| `is_ai_generated` | boolean | AI asistan tarafından doldurulduysa `true`. |
| `completed_at` | datetime veya null | Tamamlanma zamanı. |
| `assigned_by_user_id`, `assigned_by_user` | integer, object | Linki oluşturan kullanıcı. |
| `filled_by_user_id`, `filled_by_user` | integer, object | Formu hasta adına dolduran personel. |
| `created_at`, `updated_at` | datetime | Zaman damgaları. |

### Bir hastanın formları ve yanıtlar

Yanıtları yalnızca hasta bazlı detay ucu döndürür.

```bash theme={null}
curl "https://app.flextell.ai/api/v1/customers/456/form/1001" \
  -H "Authorization: Bearer <access_token>" \
  -H "X-Tenant: <tenant_id>"
```

Yanıtın `data` alanı; `template.questions[]` (seçenekleri ve görünürlük kurallarıyla), `answers[]` (her biri `question` ile), `customer`, `assigned_by_user` ve `filled_by_user` ilişkilerini içerir. Soru tek seçimliyse yanıt, seçeneğin `id`'si olarak kayıtlıdır; seçeneğin metnini şablondaki `options` listesinden eşleştirin. Evet/Hayır sorusunda "Hayır" yanıtı `0` olarak gelir ve yanıtsız anlamına gelmez.

`GET /customers/{customerId}/form` aynı hastanın formlarını listeler. `status`, `template_id`, `sort_by` (`id`, `status`, `completed_at`, `created_at`, `updated_at`), `sort_order`, `per_page` ve `page` parametrelerini kabul eder.

<Warning>
  Hasta bazlı iki uç, genel `/customer-forms` ucundan farklı bir biçimde yanıt verir. Liste, sayfalayıcıyı `data` içinde taşır, yani satırlara `data.data[]` ile ulaşırsınız. Satırlar, `token` dahil modelin tüm alanlarını ham hâliyle içerir. İki yanıt biçimini de işleyin.
</Warning>

Bu uçlar hasta görünürlük kuralına tabidir. Bulunamayan, başka kliniğe ait, kapsam dışı ya da lead aşamasındaki bir `customerId` listede `200` ile boş sonuç, detayda `404 RESOURCE_NOT_FOUND` (`Hasta formu bulunamadı`) döndürür.

### Hata kodları

| Kod | HTTP | Ne zaman |
| - | - | - |
| `RESOURCE_NOT_FOUND` | 404 | Form, şablon veya soru yok ya da kapsam dışı. |
| `VALIDATION_FAILED` | 422 | Geçersiz filtre veya gövde alanı; `errors` nesnesi alan adlarını verir. |
| `FORBIDDEN` | 403 | Scope veya izin eksik (`Bu işlem için yetkiniz yok.`). |
| `CUSTOMER_ERASED` | 409 | İmha edilmiş hasta için link oluşturma. |

Yetkilendirme modeli için [izinler ve görünürlük](/api/izinler-ve-gorunurluk) sayfasına bakın.


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