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

# Kullanıcılar, roller ve davetler

> Klinik kullanıcılarını, rolleri, izin kataloğunu ve kliniğe davetleri yönetmeyi anlatır.

Bu sayfa, bir kliniğin personelini API'den yönetmeyi anlatır: kullanıcıları listeleme ve oluşturma, rolleri düzenleme, izin kataloğunu okuma ve başka bir kliniğe davet gönderme.

Bir kişinin tek bir hesabı vardır; her klinik bu hesaba yalnızca üyelik ve o kliniğe özel roller ekler. Rol ve izinler her zaman `X-Tenant` ile seçtiğiniz klinik için geçerlidir. Bu yüzden başka bir kliniğe verilen izin, ilk klinikte işe yaramaz.

<Info>
  Panelde aynı işlemler için bkz. [Kullanıcılar](/panel/sistem/kullanicilar), [Roller](/panel/sistem/roller) ve [İzin kataloğu](/panel/sistem/izin-katalogu). Asistanlar için bkz. [Doktorlar, asistanlar ve odalar](/api/kaynaklar/doktorlar-asistanlar-odalar).
</Info>

## Endpoint özeti

Taban adres `https://app.flextell.ai/api/v1`. `POST /invitations/preview` ve `/account/*` uçları dışındaki her uç `X-Tenant` başlığı ister ([Klinikler ve X-Tenant](/api/klinikler-ve-x-tenant)). Her çağrıda hem scope hem de kliniğinizdeki izin gerekir ([İzinler ve görünürlük](/api/izinler-ve-gorunurluk)).

| Metot | Endpoint | Açıklama | Scope | İzin |
| - | - | - | - | - |
| GET | `/users` | Kullanıcıları listeler | `users:read` | `View:User` |
| POST | `/users` | Kullanıcı oluşturur | `users:write` | `Create:User` |
| GET | `/users/{id}` | Kullanıcıyı getirir | `users:read` | `View:User` |
| PUT | `/users/{id}` | Kullanıcıyı günceller | `users:write` | `Update:User` |
| DELETE | `/users/{id}` | Kullanıcıyı siler | `users:write` | `Delete:User` |
| GET | `/users/{id}/deletion-relations` | Silmenin etkileyeceği kayıtları gösterir | `users:read` | `Delete:User` |
| GET | `/users/{id}/roles` | Kullanıcının bu klinikteki rolleri | `users:read` | Kendi `id`'niz için yok, başkası için `View:User` |
| PUT | `/users/{id}/roles` | Kullanıcının rollerini değiştirir | `users:write` | `Update:User` ve `Update:Role` |
| GET | `/roles` | Rolleri listeler | `roles:read` | `View:Role` |
| POST | `/roles` | Rol oluşturur | `roles:write` | `Create:Role` |
| GET | `/roles/{id}` | Rolü izinleriyle getirir | `roles:read` | `View:Role` |
| PUT | `/roles/{id}` | Rolü ve izinlerini günceller | `roles:write` | `Update:Role` |
| DELETE | `/roles/{id}` | Rolü siler | `roles:write` | `Delete:Role` |
| GET | `/permissions` | Atanabilir izin kataloğu | `roles:read` | `View:Role` |
| GET | `/invitations` | Kliniğin davetlerini listeler | `invitations:read` | `View:User` |
| POST | `/invitations` | Davet oluşturur | `invitations:write` | `View:User` ve `Invite:User` |
| POST | `/invitations/{id}/resend` | Daveti yeniden gönderir | `invitations:write` | `View:User` ve `Invite:User` |
| DELETE | `/invitations/{id}` | Daveti iptal eder | `invitations:write` | `View:User` ve `Invite:User` |
| POST | `/invitations/preview` | Davet bağlantısını önizler (herkese açık) | Yok | Yok |
| GET | `/account/invitations` | Size gelen davetleri listeler | `account:read` | Doğrulanmış e-posta |
| POST | `/account/invitations/resolve` | Davet kodunu çözer | `account:read` | Yok |
| POST | `/account/invitations/{id}/accept` | Daveti kabul eder | `account:write` | Davet sizin e-postanıza gelmiş olmalı |
| POST | `/account/invitations/{id}/reject` | Daveti reddeder | `account:write` | Davet sizin e-postanıza gelmiş olmalı |

`users`, `roles`, `permissions` ve `invitations` uçları kurulum kilidine (`428 SETUP_REQUIRED`) takılmaz. Abonelik kilitleri bu uçlarda da geçerlidir ([Erişim kilitleri](/api/istekler/erisim-kilitleri)).

## Kullanıcılar

Kullanıcı alanları hesap geneldir: ad, e-posta, parola, telefon, unvan ve `is_active` kişinin tüm kliniklerinde aynıdır. Bir klinikte yaptığınız düzenleme, kişinin üye olduğu diğer klinikleri de etkiler.

### Listeleme

Liste yalnızca `X-Tenant` ile seçtiğiniz kliniğin üyelerini döndürür. Sayfalama için bkz. [Sayfalama](/api/istekler/sayfalama), sıralama kuralları için [Filtreleme ve sıralama](/api/istekler/filtreleme-ve-siralama).

| Parametre | Açıklama |
| - | - |
| `search` | En çok 255 karakter. `name` ve `email` içinde büyük/küçük harf ayırmadan arar. Yalnızca rakamdan oluşan terim `id` ile de eşleşir. |
| `sort_by` | `name`, `email`, `created_at`, `updated_at`, `last_login_at`. Varsayılan `created_at`. |
| `sort_order` | `asc` veya `desc`. Varsayılan `desc`. |
| `is_active` | `true` veya `false`. Göndermezseniz pasif kullanıcılar da gelir. |
| `role` | Rol **adı**, örneğin `doctor`. Var olan bir rol olmalı. |
| `title` | `Uzm. Dr.`, `Dr.`, `Prof. Dr.`, `Doç. Dr.`, `Arş. Gör.`, `Öğr. Gör.` değerlerinden biri. Başka değer 422 döndürür. |
| `created_at_from`, `created_at_to`, `updated_at_from`, `updated_at_to` | Tarih aralığı (kapsayıcı). |
| `per_page`, `page` | `per_page` 1–100, varsayılan 15. |

### Kullanıcı oluşturma ve güncelleme

`POST /users` her zaman yeni bir hesap açar. `email` hiçbir canlı hesapta kayıtlı olmamalıdır; zaten Flextell hesabı olan birini başka bir kliniğe [davetle](#davetler) ekleyin. `PUT /users/{id}` aynı alanları kabul eder, hepsi isteğe bağlıdır.

| Alan | Zorunlu | Kural |
| - | - | - |
| `name` | Evet | Ad soyad. |
| `email` | Evet | Hesaplar arasında benzersiz. |
| `password`, `password_confirmation` | Hayır | En az 8 karakter, onayla eşleşmeli. |
| `phone` | Hayır | En çok 20 karakter. |
| `title` | Hayır | En çok 255 karakter. |
| `emergency_contact_name`, `emergency_contact_surname` | Hayır | En çok 255 karakter. |
| `emergency_contact_phone_number` | Hayır | En çok 20 karakter. |
| `blood_group` | Hayır | En çok 10 karakter. |
| `language` | Hayır | Dizi. Güncellemede değerler `Turkish`, `English`, `Other` olmalı. |
| `is_active` | Hayır | `true` veya `false`. |
| `bio` | Hayır | En çok 1000 karakter. |
| `role_ids` | Hayır | Rol kimlikleri. Göndermek için `Update:Role` iznine de sahip olmalısınız. Güncellemede mevcut rollerin yerine geçer. |

`password` göndermezseniz sistem rastgele bir parola atar ve kullanıcıya parola belirleme e-postası yollar; bağlantı 60 dakika geçerlidir. `avatar_url` gönderseniz de yok sayılır.

Yanıt `{"success": true, "data": {...}}` biçimindedir; oluşturma `201` döner. Gönderdiğiniz alanlara ek olarak şunları içerir: `id`, `avatar_url`, `last_login_at`, `last_login_ip`, `roles` (bu klinikteki `{id, name}` çiftleri), `import_source` (yalnızca tekil okumada, yoksa `null`), `created_at`, `updated_at`, `deleted_at`.

<CodeGroup>
  ```bash Kullanıcı oluşturma theme={null}
  curl -X POST "https://app.flextell.ai/api/v1/users" \
    -H "Authorization: Bearer <access_token>" \
    -H "X-Tenant: <tenant_id>" \
    -H "Content-Type: application/json" \
    -d '{"name": "Ayşe Yılmaz", "email": "ayse@example.com", "role_ids": [7]}'
  ```

  ```bash Rolleri değiştirme theme={null}
  curl -X PUT "https://app.flextell.ai/api/v1/users/123/roles" \
    -H "Authorization: Bearer <access_token>" \
    -H "X-Tenant: <tenant_id>" \
    -H "Content-Type: application/json" \
    -d '{"role_ids": [7, 9]}'
  ```
</CodeGroup>

### Silme

`DELETE /users/{id}` kişi başka bir aktif kliniğin de üyesiyse yalnızca bu kliniğin üyeliğini ve bu klinikteki rollerini kaldırır. Başka klinik yoksa hesabın kendisi silinir. Geri alma ya da kalıcı silme endpoint'i yoktur. Randevu, satış ve destek talepleri geçmişte kalır.

Silmeden önce `GET /users/{id}/deletion-relations` ile bu klinikte etkilenecek kayıtlara bakın. Yanıt `[{relation, label, count, deleted}]` listesidir ve yalnızca en az bir kaydı olan ilişkileri içerir. `relation` değerleri `appointments` (Randevular), `assistant_appointments` (Asistan olduğu randevular), `sales` (Satışlar) ve `tickets` (Destek talepleri) olur. `deleted` her zaman `false`'tur; geçmiş korunur.

## Roller ve izinler

Her klinik 7 sistem rolüyle açılır. API rol adlarını İngilizce anahtarlarıyla döndürür.

| Rol adı | Panelde |
| - | - |
| `super_admin` | Süper Yönetici |
| `doctor` | Doktor |
| `assistant` | Asistan |
| `accountant` | Muhasebeci |
| `coordinator` | Koordinatör |
| `salesperson` | Satış Temsilcisi |
| `sales_director` | Satış Direktörü |

`super_admin` bir joker değildir. Her izne açıkça sahiptir.

### Rol nesnesi ve listeleme

Rol nesnesi: `id`, `tenant_id`, `name`, `is_system`, `created_at`, `updated_at`. `permissions_count` liste, tekil okuma, oluşturma ve güncelleme yanıtlarında; `permissions` (`[{id, name}]`) tekil okuma, oluşturma ve güncelleme yanıtlarında gelir.

`GET /roles` parametreleri: `search` (en çok 255 karakter), `is_system` (`true`/`false`), `sort_by` (`name`, `created_at`, `updated_at`; varsayılan `created_at`), `sort_order` (varsayılan `desc`), `per_page` (1–100, varsayılan 15) ve `page`.

### Rol oluşturma ve güncelleme

`POST /roles` ve `PUT /roles/{id}` şu alanları alır.

| Alan | Kural |
| - | - |
| `name` | Oluşturmada zorunlu. En çok 255 karakter, klinikte benzersiz. |
| `permissions` | İzin adları dizisi (`View:Lead` gibi). Güncellemede **tam değiştirme** yapar, `[]` tüm izinleri kaldırır. Adlar `GET /permissions` katalogunda olmalı ve tekrarlanmamalı. |

* `is_system`, `tenant_id` ve `guard_name` gönderseniz de yok sayılır; rol her zaman özel rol olarak bu klinikte oluşur.
* Sistem rollerinin adı değişmez (422, `name`). İzinleri düzenlenebilir.
* Sistem rolleri silinemez (403). Özel bir rolü silmek kalıcıdır ve role sahip kullanıcılar rolü hemen kaybeder.
* API izinsiz rol kabul eder. Panel formu ise en az bir izin ister.

### Yetki yükseltme koruması

Sahip olmadığınız bir izni veremezsiniz. Kurallar rol düzenlemede ve rol atamada geçerlidir; `super_admin` rolüne sahip kullanıcılar bu kuralların dışındadır.

| İşlem | Kural |
| - | - |
| Role izin ekleme | Yalnızca kendinizin sahip olduğu izinleri ekleyebilirsiniz. İhlalde 403 `FORBIDDEN` döner ve `data.missing_permissions` eksik izinleri listeler. İzin kaldırmak her zaman serbesttir. |
| Kendi rolleriniz | Kendi rollerinizi değiştiremezsiniz. |
| `super_admin` rolü | Bu rolü yalnızca bir `super_admin` verebilir ya da kaldırabilir. |
| Role sahip kullanıcıya rol ekleme | Sahip olmadığınız bir izni içeren rolü atayamazsınız. Rol kaldırma serbesttir. |

Rol atama ihlalleri `role_ids` alanında 422 döner. Bu mesajlar İngilizce ya da sabit Türkçedir ve `Accept-Language` ile değişmez. Yalnızca eklenen ya da kaldırılan roller denetlenir; kullanıcının mevcut rollerini aynen yeniden kaydetmek sorun çıkarmaz.

### Rol atama

`PUT /users/{id}/roles` kullanıcının bu klinikteki rollerini `role_ids` ile **tamamen** değiştirir. `role_ids` alanı zorunludur; boş dizi bu klinikteki tüm rolleri kaldırır. Yalnızca bu kliniğin rolleri kabul edilir; diğer kliniklerdeki roller etkilenmez.

### İzin kataloğu ve kendi izinleriniz

`GET /permissions` atanabilir izinleri modül ve gruba göre döndürür:

```json theme={null}
{
  "success": true,
  "data": [
    {
      "module_key": "lead",
      "module_label": "Lead / Potansiyel Hasta",
      "group_key": "Lead",
      "group_label": "Lead'ler",
      "permissions": [
        {"id": 41, "name": "View:Lead", "label": "Görüntüle"}
      ]
    }
  ]
}
```

İzin adı `Fiil:Konu` biçimindedir. `label` `Accept-Language` ile yerelleşir; `module_label` ve `group_label` her zaman Türkçedir. Yalnızca klinik rollerine atanabilen izinler döner. Kendi izinlerinizi görmek için `X-Tenant` ile `GET /account/roles` çağırın ([Hesap](/api/kaynaklar/hesap)). Scope'lar için bkz. [Scope'lar](/api/kimlik-dogrulama/scopelar).

## Davetler

Mevcut bir Flextell hesabını başka bir kliniğe eklemenin tek yolu davettir. Davet bir e-posta adresine ve tek bir role bağlıdır.

`POST /invitations` gövdesi:

| Alan | Zorunlu | Kural |
| - | - | - |
| `email` | Evet | Geçerli e-posta, en çok 255 karakter. Baştaki/sondaki boşluklar silinir, küçük harfe çevrilir. |
| `role_id` | Evet | Bu kliniğin bir rolü (tam sayı). Genel roller kabul edilmez. |

Sistem şu sırayla denetler ve ilk hatada durur: e-posta zaten bu kliniğin üyesi mi, boş kullanıcı kotası var mı, rol bu kliniğe ait ve atanabilir mi, aynı e-posta için süresi dolmamış bekleyen başka davet var mı. Davet 7 gün geçerlidir ve e-postayla gider. E-postada **Daveti görüntüle** düğmesi ve 8 karakterli **Davet kodu** bulunur. Kod ve bağlantı anahtarı API yanıtında dönmez.

* Bekleyen davetler kullanıcı kotasında yer ayırmaz. Kota yalnızca oluşturma, yeniden gönderme ve kabul anında denetlenir.
* Rol, davet edenin sahip olduğu izinlerle sınırlıdır. Yalnızca `super_admin` biri `super_admin` olarak davet edebilir.
* Davet oluşturma, yeniden gönderme, önizleme ve çözümleme birlikte dakikada 10 istekle sınırlıdır ([Oran sınırları](/api/istekler/oran-sinirlari)).
* Kliniğinizden çıkarılmış bir üyeyi yeniden davet edebilirsiniz.
* Bu API yeni hesap oluşturmaz. Davet edilen kişinin önce bir Flextell hesabı olmalıdır.

Davet nesnesi: `id`, `email`, `tenant` (`{id, name}`), `role_id`, `role_name` (örneğin `doctor`), `status`, `expires_at`, `processed_at`, `created_at`.

| `status` | Anlamı |
| - | - |
| `pending` | Yanıt bekliyor. |
| `accepted` | Kabul edildi. |
| `rejected` | Alıcı reddetti. |
| `cancelled` | Klinik iptal etti. |
| `expired` | Süresi doldu. Saklamada `pending` kalır, API `expired` bildirir. |

`GET /invitations` en yeni davetten başlar. `status`, `created_at_from`, `created_at_to`, `expires_at_from`, `expires_at_to`, `per_page` ve `page` ile filtrelenir.

* **Yeniden gönderme:** `POST /invitations/{id}/resend` yalnızca bekleyen (süresi dolmuş olanlar dahil) davetler için çalışır. Kodu ve bağlantıyı yeniler, eskileri geçersiz kılar, süreyi 7 gün sıfırlar. Rol aynı kalır.
* **İptal:** `DELETE /invitations/{id}` yalnızca bekleyen davetleri `cancelled` yapar. E-posta gitmez, kayıt geçmişte kalır.

```bash theme={null}
curl -X POST "https://app.flextell.ai/api/v1/invitations" \
  -H "Authorization: Bearer <access_token>" \
  -H "X-Tenant: <tenant_id>" \
  -H "Content-Type: application/json" \
  -d '{"email": "ayse@example.com", "role_id": 7}'
```

## Daveti kabul etme

Bu bölüm davet edilen kişinin tarafıdır. Bu çağrılar klinik adına değil, kendi hesabı adına yapılır ve `X-Tenant` istemez.

<Steps>
  <Step title="Daveti bulun">
    E-postadaki bağlantıda `token` (64 küçük harfli onaltılık karakter) bulunur. `POST /invitations/preview` bu `token` ile, oturum açmadan davetin hangi klinik ve e-posta için olduğunu gösterir. Giriş yapmış kişi 8 karakterli kodla `POST /account/invitations/resolve` çağırabilir ya da `GET /account/invitations` ile kendi davetlerini listeleyebilir. Çözümleme daveti tüketmez.
  </Step>

  <Step title="Kabul edin">
    `POST /account/invitations/{id}/accept` çağırın. E-postanız doğrulanmışsa gövde gerekmez. Doğrulanmamışsa e-postayla gelen `code` ya da `token` değerini gönderin; kabul e-postanızı da doğrulanmış yapar.
  </Step>

  <Step title="Sonucu okuyun">
    Yanıt, katıldığınız kliniğin bilgisini `setup_required` alanıyla birlikte döndürür. Davetteki rol, o klinikteki önceki rollerinizin yerine geçer. Diğer kliniklerdeki üyelik ve rolleriniz değişmez.
  </Step>
</Steps>

```bash theme={null}
curl -X POST "https://app.flextell.ai/api/v1/account/invitations/45/accept" \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{"code": "ABCD2345"}'
```

Daveti reddetmek için aynı gövdeyle `POST /account/invitations/{id}/reject` çağırın; yanıtta `status` değeri `rejected` olur. Başkasına ait bir davet ya da var olmayan bir `id`, aynı şekilde 404 `INVITATION_INVALID` döndürür.

Kabul için hesabınızda `name` dolu olmalıdır, kullanıcı kotasında yer olmalıdır ve davetteki rol hâlâ var olmalıdır.

## Kurallar ve hatalar

Hata zarfı ve genel kodlar için bkz. [Hata kodları](/api/istekler/hata-kodlari).

| Kod | HTTP | Ne zaman |
| - | - | - |
| `USER_LIMIT_REACHED` | 422 | Kliniğin kullanıcı kotası dolu. Aktif kullanıcı oluştururken, davet oluştururken, yeniden gönderirken ve kabul ederken oluşur. Pasif kullanıcıyı `PUT /users/{id}` ile aktif ederken bu kod yerine `VALIDATION_FAILED` döner (aşağıya bakın). |
| `USER_SAVE_FAILED` | 422 | Kullanıcı kaydedilemedi, tekrar deneyin. |
| `INVITATION_INVALID` | 404 | Davet bulunamadı, e-posta size ait değil ya da doğrulama kodu/anahtarı yanlış. |
| `INVITATION_EXPIRED` | 410 | Davetin süresi dolmuş. |
| `INVITATION_PROCESSED` | 409 | Davet artık bekleyen durumda değil. |
| `INVITATION_DUPLICATE` | 409 | Aynı e-posta için süresi dolmamış başka bir bekleyen davet var. |
| `INVITATION_ALREADY_MEMBER` | 409 | Kişi zaten bu kliniğin üyesi. |
| `INVITATION_EMAIL_UNVERIFIED` | 403 | E-postanız doğrulanmadan davetleri listelediniz ya da kod/anahtar olmadan kabul/ret yaptınız. |
| `INVITATION_ROLE_INVALID` | 422 | Rol bu kliniğe ait değil, silinmiş ya da atama yetkiniz yok. |
| `INVITATION_PROFILE_INCOMPLETE` | 422 | Kabul eden hesapta `name` boş. |
| `INVITATION_DELIVERY_UNAVAILABLE` | 503 | Davet gönderimi yapılandırılmamış. Hiçbir kayıt oluşmaz. |
| `FORBIDDEN` | 403 | Scope ya da izin eksik, sistem rolünü silmeye çalıştınız veya role sahip olmadığınız izni eklediniz. |
| `RESOURCE_NOT_FOUND` | 404 | Kullanıcı, rol ya da davet bu klinikte yok. Başka kliniğin kimliği de 404 döner. |
| `VALIDATION_FAILED` | 422 | Alan doğrulaması başarısız. `errors.<alan>` ayrıntı verir. |
| `TENANT_HEADER_REQUIRED` | 400 | `X-Tenant` başlığı yok. |
| `TENANT_NOT_FOUND` | 404 | Klinik yok ya da üye değilsiniz. |

Kota kuralı: yalnızca kliniğin aktif kullanıcıları sayılır. Pasif kullanıcı oluşturmak ve kullanıcıyı pasife almak hiçbir zaman engellenmez. `PUT /users/{id}` ile aktifleştirmede kota hatası `USER_LIMIT_REACHED` kodu yerine `errors.is_active` alanında `VALIDATION_FAILED` olarak döner.


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