
# Ekip API'si

Ekibiniz, hesabınızda sizin dışınızda çalışan herkesi (yöneticiler, temsilciler ve salt okunur görüntüleyiciler) ve gönderdiğiniz davetiyeleri ve onları düzenlediğiniz departmanları kapsar. Ekip API'si, **Ayarlar → Ekip** bölümünün programatik sürümüdür: kişileri ekleyip çıkarabilir, her birinin neyi görüp yapabileceğini ayarlayabilir, davetiye gönderebilir veya hatırlatabilir ve departmanları yönetebilirsiniz.

Aşağıdaki tüm uç noktalar `https://api.youraiconnector.com/v1` temel URL'sine göredir. Bu sayfadaki her şeyin kontrol paneli sürümü için [Ekip Yönetimi](../settings/team-management.md) bölümüne bakın.

---

## Kimlik Doğrulama: bu uç noktalar oturum açmış bir kişi gerektirir

**Bu, API'nin bir API anahtarının kullanamayacağı tek kısmıdır.** [departman](#departments) uç noktaları dışındaki her `/team` uç noktası, oturum açmış bir oturumdan alınan bir **Firebase ID token** ile çağrılmalıdır:

```
Authorization: Bearer <Firebase ID token>
```

Bunun yerine bir API anahtarı gönderirseniz, istek `401` ile reddedilir:

```json
{
  "success": false,
  "error_code": 401,
  "error": "This endpoint requires a Firebase ID token (Authorization: Bearer <token>)."
}
```

Bunun nedeni, bu uç noktaların **kimin oturum açtığına** göre ne yapılacağına karar vermesidir: rolünüz, başka birine verebileceğiniz yetkilerin sınırı ve şu anda başka bir hesap içinde çalışıp çalışmadığınız. Bir API anahtarı bir entegrasyondur, bir kişi değildir; bu nedenle bu kuralların uygulanabileceği kimse yoktur.

Uygulamada bu, Ekip API'sinin oturum açmış bir <span data-t="appName">Your AI Connector</span> kullanıcısı olan birinci taraf bir uygulama için olduğu anlamına gelir (bkz. [Kimlik Doğrulama → Firebase ID token](authentication.md#4-firebase-id-token-first-party-only)). Sunucudan sunucuya bir entegrasyon ekip üyelerini yönetemez; uygulama dışından bu token'lardan birini oluşturmanın bir yolu yoktur.

> **İstisna:** dört [departman](#departments) uç noktası normal API uç noktalarıdır. API'nin geri kalanı gibi API anahtarınızı ve oturum açmış bir oturumu kabul ederler.

Bu sayfadaki her yanıt, olağan zarfı takip eder: `success: true` artı en üst düzeyde uç noktanın alanları veya bir şeyler ters gittiğinde `error` ve `error_code` ile `success: false`.

---

## Roller ve izinler

Her ekip üyesinin, uygulamanın 12 alanındaki varsayılan erişimini belirleyen bir **rolü** vardır. Daha sonra bireysel alanları geçersiz kılabilirsiniz.

| Rol | Değer | Özet |
|---|---|---|
| Yönetici | `admin` | Sahibinin faturalandırma düzeyi işlemleri dışındaki her şey. |
| Düzenleyici | `editor` | Bir şeyler oluşturabilir ve değiştirebilir. Uygulamada **Temsilci** olarak görünür. |
| Görüntüleyici | `viewer` | Salt okunur. |

Her alan dört düzeyden birine ayarlanır: `none` (gizli), `view` (salt okunur), `edit` (oluşturma ve değiştirme), `full` (silme dahil).

| Alan | Yönetici | Düzenleyici | Görüntüleyici |
|---|---|---|---|
| `campaigns` | tam | düzenle | görüntüle |
| `contacts` | tam | düzenle | görüntüle |
| `messages` | tam | düzenle | görüntüle |
| `appointments` | tam | düzenle | görüntüle |
| `settings` | düzenle | görüntüle | yok |
| `billing` | düzenle | yok | yok |
| `team_management` | düzenle | yok | yok |
| `analytics` | tam | görüntüle | görüntüle |
| `phone_numbers` | düzenle | yok | yok |
| `integrations` | düzenle | yok | yok |
| `faqs` | tam | düzenle | görüntüle |
| `daily_summaries` | tam | görüntüle | görüntüle |

Rolün varsayılanlarından sapmak için `permission_overrides` gönderin — bir `{ "area": ..., "level": ... }` nesneleri dizisi. Her girdi, o alan için rolün varsayılanını değiştirir; listelemediğiniz her şey rol varsayılanını korur.

```json
"permission_overrides": [
  { "area": "analytics", "level": "full" },
  { "area": "billing", "level": "none" }
]
```

**Bu uç noktaları kimler çağırabilir**

- **Hesap sahibi** her zaman her şeyi yapabilir.
- Bir ekip üyesinin kadroyu ve davet listesini okuması için `view` seviyesinde `team_management` yetkisine; ekleme, değiştirme, askıya alma, kaldırma, davet etme, iptal etme veya yeniden gönderme işlemleri için ise `edit` seviyesinde yetkiye ihtiyacı vardır. Yöneticiler varsayılan olarak `edit` yetkisine sahiptir; düzenleyiciler ve görüntüleyenler `none` yetkisine sahiptir, bu nedenle varsayılan olarak yalnızca yöneticiler ekibi yönetebilir.
- **Hiç kimse kendi erişim seviyesinin üzerinde erişim veremez.** Birine kendinizde olmayan bir seviye vermeye çalışırsanız veya erişimi sizinkinden daha geniş olan birini düzenlemeye, askıya almaya veya kaldırmaya çalışırsanız, istek `403` hatası ve ilgili alanı belirten bir mesajla reddedilir.

---

## Ekip üyesi nesnesi

`GET /team/members`, üye başına bunlardan birini döndürür:

| Alan | Tür | Açıklama |
|---|---|---|
| `member_uid` | string | Üyenin kendi kullanıcı kimliği. Bu, aşağıdaki yollardaki `{memberUid}` değeridir. |
| `account_owner_uid` | string | Üyesi oldukları hesap. |
| `member_email` | string | E-posta adresleri. |
| `member_display_name` | string | Uygulamada onlar için gösterilen ad. |
| `role` | string | `admin`, `editor` veya `viewer`. |
| `permission_overrides` | array | Alana özel istisnaları. Tamamen rol varsayılanlarındalarsa `[]` değerini alır. |
| `status` | string | `active` veya `suspended`. |
| `auto_assign_enabled` | boolean \| null | Yeni kişilerin onlara otomatik olarak atanıp atanamayacağı. `null`, hiç değiştirilmediği anlamına gelir ve `true` gibi davranır. |
| `created_by` | string | Onları kimin eklediği. |
| `created_at` | string \| null | ISO 8601 zaman damgası. |
| `updated_at` | string \| null | ISO 8601 zaman damgası. |

Kaldırılan üyeler döndürülmez — liste yalnızca aktif ve askıya alınmış üyeleri içerir.

> **Görünürlük sınırları burada yalnızca yazılabilirdir.** `contact_scope`, `contact_scope_axes` ve `sub_account_access` (bkz. [Bir üyenin neleri görebileceğini sınırlama](#limiting-what-a-member-can-see)) oluşturma, güncelleme ve davet etme sırasında ayarlanabilir, ancak bu uç nokta bunları döndürmez.

---

## Ekip üyelerini listele

`GET /team/members`

Kadroyu ve planınızın koltuk sayılarını döndürür, böylece "5 koltuktan 3'ü dolu" gibi bir gösterim yapabilir ve davet etme işleminin ne zaman reddedileceğini anlayabilirsiniz.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/team/members" \
  -H "Authorization: Bearer FIREBASE_ID_TOKEN"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/team/members", {
  headers: { Authorization: `Bearer ${idToken}` },
});
const { members, seat_limit, seats_used } = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/team/members",
    headers={"Authorization": f"Bearer {id_token}"},
)
data = res.json()
```

**Yanıt**

```json
{
  "success": true,
  "members": [
    {
      "account_owner_uid": "owner_uid_123",
      "member_uid": "uid_alice",
      "member_email": "alice@example.com",
      "member_display_name": "Alice Chen",
      "role": "admin",
      "permission_overrides": [],
      "status": "active",
      "auto_assign_enabled": true,
      "created_by": "owner_uid_123",
      "created_at": "2026-05-01T10:00:00.000Z",
      "updated_at": "2026-06-02T09:15:00.000Z"
    }
  ],
  "seat_limit": 5,
  "seats_used": 3
}
```

Planınızda koltuk sınırı yoksa `seat_limit` değeri `null` olur. `seats_used` yalnızca **aktif** üyeleri sayar — birini askıya almak veya kaldırmak koltuğunu hemen boşaltır.

---

## Doğrudan bir ekip üyesi ekle

`POST /team/members`

Birini davet göndermeye gerek kalmadan doğrudan ekibinize dahil eder.

> **Bu işlem e-posta göndermez.** Kimseye eklendiklerine dair bildirim gitmez ve eğer halihazırda bir <span data-t="appName">Your AI Connector</span> girişleri yoksa, onlar için oluşturulan hesabın **parolası yoktur**, bu nedenle parolayı sıfırlayana kadar giriş yapamazlar. Kişiye durumu kendiniz bildirecek bir yolunuz yoksa ve giriş yapmalarını sağlayamıyorsanız [Davetiye gönder](#send-an-invitation) seçeneğini kullanın.

**İstek alanları**

| Alan | Zorunlu | Açıklama |
|---|---|---|
| `email` | Evet | Ekip arkadaşının e-posta adresi. |
| `display_name` | Evet | Uygulamada onlar için görünen ad. |
| `role` | Evet | `admin`, `editor` veya `viewer`. |
| `permission_overrides` | Hayır | Rolün varsayılanlarına göre alan bazlı istisnalar. |
| `contact_scope` | Hayır | `all` veya `assigned` — bkz. [Bir üyenin ne görebileceğini sınırlama](#limiting-what-a-member-can-see). |
| `contact_scope_unassigned` | Hayır | `assigned` ile birlikte, henüz kimseye atanmamış kişileri de görmelerini sağlayın. |
| `contact_scope_axes` | Hayır | Onları belirli temsilciler, kanallar veya departmanlarla sınırlandırın. |
| `sub_account_access` | Hayır | Yalnızca ajanslar için — açabilecekleri müşteri alt hesapları. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/team/members" \
  -H "Authorization: Bearer FIREBASE_ID_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "sam@example.com",
    "display_name": "Sam Rivera",
    "role": "editor"
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/team/members", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${idToken}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    email: "sam@example.com",
    display_name: "Sam Rivera",
    role: "editor",
  }),
});
const { member_uid } = await res.json();
```

**Yanıt** — `201 Created`

```json
{
  "success": true,
  "team_member_id": "owner_uid_123_uid_sam",
  "member_uid": "uid_sam",
  "message": "Team member created successfully."
}
```

| Durum | Ne zaman |
|---|---|
| `400` | `email`, `display_name` veya `role` eksikse, rol bu üçünden biri değilse veya kendinizi eklemeye çalıştıysanız. |
| `403` | Ekibi yönetme izniniz yoksa veya kendi erişiminizden daha yüksek bir erişim vermeye çalıştıysanız. |
| `409` | O kişi zaten ekibinizin aktif bir üyesidir. |
| `429` | Planınızdaki ekip koltukları dolu. |

Daha önce **askıya alınmış veya kaldırılmış** birini eklemek, işlem başarısız olmak yerine onları yeniden etkinleştirir.

---

## Bir ekip üyesini güncelle

`PATCH /team/members/{memberUid}`

Bir üyenin rolünü, izinlerini, görünürlüğünü, müşteri erişimini veya otomatik kişi atamasına katılıp katılmadığını değiştirir. Yalnızca değiştirmek istediğiniz alanları gönderin; dışarıda bıraktığınız her şey mevcut değerini korur.

**İstek alanları**

| Alan | Açıklama |
|---|---|
| `role` | `admin`, `editor` veya `viewer`. |
| `permission_overrides` | Tüm geçersiz kılma listelerini değiştirir. Onları tamamen rol varsayılanlarına döndürmek için `[]` gönderin. |
| `status` | Askıya alınmış bir üyeyi geri getirmek için yalnızca `active` kabul edilir. Birini askıya almak için [askıya alma uç noktasını](#suspend-a-team-member) kullanın. |
| `auto_assign_enabled` | `true` veya `false`. |
| `contact_scope` | `all` veya `assigned`. |
| `contact_scope_unassigned` | `true` veya `false`. |
| `contact_scope_axes` | Bkz. [Bir üyenin ne görebileceğini sınırlama](#limiting-what-a-member-can-see). |
| `sub_account_access` | Yalnızca ajanslar için. |

> **Bu, `null` ifadesinin "temizle" anlamına geldiği tek uç noktadır.** `"contact_scope": null`, `"contact_scope_axes": null` veya `"sub_account_access": null` göndermek, bu sınırı tamamen kaldırır ve üyenin her şeyi tekrar görmesini sağlar. Oluşturma ve davet etme işlemlerinde `null` basitçe "sağlanmadı" anlamına gelir.

**cURL**

```bash
curl -X PATCH "https://api.youraiconnector.com/v1/team/members/uid_sam" \
  -H "Authorization: Bearer FIREBASE_ID_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "role": "admin",
    "permission_overrides": [{ "area": "billing", "level": "none" }]
  }'
```

**Yanıt**

```json
{
  "success": true,
  "message": "Team member updated successfully."
}
```

| Durum | Ne zaman |
|---|---|
| `400` | Geçersiz bir `status` veya `auto_assign_enabled` değeri varsa ya da kaldırılmış bir üyeyi yeniden etkinleştirmeye çalıştıysanız (kaldırılan üyeler yeniden davet edilmelidir). |
| `403` | İzniniz yoksa veya değişiklik, kendi erişiminizden daha geniş bir erişim düzenleyecek ya da oluşturacaksa. |
| `404` | Böyle bir ekip üyesi yok. |

---

## Bir ekip üyesini askıya al

`POST /team/members/{memberUid}/suspend`

Birini askıya alır: ekipteki yerlerini korurlar ancak erişimlerini kaybederler. Duraklatma geçici olduğunda kaldırmak yerine bunu kullanın — `PATCH /team/members/{memberUid}` ve `{"status": "active"}` ile onları geri getirin.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/team/members/uid_sam/suspend" \
  -H "Authorization: Bearer FIREBASE_ID_TOKEN"
```

**Yanıt**

```json
{
  "success": true,
  "message": "Team member suspended successfully."
}
```

Askıya alınan bir üye **koltuğunu boşaltır**, böylece yerine başka birini davet edebilirsiniz. Erişimleri, mevcut oturum belirteçleri bir sonraki yenilendiğinde sona erer; bu işlem bir saate kadar sürebilir — işlemin anında gerçekleşmesi gerekiyorsa onları kaldırın.

| Durum | Ne zaman |
|---|---|
| `400` | Hesap sahibini veya zaten askıya alınmış ya da kaldırılmış bir üyeyi askıya almaya çalıştıysanız. |
| `403` | Erişimleri sizinkinden daha genişse. |
| `404` | Böyle bir ekip üyesi yok. |

---

## Bir ekip üyesini kaldırın

`DELETE /team/members/{memberUid}`

Birini ekibinizden çıkarır ve koltuğunu boşaltır. Oturumları kapatılır ve hesabınıza erişimlerini kaybederler; kendi giriş bilgileri etkilenmez.

**cURL**

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/team/members/uid_sam" \
  -H "Authorization: Bearer FIREBASE_ID_TOKEN"
```

**Yanıt**

```json
{
  "success": true,
  "message": "Team member removed successfully."
}
```

Kaldırma işlemi sizin tarafınızdan kalıcıdır: kaldırılan bir üye, güncelleme uç noktası ile **yeniden etkinleştirilemez**; fikrinizi değiştirirseniz onları tekrar davet edin. E-posta adresleri de hesabınızın bildirim listesinden çıkarılır.

| Durum | Ne zaman |
|---|---|
| `400` | Hesap sahibini kaldırmaya çalıştınız. |
| `403` | Erişimleri sizinkinden daha geniş. |
| `404` | Böyle bir ekip üyesi yok. |

---

## Bir üyenin neleri görebileceğini sınırlama

[Ekleme](#add-a-team-member-directly), [güncelleme](#update-a-team-member) ve [davet](#send-an-invitation) işlemlerinde kabul edilen üç isteğe bağlı alan, bir kişinin hesabı ne kadar görebileceğine karar verir. Bunlar birikir: birden fazla alanda kısıtlanan bir üye, bunların hepsinden kısıtlanmış olur.

**`contact_scope`** — `all` (varsayılan: her kişi ve görüşme) veya `assigned` (yalnızca kendilerine atananlar). `assigned` ile birlikte, henüz kimsenin sahip olmadığı kişileri de görmelerini sağlamak için `"contact_scope_unassigned": true` ekleyin.

**`contact_scope_axes`** — onları belirli temsilciler, kanallar veya departmanlarla sınırlar:

| Alan | Tür | Açıklama |
|---|---|---|
| `agents` | string[] | Temsilci kimlikleri. Yalnızca bu temsilcilerden birine yönlendirilen sohbetleri görürler. Maks. 200. |
| `channels` | string[] | Kanal adları — `whatsapp`, `whatsapp_web`, `sms`, `instagram`, `instagram_private`, `messenger`, `facebook`, `chat_widget`, `telegram`, `line`, `viber`, `tiktok`, `imessage`, `email`, `linkedin`, `skool`, `custom`, `custom_channel`. Maks. 200. |
| `departments` | string[] | Departman kimlikleri (bkz. [Departmanlar](#departments)). Yalnızca bunlar altında dosyalanan müşteri adaylarını görürler. Maks. 200. |
| `include_unrouted` | boolean | `agents` ayarlandığında, hiçbir temsilcinin ilgilenmediği sohbetleri de gösterir. Varsayılan olarak kapalıdır. `agents` boş olduğunda yoksayılır. |
| `include_undepartmented` | boolean | `departments` ayarlandığında, hiçbir departmanda olmayan sohbetleri de gösterir. Varsayılan olarak kapalıdır. `departments` boş olduğunda yoksayılır. |

Temsilci ve departman kimlikleri kaydettiğinizde kontrol edilmez; mevcut olmayan bir kimlik hiçbir şeyle eşleşmez ve hata yerine boş bir gelen kutusu olarak görünür. Kanal adları **ise** kontrol edilir: tanınmayan bir kanal `400` ile reddedilir.


Bu üçünden hiçbiri hesap sahibi üzerinde ayarlanamaz; bu istek `400` ile reddedilir.

---

## Davetleri listele

`GET /team/invites`

Gönderdiğiniz davetler, en yeniden eskiye doğru sıralanır; böylece kimlerin henüz kabul etmediğini görebilirsiniz.

**Sorgu parametreleri**

| Parametre | Gerekli | Açıklama |
|---|---|---|
| `status` | Hayır | Yalnızca bu durumdaki davetleri döndürür — `pending`, `accepted`, `declined`, `cancelled` veya `expired`. |

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/team/invites?status=pending" \
  -H "Authorization: Bearer FIREBASE_ID_TOKEN"
```

**Yanıt**

```json
{
  "success": true,
  "invites": [
    {
      "id": "inv_abc123",
      "account_owner_uid": "owner_uid_123",
      "account_owner_display_name": "Acme Ltd",
      "invitee_email": "sam@example.com",
      "invitee_uid": null,
      "role": "editor",
      "permission_overrides": [],
      "status": "pending",
      "created_by": "owner_uid_123",
      "created_at": "2026-06-10T12:00:00.000Z",
      "expires_at": "2026-06-17T12:00:00.000Z",
      "responded_at": null
    }
  ]
}
```

Davet belirteci (token) asla döndürülmez; yalnızca gönderilen e-postanın içinde bulunur.

---

## Davet gönder

`POST /team/invites`

Ekibinize katılmaları için birine e-posta yoluyla davet gönderir. Bir ekip arkadaşı eklemenin olağan yolu budur: bağlantıya tıklarlar, kendi hesaplarıyla giriş yaparlar ve kabul ederler. Henüz bir <span data-t="appName">Your AI Connector</span> hesapları yoksa, onlar için bir hesap oluşturulur ve e-posta, parola belirleme sürecinde onlara rehberlik eder.

**İstek alanları**

| Alan | Gerekli | Açıklama |
|---|---|---|
| `email` | Evet | Davetin gönderileceği yer. |
| `role` | Evet | `admin`, `editor` veya `viewer`. |
| `permission_overrides` | Hayır | Kabul ettikleri anda uygulanan alan bazlı istisnalar. |
| `contact_scope` | Hayır | Kabul ettiklerinde uygulanır. |
| `contact_scope_unassigned` | Hayır | Kabul ettiklerinde uygulanır. |
| `contact_scope_axes` | Hayır | Kabul ettiklerinde uygulanır. |
| `sub_account_access` | Hayır | Yalnızca ajanslar için. Kabul ettiklerinde uygulanır. |

İzinleri önceden ayarlamak, daha sonra üyeyi düzenlemek zorunda kalmayacağınız anlamına gelir; kabul ettiklerinde her şey üyeliklerine kopyalanır.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/team/invites" \
  -H "Authorization: Bearer FIREBASE_ID_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "email": "sam@example.com", "role": "editor" }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/team/invites", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${idToken}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ email: "sam@example.com", role: "editor" }),
});
const { invite_id } = await res.json();
```

**Yanıt** — `201 Created`

```json
{
  "success": true,
  "invite_id": "inv_abc123",
  "message": "Team invite sent successfully."
}
```

**Planlanması gerekenler**

- **Davetlerin süresi 7 gün sonra dolar.** Süresi dolan bir davet yeniden gönderilebilir ve bu işlem yeni bir 7 günlük süre başlatır.
- **Bekleyen davetler bir koltuk işgal eder.** Doğrudan üye eklemenin aksine, buradaki koltuk kontrolü aktif üyeleri *artı* bekleyen davetleri sayar; bu nedenle tüm koltukları dolu olan bir hesapta, e-posta gönderilmeden önce işlem reddedilir.
- **Günlük 20 davet sınırı**, hem gönderme hem de yeniden gönderme işlemleri dahil olmak üzere hesap başına sayılır.

| Durum | Ne zaman |
|---|---|
| `400` | `email` eksik veya rol geçersiz. |
| `403` | Ekibi yönetme izniniz yok veya kendi yetkinizden daha yüksek bir erişim vermeye çalıştınız. |
| `409` | Bu e-posta adresi için bekleyen bir davet zaten var veya o kişi zaten ekibinizde. |
| `429` | Planınızdaki ekip koltukları dolu veya günlük 20 davet sınırına ulaştınız. `error` mesajı hangisinin olduğunu belirtir. |

---

## Daveti iptal et

`DELETE /team/invites/{inviteId}`

Bir daveti kabul edilmeden önce geri çeker. E-postadaki bağlantı çalışmayı durdurur.

**cURL**

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/team/invites/inv_abc123" \
  -H "Authorization: Bearer FIREBASE_ID_TOKEN"
```

**Yanıt**

```json
{
  "success": true,
  "message": "Team invite cancelled."
}
```

Hem `pending` hem de `expired` davetleri iptal edilebilir. Zaten kabul edilmiş, reddedilmiş veya iptal edilmiş bir davet `400` döndürür; size ait olmayan bir davet `403` döndürür; bilinmeyen bir kimlik ise `404` döndürür.

---

## Bir daveti yeniden gönder

`POST /team/invites/{inviteId}/resend`

Davet e-postasını tekrar gönderir — gözden kaçırıldığı veya spam'e düştüğü durumlar için. `pending` ve `expired` davetlerinde çalışır ve son kullanma süresini şu andan itibaren 7 gün sonrasına sıfırlar.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/team/invites/inv_abc123/resend" \
  -H "Authorization: Bearer FIREBASE_ID_TOKEN"
```

**Yanıt**

```json
{
  "success": true,
  "message": "Team invite resent successfully."
}
```

Yeni e-posta yeni bir bağlantı içerir ve **eski bağlantı da çalışmaya devam eder**, böylece ilk e-postayı daha sonra bulan bir kişi mağdur olmaz. Yeniden gönderme işlemi, gönderim için geçerli olan günlük 20 adetlik sınırla aynı sınıra tabidir ve *süresi dolmuş* bir daveti canlandırmak koltuk sayınızı tekrar kontrol eder — dolu bir plan `429` ile reddedilir.

---

## Bir daveti kabul et

`POST /team/invites/accept`

Davet e-postasındaki belirteç (token) ile bir daveti kabul eder ve oturum açmış kişiyi o hesabın ekibine dahil eder.

> **Bu, kendi kimliğinizle gerçekleştirdiğiniz bir işlemdir.** Kendi adınızla oturum açın — başkasının hesabında çalışırken bu işlem kasıtlı olarak `403` ile reddedilir.

**İstek alanları**

| Alan | Gerekli | Açıklama |
|---|---|---|
| `invite_token` | Evet | Davet e-postası bağlantısındaki belirteç (token). |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/team/invites/accept" \
  -H "Authorization: Bearer FIREBASE_ID_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "invite_token": "1f4c…" }'
```

**Yanıt**

```json
{
  "success": true,
  "team_member_id": "owner_uid_123_uid_sam",
  "account_owner_uid": "owner_uid_123",
  "message": "Team invite accepted successfully."
}
```

| Durum | Ne zaman |
|---|---|
| `400` | `invite_token` eksikse veya davet kendi hesabınız içinse. |
| `403` | Oturum başka bir hesap içinde çalışıyorsa veya davet, oturum açtığınız e-posta adresinden farklı bir adrese gönderilmişse. |
| `404` | Davet mevcut değil veya zaten kullanılmış. |
| `429` | Davet ile kabulünüz arasında hesabın koltukları dolmuşsa. |
| `504` | Davetin süresi dolmuşsa. Gönderenden tekrar göndermesini isteyin. |

---

## Bir daveti reddet

`POST /team/invites/decline`

E-postadaki belirteç (token) ile bir daveti reddeder. Kabul etme işleminde olduğu gibi, bu da kendi kimliğinizle gerçekleştirdiğiniz bir işlemdir ve başka bir hesapta çalışırken reddedilir.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/team/invites/decline" \
  -H "Authorization: Bearer FIREBASE_ID_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "invite_token": "1f4c…" }'
```

**Yanıt**

```json
{
  "success": true,
  "message": "Team invite declined."
}
```

---

## Departmanlar

Bir **departman**, ekibinizin adlandırılmış bir grubudur — Satış, Müşteri desteği, İK gibi. Bir potansiyel müşteriye bir sahip ekip atar, kendi başına yeni konuşmaları üstlenebilir ve bir üyenin neleri görebileceğini sınırlamak için kullanılabilir.

> **Bu dört uç nokta bir API anahtarı gerektirir.** Bu sayfanın geri kalanının aksine, API'deki diğer tüm uç noktalar gibi kimlik doğrulaması yaparlar (bkz. [Kimlik Doğrulama](authentication.md)). Oturum açmış bir oturum da işe yarar: okuma işlemi `view` adresinde `contacts` gerektirir; oluşturma, değiştirme veya silme işlemleri ise `edit` adresinde `team_management` gerektirir.

**Departman nesnesi**

| Alan | Tür | Açıklama |
|---|---|---|
| `id` | string | Departmanın kimliği. Bunu `contact_scope_axes.departments` içinde ve aşağıdaki yollarda kullanın. |
| `name` | string | Ekibin adı. 60 karaktere kadar, hesapta benzersiz olmalıdır. |
| `color` | string \| null | `#rrggbb` veya `null` olarak vurgu rengi. |
| `member_uids` | string[] | Bu departmandaki ekip üyeleri. Hesap sahibini içerebilir. |
| `auto_assign_enabled` | boolean | Bu departman altında dosyalanan bir potansiyel müşterinin aynı zamanda departmandaki birine atanıp atanmayacağı. `false`, departmanın paylaşılan bir kuyruktan çalıştığı anlamına gelir. |
| `routing_agents` | string[] | Bu yapay zeka temsilcileri tarafından ele alınan yeni konuşmalar otomatik olarak bu departman altında dosyalanır. Boş olması, temsilci kuralı olmadığı anlamına gelir. |
| `routing_channels` | string[] | Bu kanallardaki yeni konuşmalar otomatik olarak burada dosyalanır. Boş olması, kanal kuralı olmadığı anlamına gelir. |
| `created_by` | string \| null | Onu kimin oluşturduğu. |

Hem `routing_agents` hem de `routing_channels` ayarlandığında, bir konuşmanın burada dosyalanması için **her ikisiyle de** eşleşmesi gerekir — bir ekibe "destek temsilcisi, ancak sadece WhatsApp'ta" kuralını bu şekilde verirsiniz.

Bir hesapta en fazla **50** departman bulunabilir.

### Departmanları listele

`GET /team/departments`

```bash
curl "https://api.youraiconnector.com/v1/team/departments?apiKey=YOUR_API_KEY"
```

**Yanıt**

```json
{
  "success": true,
  "departments": [
    {
      "id": "dep_abc123",
      "name": "Sales",
      "color": "#2f6fed",
      "member_uids": ["uid_alice", "uid_bob"],
      "auto_assign_enabled": true,
      "routing_agents": [],
      "routing_channels": ["whatsapp"],
      "created_by": "owner_uid_123"
    }
  ]
}
```

### Departman oluştur

`POST /team/departments`

**İstek alanları**

| Alan | Zorunlu | Açıklama |
|---|---|---|
| `name` | Evet | 60 karaktere kadar. Mevcut bir departmanla eşleşmemelidir. |
| `color` | Hayır | `#rrggbb` onaltılık (hex) veya `null`. |
| `member_uids` | Hayır | Kimin üzerinde olduğu. Her UID, hesap sahibi veya **aktif** bir ekip üyesi olmalıdır. |
| `auto_assign_enabled` | Hayır | Varsayılan olarak `true`. |
| `routing_agents` | Hayır | Yeni sohbetlerin buraya düştüğü Temsilci kimlikleri. |
| `routing_channels` | Hayır | Yeni sohbetlerin buraya düştüğü kanal adları — `contact_scope_axes.channels` ile aynı kelime dağarcığı. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/team/departments?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Sales",
    "color": "#2f6fed",
    "member_uids": ["uid_alice", "uid_bob"],
    "routing_channels": ["whatsapp"]
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/team/departments", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    name: "Sales",
    color: "#2f6fed",
    member_uids: ["uid_alice", "uid_bob"],
    routing_channels: ["whatsapp"],
  }),
});
const { department } = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/team/departments",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "name": "Sales",
        "color": "#2f6fed",
        "member_uids": ["uid_alice", "uid_bob"],
        "routing_channels": ["whatsapp"],
    },
)
department = res.json()["department"]
```

**Yanıt** — `201 Created`

```json
{
  "success": true,
  "department": {
    "id": "dep_abc123",
    "name": "Sales",
    "color": "#2f6fed",
    "member_uids": ["uid_alice", "uid_bob"],
    "auto_assign_enabled": true,
    "routing_agents": [],
    "routing_channels": ["whatsapp"],
    "created_by": "owner_uid_123"
  }
}
```

| Durum | Ne zaman |
|---|---|
| `400` | `name` eksik veya çok uzunsa, `color` `#rrggbb` değilse, bir kanal adı tanınmıyorsa, listelenen bir UID bu ekibin aktif bir üyesi değilse veya zaten 50 departmanınız varsa. |
| `409` | Bu ada sahip bir departman zaten mevcut. |

### Departmanı güncelle

`PATCH /team/departments/{departmentId}`

Bir departmanı değiştirir. Yalnızca gönderdiğiniz alanlar değiştirilir.

```bash
curl -X PATCH "https://api.youraiconnector.com/v1/team/departments/dep_abc123?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "member_uids": ["uid_alice"], "auto_assign_enabled": false }'
```

**Yanıt**

```json
{
  "success": true,
  "department": {
    "id": "dep_abc123",
    "name": "Sales",
    "color": "#2f6fed",
    "member_uids": ["uid_alice"],
    "auto_assign_enabled": false,
    "routing_agents": [],
    "routing_channels": ["whatsapp"],
    "created_by": "owner_uid_123"
  }
}
```

Tanınmayan alanlar gönderilmesi `400` döndürür; bilinmeyen bir departman `404` döndürür; başka bir departmanla çakışan bir isim `409` döndürür.

### Bir departmanı silme

`DELETE /team/departments/{departmentId}`

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/team/departments/dep_abc123?apiKey=YOUR_API_KEY"
```

**Yanıt**

```json
{
  "success": true,
  "deleted": "dep_abc123"
}
```

> **Birinin erişiminin kısıtlı olduğu bir departmanı silme işlemi reddedilir.** `400` yanıtı, görünürlükleri bu departmanla sınırlandırılmış üyelerin isimlerini verir, böylece önce onların kapsamını yeniden ayarlayabilirsiniz. Bu kasıtlıdır: onları sessizce kısıtlamadan çıkarmak, hiçbir uyarı olmaksızın tüm müşteri tabanınızı görmelerine neden olur.

Silinen bir departman altında dosyalanan kişiler yeniden yazılmaz; sadece bir departman göstermeyi bırakırlar ve onları bir sonraki dosyalayışınızda bu durum geçerli olur.

---

## Kendi izinlerinizi kontrol edin

`GET /team/permissions`

Oturum açmış kişinin şu anda üzerinde çalıştığı hesapta neler yapabileceğini döndürür. Bir üyenin kullanamayacağı düğmeleri, hatayla karşılaşmalarını beklemek yerine gizlemek için bunu kullanın.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/team/permissions" \
  -H "Authorization: Bearer FIREBASE_ID_TOKEN"
```

**Yanıt — hesap sahibi**

```json
{
  "success": true,
  "role": "owner",
  "is_team_mode": false,
  "permissions": {
    "campaigns": "full",
    "contacts": "full",
    "messages": "full",
    "appointments": "full",
    "settings": "full",
    "billing": "full",
    "team_management": "full",
    "analytics": "full",
    "phone_numbers": "full",
    "integrations": "full",
    "faqs": "full",
    "daily_summaries": "full"
  }
}
```

**Yanıt — bir hesap içinde çalışan ekip üyesi**

```json
{
  "success": true,
  "role": "editor",
  "is_team_mode": true,
  "permissions": { "campaigns": "edit", "billing": "none", "…": "…" },
  "member": {
    "uid": "uid_sam",
    "email": "sam@example.com",
    "display_name": "Sam Rivera",
    "account_owner_uid": "owner_uid_123"
  }
}
```

Oturum açmış kişi hesap sahibi olduğunda `role` değeri `owner` olur; aksi takdirde bu, ekip rolüdür. `member` yalnızca ekip modunda mevcuttur ve üyelikleri olduğunda `contact_scope`, `contact_scope_unassigned` ve `contact_scope_axes` değerlerini taşır.

---

## Oturum belirteçleri

Beş uç nokta, hesaplar arasında geçiş yapmak için tek kullanımlık bir oturum açma belirteci oluşturur. Hepsi aynı şekilde yanıt verir:

```json
{
  "success": true,
  "customToken": "eyJhbGciOi…"
}
```

Belirteç, Firebase istemci SDK'sı ile bir oturum için değiştirilir. **Bu bir API anahtarı değildir ve bu şekilde gönderilemez**, bu nedenle bu uç noktalar yalnızca birinci taraf bir uygulama içinde kullanışlıdır.

| Uç Nokta | Ne işe yarar | Gövde |
|---|---|---|
| `POST /team/tokens/team-member` | Bir ekip üyesinin ait olduğu bir hesap içinde çalışmaya başlamasını sağlar. | `account_owner_uid` (gerekli) |
| `POST /team/tokens/return-from-team` | Onları kendi hesaplarına geri döndürür. | — |
| `POST /team/tokens/assist` | <span data-t="appName">Your AI Connector</span> personelinin yardım etmek için bir müşterinin hesabını açmasını sağlar. Sadece personel içindir. | `customerUid` |
| `POST /team/tokens/return-to-admin` | Bir yardım oturumunu sonlandırır ve personeli kendi hesabına döndürür. | — |
| `POST /team/tokens/agency-assist` | Bir ajansın kendi müşteri alt hesaplarından birini açmasını veya belirtilmediğinde ajans hesabına dönmesini sağlar. | `subAccountUid` (isteğe bağlı) |

Oturumun buna yetkisi olmadığında her biri `403` ile reddeder: o hesaba üye olunmaması, personel olunmaması, o alt hesabın ajansınızda bulunmaması veya size verilmemiş olması ya da oturumun uç noktanın gerektirdiği modda olmaması durumları.

---

## Bir platform rolü atayın

`POST /team/users/{targetUid}/role`

Bir kullanıcının **platform** rolünü ayarlar — `User`, `Dev`, `Support` veya `Agency`. Bu, ekip üyeliği değildir: birinin ne tür bir <span data-t="appName">Your AI Connector</span> hesabına sahip olduğudur.

Bu uç nokta <span data-t="appName">Your AI Connector</span> personeli ile sınırlıdır ve son kalan `Dev` yetkisi düşürülemez. Eksiksiz olması için listelenmiştir; kendi ekibinizi yönetmenin bir parçası değildir.

```json
{
  "success": true,
  "targetUid": "uid_sam",
  "role": "Agency",
  "claimUpdated": true
}
```

| Durum | Ne zaman |
|---|---|
| `400` | `role` eksikse veya dört rolden biri değilse ya da bu işlem son `Dev` rolünü kaldıracaksa. |
| `403` | Personel değilseniz veya oturum başka bir hesap içinde çalışıyorsa. |
| `404` | Böyle bir kullanıcı yok. |

---

## Ekip API hataları

Ekip uç noktaları, HTTP durumuyla birlikte her zaman `error_code` içeren standart hata zarfını döndürür:

```json
{
  "success": false,
  "error_code": 403,
  "error": "Cannot grant \"full\" access to \"billing\" — exceeds your own permissions."
}
```

| Durum | Bir ekip uç noktasında ne zaman gerçekleşir |
|---|---|
| `400` | Gerekli bir alan eksik veya geçersizse ya da bu durumda eyleme izin verilmiyorsa (kaldırılmış bir üyeyi yeniden etkinleştirme, sahibini askıya alma, birinin sınırlı olduğu bir departmanı silme). |
| `401` | Oturum açmış bir kişi gerektiren bir uç noktaya API anahtarı gönderdiniz — bkz. [Kimlik Doğrulama](#authentication-these-endpoints-need-a-signed-in-person). |
| `403` | `team_management` izniniz yoksa, değişiklik kendi erişim yetkinizi aşıyorsa veya başka bir hesap içinde çalışırken eylem reddediliyorsa. |
| `404` | Böyle bir üye, davet, departman veya kullanıcı yok. |
| `409` | Zaten bir ekip üyesi, bekleyen bir davet zaten mevcut veya o isimde bir departman mevcut. |
| `429` | Ekip koltukları dolu, günlük 20 davet limiti doldu veya API hız sınırına ulaştınız. |
| `504` | Kabul etmeye çalıştığınız davetin süresi dolmuş. |

Her uç noktanın döndürebileceği paylaşılan kodlar — `429` (hız sınırı) ve `500` — [Hatalar ve Sayfalandırma](errors-and-pagination.md) bölümünde yeniden deneme rehberliği ile listelenmiştir.

---

## İlgili

- [Ekip Yönetimi](../settings/team-management.md) — kontrol panelindeki aynı özellikler, ekran görüntüleriyle birlikte.
- [Kimlik Doğrulama](authentication.md) — API anahtarı yerine Firebase kimlik belirteci gönderme.
- [Kişiler API'si](contacts.md) — bir üyenin görünürlük sınırlarının uygulandığı kişiler.

