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

# Herkese açık hasta formları

> Form linki token'ı ile hastanın formu okuyup göndermesini sağlayan açık API'yi anlatır.

Hasta formları (anamnez, onam formu vb.) hastanın giriş yapmadan doldurabileceği bir link ile paylaşılır. Kendi form sayfanızı yazmak isterseniz bu linkin arkasındaki açık API'yi kullanırsınız: bir `GET` ile formu okur, bir `POST` ile yanıtları gönderirsiniz.

Bu uçlar OAuth gerektirmez. `Authorization` ve `X-Tenant` başlıkları gönderilmez; tek kimlik bilgisi yolundaki form token'ıdır.

| Metot | Endpoint | Açıklama |
| - | - | - |
| `GET` | `/api/v1/public/forms/{token}` | Formun adını, açıklamasını ve sorularını döndürür. |
| `POST` | `/api/v1/public/forms/{token}` | Hastanın yanıtlarını kaydeder ve formu tamamlar. |

## Form linki

Form linkini klinik adına yetkili bir istemci oluşturur: `POST /api/v1/form-templates/{id}/links`. Bu çağrı `form_templates:write` scope'unu ve `GenerateLink:FormTemplate` iznini gerektirir. Ayrıntılar için [Hasta formları](/api/kaynaklar/hasta-formlari) ve [Hasta formu gönderme](/api/rehberler/hasta-formu-gonderme) sayfalarına bakın.

Gövdede isteğe bağlı `customer_id` gönderebilirsiniz. Boş bırakırsanız link anonim olur: URL'yi bilen herkes formu doldurabilir ve yanıtlar hiçbir hastaya bağlanmaz.

Yanıt `201` döner:

```json theme={null}
{
  "id": 123,
  "template_id": 45,
  "customer_id": null,
  "status": "pending",
  "token": "A1B2C3",
  "url": "https://.../forms/A1B2C3",
  "created_at": "2026-10-12T14:30:00+03:00"
}
```

<Info>
  Her çağrı yeni bir bekleyen (`pending`) form oluşturur. `token`, 6 karakterlik rastgele büyük harf ve rakam dizisidir. Açık uçların yoluna `{token}` olarak aynen yazılır.
</Info>

`url`, hastanın tarayıcıda açacağı Flextell form sayfasıdır. Bu sayfayı kullanırsanız aşağıdaki uçları çağırmanız gerekmez. Kendi sayfanızı yazıyorsanız yalnızca `token` değerini alıp açık API'yi kullanın.

## Formu okuma

```bash theme={null}
curl https://app.flextell.ai/api/v1/public/forms/A1B2C3
```

Başarılı yanıt `200` döner ve `Cache-Control: no-store` başlığı taşır.

| Alan | Tür | Açıklama |
| - | - | - |
| `token` | string | Form token'ı. |
| `status` | string | Her zaman `pending`. Tamamlanmış form `409` döndürür. |
| `name` | string | Form şablonunun adı. |
| `description` | string | Şablon editöründe yazılan giriş metni, HTML olarak. Betikler, olay işleyicileri ve güvenli olmayan URL'ler sunucuda temizlenir. HTML olarak gösterin. |
| `questions` | array | Soru listesi. |

Yanıt klinik, hasta veya personel bilgisi içermez.

### Soru nesnesi

| Alan | Tür | Açıklama |
| - | - | - |
| `id` | integer | Soru kimliği. Yanıt gönderirken anahtar olarak kullanılır. |
| `order` | integer | Görüntüleme sırası. |
| `label` | string | Soru metni. |
| `helper_text` | string veya null | Yardımcı metin. |
| `question_type` | string | `text`, `textarea`, `select`, `radio`, `checkbox`, `number`, `date` veya `boolean`. |
| `required` | boolean | Zorunlu soru. |
| `options` | array | Seçenekler: `id`, `label`, `order`. Seçim tipindeki sorularda kullanılır. |
| `visibility_rules` | array | Sorunun görünürlük kuralları. |
| `visibility_match_type` | string | Kuralların birleşimi: `all` her kural eşleşince, `any` biri eşleşince gösterir. |

Her görünürlük kuralı `id`, `depends_on_question_id`, `operator`, `value` ve `match_type` alanlarını taşır. `operator` değerleri: `equals`, `not_equals`, `in`, `not_in`, `greater_than`, `less_than`, `contains`.

<Tip>
  Kendi sayfanızda, bir sorunun kuralları sağlanmıyorsa o soruyu gizleyin. Sunucu gizli sorulardaki yanıtları doğrulamaz ve kaydetmez.
</Tip>

## Formu gönderme

`answers` zorunludur ve anahtarları soru kimliği olan bir nesnedir.

```bash theme={null}
curl -X POST https://app.flextell.ai/api/v1/public/forms/A1B2C3 \
  -H "Content-Type: application/json" \
  -d '{
    "answers": {
      "101": "Ayşe Yılmaz",
      "102": 205,
      "103": [301, 302],
      "104": "2026-10-12",
      "105": true
    }
  }'
```

Başarılı yanıt `200` döner ve `Cache-Control: no-store` başlığı taşır:

```json theme={null}
{ "message": "Formunuz başarıyla gönderildi." }
```

### Yanıt değerleri

| Soru tipi | Beklenen değer |
| - | - |
| `text` | Metin, en çok 1000 karakter. |
| `textarea` | Metin, en çok 10000 karakter. |
| `select`, `radio` | O soruya ait tek bir seçenek `id`'si. |
| `checkbox` | O soruya ait, birbirinden farklı seçenek `id`'lerinin listesi. Zorunluysa en az bir değer. |
| `number` | Sayı. |
| `date` | `Y-m-d` biçiminde tarih, örneğin `2026-10-12`. |
| `boolean` | `true`, `false`, `1` veya `0`. |

Kurallar:

* Zorunlu (`required`) ve görünür her soru yanıtlanmalıdır.
* Gizli sorular doğrulanmaz ve yanıtları atılır.
* Başka şablona ait soru kimlikleri ve sayısal olmayan anahtarlar yok sayılır.
* Gönderim tek seferliktir. Yanıtlar kaydedilince form `completed` olur ve `completed_at` dolar.
* Aynı anda gelen iki gönderimden yalnızca biri kaydedilir.

## Yanıt biçimleri

Hata gövdeleri API'nin genel hata yapısını izler. Ayrıntı için [Hatalar](/api/istekler/hatalar) sayfasına bakın. Hata mesajları `Accept-Language` başlığına göre yerelleştirilir.

| HTTP | Kod | Ne zaman |
| - | - | - |
| 404 | `RESOURCE_NOT_FOUND` | Token bulunamadı, form şablonu silinmiş ya da hasta silinmiş veya KVKK kapsamında imha edilmiş. Mesaj: `Hasta formu bulunamadı`. |
| 409 | `CUSTOMER_FORM_ALREADY_COMPLETED` | Form daha önce doldurulmuş. Mesaj: `Bu form zaten doldurulmuş.` |
| 422 | `VALIDATION_FAILED` | Yanıtlar kurallara uymuyor. |
| 429 | `TOO_MANY_REQUESTS` | Oran sınırı aşıldı. |

<Note>
  `404` yanıtı, token'ın yanlış olmasıyla şablonun ya da hastanın silinmiş olması arasında ayrım yapmaz. Bu bilinçlidir: token tahmin etmeye çalışan biri hiçbir şey öğrenemez.
</Note>

### Doğrulama hataları

`422` yanıtında hatalar `answers.{soru_id}` anahtarıyla gelir. Checkbox öğeleri için anahtar `answers.{soru_id}.{n}` olur. Alan adı olarak sorunun `label` değeri kullanılır.

Örneğin zorunlu `Ad Soyad` sorusu boş bırakılırsa `answers.101` anahtarı altında `The Ad Soyad field is required.` biçiminde bir mesaj gelir. Hata gövdesinin genel yapısı için [Hatalar](/api/istekler/hatalar) sayfasına bakın.

## Tek kullanımlık formlar

Her link bir kez doldurulabilir.

1. Link oluşturulduğunda form `pending` durumundadır.
2. Başarılı bir `POST` formu `completed` yapar.
3. Bundan sonra aynı token ile hem `GET` hem `POST` `409 CUSTOMER_FORM_ALREADY_COMPLETED` döndürür.

Hastaya yeniden doldurtmak için yeni bir link oluşturun. Başarısız (örneğin `422`) bir gönderim formu tamamlamaz; hasta düzeltip yeniden gönderebilir.

<Note>
  Formu doldurmak hastanın ön görüşme (intake) durumunu değiştirmez. Bu uçlar kliniğin faturalama veya kurulum durumuna da bağlı değildir.
</Note>

## Oran sınırları

Sınırlar form token'ına değil, istemcinin IP adresine uygulanır. Token'lar kısa olduğu için sınır tüm token'ları birlikte sayar; böylece token tahmini engellenir.

| Kapsam | Sınır |
| - | - |
| `GET` ve `POST`, tüm token'lar birlikte | IP başına dakikada 60 |
| Yalnızca `POST` (ek olarak) | IP başına dakikada 10 |

Sınır aşılınca `429 TOO_MANY_REQUESTS` döner. Yanıt, oran sınırı başlıklarını ve `Retry-After` değerini taşır;  beklenen süre dolmadan yeniden denemeyin. Kimliği doğrulanmış API'nin sınırları farklıdır: [Oran sınırları](/api/istekler/oran-sinirlari).

<Tip>
  Form sayfasını sunucunuz üzerinden çağırırsanız tüm hastalar aynı IP'den görünür ve sınırı birlikte tüketir. Çağrıları hastanın tarayıcısından yapın.
</Tip>

## İlgili sayfalar

<CardGroup cols={2}>
  <Card title="Hasta formları" icon="clipboard-list" href="/api/kaynaklar/hasta-formlari">
    Form şablonları, link oluşturma ve doldurulan formlar.
  </Card>

  <Card title="Hasta formu gönderme" icon="send" href="/api/rehberler/hasta-formu-gonderme">
    Link oluşturmadan yanıtları okumaya uçtan uca akış.
  </Card>
</CardGroup>


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