
# Kişiler API'si

Bir kişi, mesajlaştığınız tek bir bireydir; adı, telefon numarası, e-postası, kanalı, etiketleri, özel alanları ve dahil olduğu listeler ve kampanyalar bu kapsamdadır. Kişiler API'si, kontrol panelini kullanmadan kişileri oluşturmanıza, aramanıza, güncellemenize, etiketlemenize, toplu olarak içe aktarmanıza ve silmenize olanak tanır.

Bu sayfadaki tüm yollar, temel URL'ye göre belirlenmiştir:

```
https://api.youraiconnector.com/v1
```

Yani `/contacts` ifadesi `https://api.youraiconnector.com/v1/contacts` anlamına gelir.

> **API'de yeni misiniz?** Öncelikle [API Erişimi](../integrations/api-access.md) bölümünü okuyun; bu bölüm API anahtarınızı nasıl oluşturacağınızı, üç kimlik doğrulama yöntemini, hız sınırlarını ve hata biçimini kapsar. Bu sayfadaki her şey, halihazırda çalışan bir API anahtarınız olduğunu varsayar.

---

## Kişi kimlikleri (ID) hakkında

Her kişinin benzersiz bir kimliği (ID) vardır. Bir kişiyi **oluşturduğunuzda** (bkz. `data.contactId`) aldığınız kimlik, diğer her yerde (o kişiyi getirmek, güncellemek, etiketlemek, mesaj göndermek veya silmek için) kullandığınız kimliğin aynısıdır. Bir kez kaydedin ve tekrar kullanın.

Kimliğini almak için bir kişi oluşturmak zorunda değilsiniz. Ayrıca telefon numarası veya e-posta ile arama yapabilir (bkz. [Bir kişiyi getir](#get-a-contact-by-phone-or-email)) veya tüm kişilerinizi sayfalayarak listeleyebilirsiniz (bkz. [Kişileri listele](#list-contacts)). Bunların her biri aynı kimliği döndürür.

---

## Bir kişi oluştur

`POST /contacts`

Hesabınıza yeni bir kişi ekler. **Ülke koduyla birlikte bir telefon numarası zorunludur**; sadece e-posta yeterli değildir. Diğer her şey isteğe bağlıdır.

İsteğe bağlı olarak, yeni kişiyi `listId` (tek bir liste) veya `listIds` (bir dizi) kullanarak doğrudan bir veya daha fazla listeye ekleyebilirsiniz. Her ikisi de gönderilirse, `listIds` önceliklidir.

Aşağıdaki **Kişi oluşturma** alanı tablosunda listelenen standart oluşturma alanlarından biri olmayan gönderdiğiniz her alan (`phoneNumber`, `firstName`, `lastName`, `email`, `channel`, `is_bot_active`, `is_private`, `lead_profile`, `listId`, `listIds`, `custom_fields`) otomatik olarak **özel alan** olarak kaydedilir; bu sayede Make veya Zapier gibi bir araçtan gelen düz bir yük, iç içe yerleştirme gerektirmeden çalışır. Ayrıca açık bir `custom_fields` nesnesi de iletebilirsiniz.

| Alan | Zorunlu | Açıklama |
|---|---|---|
| `phoneNumber` | Evet | Kişinin ülke koduyla birlikte telefon numarası (örneğin `+15551234567`). |
| `firstName` | Hayır | Ad. |
| `lastName` | Hayır | Soyad. |
| `email` | Hayır | E-posta adresi. |
| `channel` | Hayır | Mesajlaşma kanalı. `whatsapp`, `sms`, `whatsapp_web` değerlerinden biri. Varsayılan değer `whatsapp`'dur. |
| `is_bot_active` | Hayır | Yapay zeka asistanının bu kişiye yanıt verip vermeyeceği. Varsayılan değer `true`'dir. |
| `is_private` | Hayır | Kişiyi özel olarak işaretleyin. `true` olduğunda, yapay zeka asistanı onlar için kapatılır. Varsayılan değer `false`'tür. |
| `lead_profile` | Hayır | Aday hakkında serbest metin notları. |
| `listId` | Hayır | Kişinin ekleneceği tek bir liste kimliği. |
| `listIds` | Hayır | Kişinin ekleneceği liste kimliklerinden oluşan bir dizi (`listId` değerine göre önceliklidir). |
| `custom_fields` | Hayır | Kendi anahtar/değer alanlarınızdan oluşan bir nesne. Bunları en üst düzey anahtarlar olarak da iletebilirsiniz. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/contacts?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumber": "+15551234567",
    "firstName": "Jane",
    "lastName": "Smith",
    "email": "jane@example.com",
    "is_bot_active": true,
    "listIds": ["list123", "list456"]
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/contacts", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    phoneNumber: "+15551234567",
    firstName: "Jane",
    lastName: "Smith",
    email: "jane@example.com",
    is_bot_active: true,
    listIds: ["list123", "list456"],
  }),
});
const data = await res.json();
console.log(data.data.contactId);
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "phoneNumber": "+15551234567",
        "firstName": "Jane",
        "lastName": "Smith",
        "email": "jane@example.com",
        "is_bot_active": True,
        "listIds": ["list123", "list456"],
    },
)
print(res.json()["data"]["contactId"])
```

**Yanıt**

```json
{
  "success": true,
  "data": {
    "message": "Successfully created new contact",
    "contactId": "contact_abc123",
    "listsAdded": ["list123", "list456"]
  }
}
```

Yeni kişinin kimliği `data.contactId` adresindedir. Eklendiği listeler `data.listsAdded` içinde geri yansıtılır.

> **Yinelenenler oluşturulmaz.** Aynı telefon numarasına sahip bir kişi zaten mevcutsa, oluşturma çağrısı onu **oluşturmaz** veya döndürmez. Yanıt, HTTP durumu `200` ve gövdesinde `409` değerine sahip bir `error_code` ile döner, bu nedenle HTTP durumu yerine `error_code` değerine göre dallanma yapın:
>
> ```json
> { "success": false, "error_code": 409, "error": "A contact with this phone number already exists for the current user." }
> ```
>
> `error_code` değeri `409` olan bir işlemden sonra mevcut bir kişiyle çalışmak için, [Telefon veya e-posta ile kişi alma](#get-a-contact-by-phone-or-email) yöntemini kullanarak onu arayın — `GET /contacts?phoneNumber=...` — ve döndürdüğü kimliği (ID) yeniden kullanın.

> **Eşdeğer WhatsApp yazımları aynı numara olarak sayılır.** Bazı ülkelerde aynı mobil hat için iki geçerli yazım biçimi bulunur ve WhatsApp bunlardan herhangi birini bildirebilir: Meksika (`+52…` ve eski `+521…`), Brezilya (dokuzuncu hane olsun veya olmasın) ve Arjantin (`+54`'ten sonra `9` olsun veya olmasın). Oluşturma sırasındaki kopya denetimi ve `GET /contacts?phoneNumber=`, her iki yazım biçimiyle de eşleşir; bu sayede hangi biçimi gönderirseniz gönderin mevcut kişiyi geri alırsınız. Kişi üzerinde kayıtlı olan `phone_number` hiçbir zaman yeniden yazılmaz.

---

## Telefon veya e-posta ile kişi getirme

`GET /contacts?phoneNumber=...` veya `GET /contacts?email=...`

Tek bir kişiyi arar ve `{ id, name }` çiftlerine çözümlenmiş listeleri, etiketleri ve kampanyaları ile son mesajlaşmayı içeren tam, zenginleştirilmiş kişi nesnesini döndürür.

**Ya** `phoneNumber` (uluslararası formatta) **ya da** `email` gönderin. İkisini de göndermezseniz, bu uç nokta bunun yerine [Kişileri listele](#list-contacts) moduna geçer.

**cURL**

```bash
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts?phoneNumber=%2B15551234567&apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const phone = encodeURIComponent("+15551234567");
const res = await fetch(`https://api.youraiconnector.com/v1/contacts?phoneNumber=${phone}`, {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.contact);
```

**Python**

```python
import requests

res = requests.get(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"phoneNumber": "+15551234567"},
)
print(res.json()["contact"])
```

**Yanıt**

```json
{
  "success": true,
  "contactId": "contact_abc123",
  "contact": {
    "id": "contact_abc123",
    "firstName": "Jane",
    "lastName": "Smith",
    "email": "jane@example.com",
    "phoneNumber": "+15551234567",
    "channel": "whatsapp",
    "isBotActive": true,
    "isPrivate": false,
    "doNotDisturb": false,
    "lead_profile": null,
    "avatarUrl": "https://example.com/photo.jpg",
    "customFields": {},
    "lists": [{ "id": "list123", "name": "VIP customers" }],
    "tags": [{ "id": "tagHotLead", "name": "Hot lead" }],
    "campaigns": [{ "id": "campaign789", "name": "Spring promo" }],
    "currentCampaign": { "id": "campaign789", "name": "Spring promo" },
    "lastMessage": {
      "direction": "inbound",
      "body": "Sounds good, thanks!",
      "status": "received",
      "timestamp": "2026-06-09T10:21:00.000Z"
    }
  }
}
```

Kişi kimliği hem en üst düzeyde (`contactId`) hem de nesnenin içinde (`contact.id`) döndürülür. Eşleşme olmazsa, `{ "success": false, "message": "Contact not found" }` içeren bir `404` alırsınız.

> **`avatarUrl`**, kişiye mesaj attığında WhatsApp veya Meta'dan alınan profil fotoğrafıdır. Salt okunurdur: bunu ayarlayamazsınız ve fotoğrafı olmayan veya fotoğraf paylaşmayan bir kanaldan size ulaşan kişiler için `null` değerindedir. Bu fotoğraf bağlantılarından bazıları süreli olup otomatik olarak yenilendiğinden, bağlantıyı saklamak yerine geçici olarak değerlendirin. (Aşağıdaki liste uç noktasında aynı değer `avatar_url` olarak adlandırılır.)

> **URL'lerdeki telefon numaraları.** Sorgu dizesindeki bir `+` işareti `%2B` olarak URL kodlanmalıdır, aksi takdirde boşluk olarak okunur. Yukarıdaki örnekler bunu sizin için yapar.

---

## Kimlik (ID) ile kişi getirme

`GET /contacts/{contactId}`

Bir kişinin kimliğine (ID) zaten sahipseniz, onu doğrudan getirebilirsiniz. Yanıt biçimi yukarıdaki arama ile aynıdır.

**cURL**

```bash
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.contact);
```

**Python**

```python
import requests

res = requests.get(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
print(res.json()["contact"])
```

Hesabınızda bulunmayan bir kişi kimliği, `404` döndürür.

---

## İletişim istatistiklerini al

`GET /contacts/{contactId}/stats`

Bir kişi için toplu mesaj istatistiklerini döndürür: toplamlar, yapay zeka ve insan yanıtları, harcanan krediler ve ilk/son mesaj zaman damgaları.

**cURL**

```bash
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/stats?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/stats", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.totalMessages, data.creditsUsed);
```

**Python**

```python
import requests

res = requests.get(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/stats",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
print(data["totalMessages"], data["creditsUsed"])
```

**Yanıt**

```json
{
  "success": true,
  "totalMessages": 48,
  "sent": 21,
  "received": 27,
  "aiReplies": 18,
  "humanReplies": 3,
  "creditsUsed": 34,
  "botMessageCount": 18,
  "firstMessageAt": "2026-05-01T09:00:00.000Z",
  "lastMessageAt": "2026-06-09T10:21:00.000Z"
}
```

`botMessageCount`, uygulama içindeki "sıfırla" düğmesinin bir kişi için sıfırladığı yapay zeka mesaj sayacıyla aynıdır. `creditsUsed`, sadece bu yanıtın sayıları değil, bu kişi için devam eden toplam kredi miktarıdır. Hesabınızda bulunmayan bir kişi kimliği `404` döndürür.

---

## Kişileri listeleme

`GET /contacts`

Tüm kişilerinizi en yeniden başlayarak sayfalamak için `GET /contacts` öğesini **ne** `phoneNumber` **ne de** `email` olmadan çağırın. Her sayfa, kompakt kişi özetleri (listeler, etiketler ve kampanyalar tam nesneler yerine kimlik dizileri olarak döner) ve bir `next_cursor` döndürür.

| Sorgu parametresi | Açıklama |
|---|---|
| `limit` | Sayfa boyutu. Varsayılan 50, maksimum 100'dür. |
| `cursor` | Önceki sayfadan gelen `next_cursor` değeri. İlk sayfada atlayın. |
| `listId` | İsteğe bağlı. Yalnızca bu listeye ait kişileri döndürür. |

Her sayfayı gezmek için: ilk çağrıyı imleç (cursor) olmadan yapın, ardından dönen `next_cursor` değerini `cursor` olarak iletmeye devam edin. **`next_cursor` değeri `null` olduğunda durun** — bu, başka sonuç kalmadığı anlamına gelir.

**cURL**

```bash
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts?limit=50&apiKey=YOUR_API_KEY"

# next page:
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts?limit=50&cursor=contact_abc123&apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
async function listAllContacts() {
  const all = [];
  let cursor = null;
  do {
    const url = new URL("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts");
    url.searchParams.set("limit", "100");
    if (cursor) url.searchParams.set("cursor", cursor);
    const res = await fetch(url, { headers: { "X-API-Key": "YOUR_API_KEY" } });
    const data = await res.json();
    all.push(...data.contacts);
    cursor = data.next_cursor;
  } while (cursor);
  return all;
}
```

**Python**

```python
import requests

def list_all_contacts():
    all_contacts = []
    cursor = None
    while True:
        params = {"limit": 100}
        if cursor:
            params["cursor"] = cursor
        res = requests.get(
            "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts",
            headers={"X-API-Key": "YOUR_API_KEY"},
            params=params,
        )
        data = res.json()
        all_contacts.extend(data["contacts"])
        cursor = data["next_cursor"]
        if not cursor:
            break
    return all_contacts
```

**Yanıt**

```json
{
  "success": true,
  "contacts": [
    {
      "id": "contact_abc123",
      "first_name": "Jane",
      "last_name": "Smith",
      "email": "jane@example.com",
      "phone_number": "+15551234567",
      "channel": "whatsapp",
      "is_bot_active": true,
      "is_private": false,
      "do_not_disturb": false,
      "avatar_url": "https://example.com/photo.jpg",
      "custom_fields": {},
      "created_at": "2026-06-01T09:00:00.000Z",
      "list_ids": ["list123"],
      "tag_ids": ["tagHotLead"],
      "campaign_ids": ["campaign789"],
      "current_campaign_id": "campaign789"
    }
  ],
  "next_cursor": "contact_abc123"
}
```

::: note
**Not:** Hesabınızda bulunmayan bir `listId` ile filtreleme yapmak `404` döndürür. Geçersiz bir `cursor` ise `400` döndürür.
:::


---

## Kişi sayısını al

`GET /contacts/count`

Filtreyle eşleşen kaç kişi olduğunu, kanal bazlı dağılımıyla birlikte, sayfalandırma yapmadan döndürür. Bu uç nokta; kontrol paneli kutucukları, otomasyonlar veya Champ'e soru sormak gibi "kaç tane" sorusunun sorulduğu her durum için doğru tercihtir. Tüm filtreler isteğe bağlıdır ve birden fazlasını birleştirmek sayıyı daraltır (bir kişinin gönderdiğiniz her bir filtreyle eşleşmesi gerekir).

| Sorgu parametresi | Açıklama |
|---|---|
| `agentId` | Yalnızca bu yapay zeka temsilcisine atanmış kişiler. Atanmış temsilcisi olmayan kişiler için (bunlar kanalın varsayılan temsilcisi tarafından yanıtlanır) `none` değerini gönderin. |
| `channel` | Yalnızca bu kanaldaki kişiler, örneğin `whatsapp`, `messenger`, `instagram`, `sms`, `email`, `chat_widget`. |
| `tag` | Yalnızca bu etiketi taşıyan kişiler, etiket **adı** ile (büyük/küçük harf duyarlı değildir). Sahip olmadığınız bir etiket adı `404` döndürür. |
| `listId` | Yalnızca bu listedeki kişiler. |
| `botActive` | `true` veya `false` — yalnızca yapay zeka asistanı açık veya kapalı olan kişiler. |
| `status` | Yalnızca bu duruma sahip kişiler, örneğin `Lead`. |
| `rules` | Akıllı liste ile aynı yapıda URL kodlu bir JSON kuralları nesnesi (aşağıdaki [The `smart_rules` shape](#the-smart_rules-shape) bölümüne bakın). Diğer filtrelerle birleştirilemez. |

Hiç filtre göndermezseniz, hesabınızdaki toplam kişi sayısını alırsınız.

**cURL**

```bash
# everything
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/count?apiKey=YOUR_API_KEY"

# only the contacts one agent handles on Messenger
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/count?agentId=agent_xyz789&channel=messenger&apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const url = new URL("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/count");
url.searchParams.set("agentId", "agent_xyz789");
url.searchParams.set("channel", "messenger");

const res = await fetch(url, { headers: { "X-API-Key": "YOUR_API_KEY" } });
const data = await res.json();
console.log(data.total);
```

**Python**

```python
import requests

res = requests.get(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/count",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"agentId": "agent_xyz789", "channel": "messenger"},
)
data = res.json()
print(data["total"])
```

**Yanıt**

```json
{
  "success": true,
  "total": 3423,
  "by_channel": { "messenger": 2744, "instagram": 667, "none": 12 },
  "filters": { "agentId": "agent_xyz789" }
}
```

`by_channel`, aynı toplamı kanal bazında böler; hiçbir kanalda olmayan kişiler `none` altında sayılır. `filters`, uygulanan filtreleri geri yansıtır, böylece çağrının istediğiniz işlemi yapıp yapmadığını kontrol edebilirsiniz.

::: note
**Not:** `rules` değerini başka bir filtreyle veya geçerli bir JSON olmayan bir `rules` değeriyle birlikte göndermek `400` döndürür. Hesabınızda bulunmayan bir etiket adı veya liste kimliği `404` döndürür.
:::


---

## Bir kişiyi güncelle

`PUT /contacts/{contactId}`

Mevcut bir kişiyi günceller. Yalnızca dahil ettiğiniz alanlar değiştirilir; dokunmak istemediğiniz hiçbir şeyi göndermeyin. En az bir alan göndermelisiniz, aksi takdirde bir `400` ("Güncellenecek alan yok") alırsınız.

| Alan | Açıklama |
|---|---|
| `firstName` | Ad. |
| `lastName` | Soyadı. |
| `email` | E-posta adresi. |
| `is_bot_active` | Yapay zeka asistanının bu kişiye yanıt verip vermeyeceği. |
| `is_private` | Gizli olarak işaretle. Bunu `true` olarak ayarlamak, yapay zeka asistanını da kapatır. |
| `do_not_disturb` | Bu kişiye yönelik otomatik erişimi duraklatın. Ayrıca yapay zekanın yanıt vermesini de durdurur. |
| `follow_ups_disabled` | Yapay zeka gönderdikleri mesajlara yanıt vermeye devam ederken, bu kişi için tüm otomatik takip işlemlerini (hızlı, döngüsel ve soğuk müşteri adayı) durdurun. Birisi satın alma işlemi yaptığında kullanışlıdır. Siz tekrar `false` olarak ayarlayana kadar kapalı kalır. |
| `lead_profile` | Serbest metin müşteri adayı notları. |
| `custom_fields` | Özel alanlardan oluşan bir nesne. **Anahtar bazında birleştirilir** — yalnızca gönderdiğiniz anahtarlar yazılır, mevcut özel alanların geri kalanı korunur. Ayrıca en üst düzeyde özel alan anahtarları da iletebilirsiniz. |

**cURL**

```bash
curl -X PUT "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "firstName": "Jane", "do_not_disturb": true }'
```

**JavaScript**

```javascript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123", {
  method: "PUT",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ firstName: "Jane", do_not_disturb: true }),
});
const data = await res.json();
console.log(data.message);
```

**Python**

```python
import requests

res = requests.put(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"firstName": "Jane", "do_not_disturb": True},
)
print(res.json()["message"])
```

**Yanıt**

```json
{
  "success": true,
  "message": "Contact updated successfully"
}
```

> **Özel alanlar değiştirilmez, birleştirilir.** `{ "custom_fields": { "tier": "gold" } }` göndermek yalnızca `tier` değerini ayarlar; kişideki diğer tüm özel alanlar tam olarak oldukları gibi kalır. Bir özel alanı tüm kişiler genelinde tamamen kaldırmak için [Özel alanı sil](#delete-a-custom-field) özelliğini kullanın.

---

## Etiket ekle veya kaldır

`POST /contacts/{contactId}/tags`

Tek bir çağrıda tek bir kişiye etiket ekler ve/veya kaldırır. Etiket **ID**'lerini `addTagIds` ve `removeTagIds` içinde iletin. İkisinden en az biri boş olmamalıdır.

Etiketler hesabınızda zaten mevcut olmalıdır; bunları önce [etiketler uç noktası](reference.md) aracılığıyla oluşturun. Kişi veya referans verilen herhangi bir etiket mevcut değilse, bir `404` alırsınız.

| Alan | Açıklama |
|---|---|
| `addTagIds` | Kişiye eklenecek etiket kimliklerinden (ID) oluşan dizi. |
| `removeTagIds` | Kişiden kaldırılacak etiket kimliklerinden (ID) oluşan dizi. |

**cURL**

```bash
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/tags?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "addTagIds": ["tagHotLead"], "removeTagIds": ["tagColdLead"] }'
```

**JavaScript**

```javascript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/tags", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    addTagIds: ["tagHotLead"],
    removeTagIds: ["tagColdLead"],
  }),
});
const data = await res.json();
console.log(data.added, data.removed);
```

**Python**

```python
import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/tags",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"addTagIds": ["tagHotLead"], "removeTagIds": ["tagColdLead"]},
)
data = res.json()
print(data["added"], data["removed"])
```

**Yanıt**

```json
{
  "success": true,
  "contact_id": "contact_abc123",
  "added": 1,
  "removed": 1
}
```

---

## Etiket kitaplığınızı yönetin

Bu uç noktalar, bir kişiye etiket uygulamak veya kaldırmaktan (yukarıdaki [Etiket ekle veya kaldır](#add-or-remove-tags) bölümüne bakın) farklı olarak, etiketin kendisini yönetir; yani hesabınızdaki bir etiketi yeniden adlandırır veya siler. Hesabınızdaki her etiketin bir kimliği (`tagId`) vardır: bu, kontrol panelinizin etiket yöneticisinde gösterilen ve `POST /tags` ile `{ "name": "..." }` JSON gövdesi (hiçbir `phoneNumber`, `email` veya `contactId` olmadan) kullanarak bir etiket oluşturduğunuzda `data.tag_id` olarak döndürülen kimliktir.

### Bir etiketi güncelle

`PUT /tags/{tagId}`

Yalnızca değiştirdiğiniz alanları gönderin.

| Alan | Açıklama |
|---|---|
| `name` | Etiketin adı. |

```bash
curl -X PUT "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/tags/tagHotLead?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Hot lead (Q3)" }'
```

**Yanıt**

```json
{ "success": true, "tag_id": "tagHotLead" }
```

Hesabınızda bulunmayan bir `tagId`, `404` döndürür.

### Bir etiketi sil

`DELETE /tags/{tagId}`

Bir etiketi kimliğine göre siler. **Bu işlem geri alınamaz** — etiketi taşıyan kişiler etiketi kaybeder. Zaten silinmiş (veya hiç var olmamış) bir etiketi silmek, numaralandırılacak bir şey olmadığından `404` yerine `deleted: 0` ile `200` döndürür.

```bash
curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/tags/tagColdLead?apiKey=YOUR_API_KEY"
```

**Yanıt**

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

### Birden fazla etiketi aynı anda sil

`DELETE /tags`

| Alan | Açıklama |
|---|---|
| `tagIds` | Silinecek etiket kimliklerinden (ID) oluşan dizi (maksimum 1000). |

```bash
curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/tags?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "tagIds": ["tagColdLead", "tagUnsubscribed"] }'
```

**Yanıt**

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

Mevcut olmayan veya başka bir hesaba ait olan kimlikler sessizce atlanır ve `deleted` içinde sayılmaz.

---

## Toplu bayrak ayarla

`POST /contacts/bulk-flag`

Birçok kişide aynı anda bir boolean bayrağı ayarlar. İstek başına en fazla 500 kişi kimliği. Hesabınızda bulunmayan kimlikler atlanır ve `skipped` içinde sayılır.

| Alan | Açıklama |
|---|---|
| `contactIds` | Güncellenecek kişi kimliklerinden (ID) oluşan dizi (maks. 500). |
| `field` | Hangi bayrağın ayarlanacağı. Şunlardan biri: `bot_active` (yapay zeka asistanı açık/kapalı), `dnd` (otomatik erişimi duraklat), `spam`, `private`. |
| `value` | Bayrağın ayarlanacağı boolean değeri. |

**cURL**

```bash
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/bulk-flag?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contactIds": ["contactId1", "contactId2"],
    "field": "bot_active",
    "value": false
  }'
```

**JavaScript**

```javascript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/bulk-flag", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    contactIds: ["contactId1", "contactId2"],
    field: "bot_active",
    value: false,
  }),
});
const data = await res.json();
console.log(data.updated, data.skipped);
```

**Python**

```python
import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/bulk-flag",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "contactIds": ["contactId1", "contactId2"],
        "field": "bot_active",
        "value": False,
    },
)
data = res.json()
print(data["updated"], data["skipped"])
```

**Yanıt**

```json
{
  "success": true,
  "updated": 2,
  "skipped": 0
}
```

---

## Toplu kişi içe aktarma

`POST /contacts/import`

Bir JSON dizisinden tek bir çağrıda 500'e kadar kişi oluşturur. Her kaydın uluslararası formatta bir `phone_number` değerine ihtiyacı vardır; diğer her şey isteğe bağlıdır. Geçersiz telefon numaralarına veya desteklenmeyen kanallara sahip kayıtlar **atlanır** (oluşturulmaz) ve atlanan her kayıt, dizini ve nedeni ile birlikte raporlanır; böylece yalnızca hatalı olanları düzeltip yeniden deneyebilirsiniz.

Hesabınızda zaten mevcut olan telefon numaraları varsayılan olarak `duplicate` şeklinde atlanır. Bunun yerine bu kişileri **güncellemek** için `updateExisting: true` gönderin: kayıtta bulunan alanlar kişinin (`first_name`, `last_name`, `email`, `lead_profile` ve `custom_fields` anahtar bazında birleştirilir) üzerine yazılır, `tags` eklenir ve kişi `listId` listesine eklenir. Mevcut bir kişide kanal, telefon numarası ve bot bayrakları asla değiştirilmez.

İsteğe bağlı olarak, içe aktarılan (veya güncellenen) her kişiyi `listId` ile bir listeye ekleyebilir, belirtilmeyen kayıtlar için bir `defaultChannel` ayarlayabilir ve kayıtları `tags` ile etiketleyebilirsiniz (etiket adları — eksik etiketler oluşturulur, mevcut olanlar büyük/küçük harf duyarsız olarak eşleştirilir).

**Üst düzey alanlar**

| Alan | Gerekli | Açıklama |
|---|---|---|
| `contacts` | Evet | Kişi kayıtları dizisi (maks. 500). |
| `listId` | Hayır | İçe aktarılan (ve güncellenen) her kişinin ekleneceği liste. Hesabınızda mevcut bir liste olmalıdır. |
| `defaultChannel` | Hayır | `channel` belirtilmeyen kayıtlara uygulanan kanal. `whatsapp`, `sms`, `whatsapp_web` değerlerinden biri. Varsayılan olarak `whatsapp`. |
| `updateExisting` | Hayır | Telefon numarası zaten mevcut olan kişileri `duplicate` olarak atlamak yerine güncellemek için `true`. Varsayılan olarak `false`. |

**Kayıt bazlı alanlar**

| Alan | Gerekli | Açıklama |
|---|---|---|
| `phone_number` | Evet | Uluslararası formatta telefon numarası (eksikse başına `+` eklenir). |
| `first_name` | Hayır | Ad. |
| `last_name` | Hayır | Soyadı. |
| `email` | Hayır | E-posta adresi. |
| `channel` | Hayır | `whatsapp`, `sms`, `whatsapp_web` değerlerinden biri. `defaultChannel` değerine geri döner. |
| `is_bot_active` | Hayır | Yapay zeka asistanının yanıt verip vermeyeceği. Varsayılan olarak `true`. |
| `is_private` | Hayır | Özel olarak işaretle. Varsayılan olarak `false`. |
| `lead_profile` | Hayır | Serbest metin müşteri adayı notları. |
| `custom_fields` | Hayır | Özel alan anahtarları ve değerlerinden oluşan nesne. |
| `tags` | Hayır | Etiket adları dizisi (tek bir `"a; b"` dizesi de çalışır). Mevcut olmayan etiketler oluşturulur; mevcut olanlar büyük/küçük harf dikkate alınmadan eşleştirilir. Kayıt başına maksimum 25 adet. |

**cURL**

```bash
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contacts": [
      { "phone_number": "+12025551234", "first_name": "Ann", "last_name": "Lee", "tags": ["vip", "newsletter"] },
      { "phone_number": "+12025551235", "first_name": "Bob" }
    ],
    "listId": "list123",
    "defaultChannel": "whatsapp_web",
    "updateExisting": true
  }'
```

**JavaScript**

```javascript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    contacts: [
      { phone_number: "+12025551234", first_name: "Ann", last_name: "Lee", tags: ["vip", "newsletter"] },
      { phone_number: "+12025551235", first_name: "Bob" },
    ],
    listId: "list123",
    defaultChannel: "whatsapp_web",
    updateExisting: true,
  }),
});
const data = await res.json();
console.log(`Imported ${data.imported}, updated ${data.updated}, skipped ${data.skipped.length}`);
```

**Python**

```python
import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "contacts": [
            {"phone_number": "+12025551234", "first_name": "Ann", "last_name": "Lee", "tags": ["vip", "newsletter"]},
            {"phone_number": "+12025551235", "first_name": "Bob"},
        ],
        "listId": "list123",
        "defaultChannel": "whatsapp_web",
        "updateExisting": True,
    },
)
data = res.json()
print(f"Imported {data['imported']}, updated {data['updated']}, skipped {len(data['skipped'])}")
```

**Yanıt**

```json
{
  "success": true,
  "imported": 2,
  "contact_ids": ["contact_abc123", "contact_def456"],
  "updated": 0,
  "updated_contact_ids": [],
  "skipped": []
}
```

Bazı kayıtlar oluşturulamazsa, nedeni ile birlikte `skipped` içinde görünürler (burada `updateExisting` olmadan, bu nedenle mevcut numara atlanır):

```json
{
  "success": true,
  "imported": 1,
  "contact_ids": ["contact_abc123"],
  "updated": 0,
  "updated_contact_ids": [],
  "skipped": [
    { "index": 1, "phone_number": "+12025551235", "reason": "duplicate" }
  ]
}
```

`updateExisting: true` ile aynı istek, mevcut kişiyi `updated` / `updated_contact_ids` altında raporlar.

Olası atlama nedenleri: `invalid_record`, `missing_phone_number`, `invalid_phone_number`, `invalid_channel`, `duplicate_in_request`, `duplicate`, `contact_limit_reached`, `create_failed`.

> **Plan limitleri.** Planınızın kişi limiti bu kadar yeni kişiye izin vermiyorsa, isteğin tamamı en başta `403` ile reddedilir. Limit işlem sırasında aşılırsa, kalan kayıtlar `contact_limit_reached` nedeni ile atlanmış olarak geri döner.

---

## Bir CSV dosyasından kişileri içe aktarma

[Toplu içe aktarma](#bulk-import-contacts) özelliğinin desteklediğinden daha büyük içe aktarmalar için (yaklaşık 50.000 satıra kadar), hesabınızın depolama alanında zaten bulunan bir CSV dosyası için eşzamansız (async) bir içe aktarma işini sıraya alın ve tamamlanana kadar sorgulayın.

### İçe aktarmayı başlatma

`POST /contacts/import-csv`

| Alan | Gerekli | Açıklama |
|---|---|---|
| `csvStoragePath` | Evet | CSV dosyasının `users/{your account id}/imports/` altındaki, `.csv` ile biten depolama yolu. |
| `listName` | Evet | Bu isimde bir liste oluşturur (veya yeniden kullanır) ve içe aktarılan her kişiyi bu listeye ekler. |
| `existingListRefs` | Hayır | İçe aktarılan her kişinin ayrıca ekleneceği mevcut liste kimliklerinden (ID) oluşan dizi. |
| `defaultChannel` | Hayır | Belirtilmeyen satırlara uygulanan kanal. |

```bash
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import-csv?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "csvStoragePath": "users/abc123/imports/leads.csv",
    "listName": "Webinar signups"
  }'
```

**JavaScript**

```javascript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import-csv", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    csvStoragePath: "users/abc123/imports/leads.csv",
    listName: "Webinar signups",
  }),
});
const data = await res.json();
console.log(data.job_id);
```

**Python**

```python
import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import-csv",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "csvStoragePath": "users/abc123/imports/leads.csv",
        "listName": "Webinar signups",
    },
)
job_id = res.json()["job_id"]
```

**Yanıt** (`202` — içe aktarma sıraya alındı, henüz tamamlanmadı)

```json
{
  "success": true,
  "job_id": "csvimp_abc123",
  "status": "queued"
}
```

> **Dosyayı depolama alanına alma.** Bu uç nokta içe aktarma işini başlatır ve takip eder; dosya yüklemesini doğrudan kabul etmez. CSV dosyasının, siz bu uç noktayı çağırmadan önce `csvStoragePath` konumunda bulunması gerekir — kontrol panelinin kendi CSV içe aktarıcısı bu işlemi ilk adım olarak gerçekleştirir.

### İçe aktarma işini sorgulama

`GET /contacts/import-csv/{jobId}`

```bash
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import-csv/csvimp_abc123?apiKey=YOUR_API_KEY"
```

**Yanıt**

```json
{
  "success": true,
  "job_id": "csvimp_abc123",
  "status": "completed",
  "imported": 812,
  "updated": 0,
  "skipped": 14,
  "errors": [],
  "error_message": null
}
```

`status`, `queued` → `processing` → `completed` aşamalarından geçer veya `error_message` içindeki neden ile `failed` durumuna düşer. Hesabınızda bulunmayan bir `jobId`, `404` döndürür.

---

## Kişileri dışa aktarma

Kişilerinizin eşzamansız (async) CSV dışa aktarma işlemini başlatır ve tamamlanma durumunu sorgulayabileceğiniz bir iş döndürür.

### Dışa aktarmayı başlat

`POST /contacts/export`

| Alan | Zorunlu | Açıklama |
|---|---|---|
| `listId` | Hayır | Yalnızca bu listeye ait kişileri dışa aktar. |
| `contactIds` | Hayır | Yalnızca bu belirli kişi kimliklerini (ID) dışa aktar. |

Her ikisini de boş bırakmak, hesabınızdaki tüm kişileri dışa aktarır.

```bash
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/export?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "listId": "list123" }'
```

**JavaScript**

```javascript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/export", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ listId: "list123" }),
});
const data = await res.json();
console.log(data.job_id);
```

**Python**

```python
import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/export",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"listId": "list123"},
)
job_id = res.json()["job_id"]
```

**Yanıt** (`202` — dışa aktarma kuyruğa alındı)

```json
{
  "success": true,
  "job_id": "export_abc123",
  "status": "queued"
}
```

### Dışa aktarma işini sorgula

`GET /contacts/export/{jobId}`

```bash
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/export/export_abc123?apiKey=YOUR_API_KEY"
```

**Yanıt**

```json
{
  "success": true,
  "job_id": "export_abc123",
  "status": "completed",
  "export_id": "exp_xyz789",
  "contact_count": 812,
  "error_message": null
}
```

> `status` `"completed"` olduğunda `export_id` ve `contact_count` alırsınız. Oluşturulan CSV dosyasını indirme işlemi, kontrol panelinizin Dışa Aktarmalar sayfasından yapılır.

---

## Bir kişiye mesaj gönderin

`POST /contacts/{contactId}/send-message`

Mevcut bir kişiye, zaten kullandıkları kanal üzerinden bir mesaj gönderir. Mesaj kuyruğa alınır ve arka planda iletilir; yanıt, mesajın teslim edildiğini değil, kabul edildiğini doğrular.

| Alan | Gerekli | Açıklama |
|---|---|---|
| `body` | Evet | Gönderilecek mesajın metni. |
| `mediaUrl` | Hayır | Eklenecek medya dosyasının URL'si. |
| `mediaContentType` | Hayır | Ekli medyanın MIME türü (örneğin `image/jpeg`). |

**cURL**

```bash
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/send-message?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "body": "Hi! Your appointment is confirmed." }'
```

**JavaScript**

```javascript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/send-message", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ body: "Hi! Your appointment is confirmed." }),
});
const data = await res.json();
console.log(data.messageId);
```

**Python**

```python
import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/send-message",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"body": "Hi! Your appointment is confirmed."},
)
print(res.json()["messageId"])
```

**Yanıt**

```json
{
  "success": true,
  "messageId": "aB3dE5fG7hI9jK1lM2nO",
  "contactId": "contact_abc123",
  "channel": "whatsapp",
  "message": "Message created successfully. Delivery is being processed."
}
```

> **Şu anda gönderilemiyor mu?** Kişinin rahatsız etmeyin veya gizli modu etkinse ya da giden mesajları alabilen bir kanalda değilse, istek bir `422` ve açıklayıcı bir `error` ile reddedilir.

Kişi kimliği yerine telefon numarası, Instagram kimliği veya diğer kanal kimlikleri ile göndermek için — ve genel olarak mesajlaşma hakkında daha fazla bilgi için — [Messages API](messages.md) bölümüne bakın.

---

## Bir kişiye yapay zeka temsilcisi atayın

`POST /contacts/{contactId}/assign-agent`

Mevcut bir konuşmayı, bir sonraki mesajdan itibaren farklı bir yapay zeka temsilcisine taşır. Bu, bir sohbetin menüsündeki **Yapay Zeka Temsilcisi Ata** seçeneğiyle ve Otomasyonlardaki **Yapay zeka temsilcisi veya kampanya ata** eyleminin kullandığı adımla aynıdır.

| Alan | Zorunlu | Açıklama |
|---|---|---|
| `agentId` | Evet | Devralması gereken yapay zeka temsilcisinin kimliği veya konuşmanın ekip gelen kutunuza geri dönmesi için atamayı temizlemek üzere `null`. |
| `triggerAIResponse` | Hayır | `true`, yeni atanan temsilcinin kişinin yanıtlanmamış en son mesajlarına hemen yanıt vermesini sağlar. Varsayılan değer `false` şeklindedir. |

> **`triggerAIResponse: true` ile dikkatli olun** — kişiye o anda bir mesaj gönderir, bu yüzden yalnızca hemen mesajlaşmak istediğinizde kullanın. Messenger ve Instagram'da, kişi size en son 24 saatten daha uzun süre önce yazdıysa bu mesaj başarısız olur.

**cURL**

```bash
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/assign-agent?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "agentId": "agent_xyz789" }'
```

**JavaScript**

```javascript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/assign-agent", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ agentId: "agent_xyz789" }),
});
const data = await res.json();
console.log(data.data.agentId);
```

**Python**

```python
import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/assign-agent",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"agentId": "agent_xyz789"},
)
print(res.json()["data"]["agentId"])
```

**Yanıt**

```json
{
  "success": true,
  "data": {
    "contactId": "contact_abc123",
    "agentId": "agent_xyz789",
    "aiResponseTriggered": false
  }
}
```

> Temsilci, kişiyle aynı hesaba ait olmalıdır; aksi takdirde istek bir `404` veya `403` ile reddedilir. Temsilci kimliklerini Yapay Zeka Temsilcileri sayfasında bulabilirsiniz (her temsilcinin URL'si kendi kimliğiyle biter).

---

## Birçok kişiye yapay zeka temsilcisi atama

`POST /contacts/bulk-assign-agent`

Birçok görüşmeyi tek bir çağrıda farklı bir yapay zeka temsilcisine taşır veya `null` ile hepsinin atamasını temizler. Bu tamamen bir yönlendirme değişikliğidir: **hiçbir mesaj gönderilmez ve temsilci kimseye yanıt vermez**. Her kişi, bir sonraki yazışmasında yeni temsilciye atanmış olur. (Bu yüzden burada `triggerAIResponse` yoktur.)

| Alan | Gerekli | Açıklama |
|---|---|---|
| `agentId` | Evet | Devralması gereken yapay zeka temsilcisi veya atamayı temizlemek için `null`. |
| `contactIds` | Üçünden biri | Taşınacak en fazla 500 kişi kimliği. |
| `filter` | Üçünden biri | Kişileri listelemek yerine sunucudan seçin, en yeniden başlayarak. Sayım uç noktasının filtreleriyle aynı anahtarları alır: `agentId` (veya `none`), `channel`, `tag`, `listId`, `botActive`, `status`. |
| `rules` | Üçünden biri | Bir akıllı liste kuralları nesnesi — [The `smart_rules` shape](#the-smart_rules-shape) bölümüne bakın. |
| `limit` | Hayır | `filter` veya `rules` ile seçim yaptığınızda bu çağrıda kaç kişinin taşınacağı. 1 ile 500 arası, varsayılan 500'dür. |

`contactIds`, `filter` veya `rules` değerlerinden tam olarak birini gönderin.

**cURL**

```bash
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/bulk-assign-agent?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agentId": "agent_xyz789",
    "filter": { "agentId": "agent_abc123", "channel": "messenger" }
  }'
```

**JavaScript**

```javascript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/bulk-assign-agent", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    agentId: "agent_xyz789",
    filter: { agentId: "agent_abc123", channel: "messenger" },
  }),
});
const data = await res.json();
console.log(data.updated, data.remaining);
```

**Python**

```python
import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/bulk-assign-agent",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "agentId": "agent_xyz789",
        "filter": {"agentId": "agent_abc123", "channel": "messenger"},
    },
)
data = res.json()
print(data["updated"], data["remaining"])
```

**Yanıt**

```json
{
  "success": true,
  "agentId": "agent_xyz789",
  "matched": 3415,
  "updated": 500,
  "skipped": 0,
  "remaining": 2915,
  "filters": { "agentId": "agent_abc123" }
}
```

`matched`, seçimin toplamda kaç kişi bulduğudur, `updated` bu çağrıyla kaç kişinin taşındığıdır, `skipped` gönderdiğiniz kimliklerden kaçının hesabınızda bulunamadığıdır ve `remaining` bu çağrı bittiğinde hala kaç kişinin eşleştiğidir.

**Herkesi taşıma.** Bir çağrı en fazla 500 kişiyi taşıdığından, büyük bir grup birkaç çağrı gerektirir. Bir kişi taşındıktan sonra eşleşmeyi durduran bir filtre kullanın — örneğin `agent_xyz789`'e atarken `filter: { "agentId": "agent_abc123" }` kullanın — ve `remaining` değeri `0` olarak dönene kadar aynı çağrıyı tekrarlayın. Bunun yerine `contactIds` gönderdiğinizde, `remaining` her zaman `0` olur.

---

## Bir kişiyi departmana ata

`POST /contacts/{contactId}/department`

"Bu adayı Satış departmanına ata" — bir kişiyi adlandırılmış bir departman altında dosyalar ve varsayılan olarak, o departmanda şu anda en az kişiye sahip olan kişiye yönlendirir. Bu, [bir yapay zeka temsilcisi atamaktan](#assign-an-ai-agent-to-a-contact) ayrıdır: bir departman "bunun sahibi hangi ekip" sorusunu yanıtlar, bir temsilci "bunu hangi yapay zeka yanıtlar" sorusunu yanıtlar ve birini ayarlamak diğerini asla temizlemez.

| Alan | Zorunlu | Açıklama |
|---|---|---|
| `department_id` | Evet | Kişinin altında dosyalanacağı departman. Temizlemek için `null` değerini iletin. |
| `hand_to_member` | Hayır | Kişiyi ayrıca o departmandaki en az iş yüküne sahip kişiye yönlendirir. Varsayılan olarak `true` değerindedir. Zaten birinin sahip olduğu bir kişiyi asla yeniden atamaz. |

**cURL**

```bash
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/department?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "department_id": "dept_sales" }'
```

**JavaScript**

```javascript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/department", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ department_id: "dept_sales" }),
});
const data = await res.json();
console.log(data.assigned_to);
```

**Python**

```python
import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/department",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"department_id": "dept_sales"},
)
print(res.json()["assigned_to"])
```

**Yanıt**

```json
{
  "success": true,
  "department_id": "dept_sales",
  "assigned_to": "member_uid_123"
}
```

`assigned_to`, kişi zaten birine ait olduğunda veya `hand_to_member: false` değerini ilettiğinizde `null` olur.

---

## Bir kişiyi kanallar arasında bağla

"WhatsApp'ta devam et" (veya SMS), bu kişinin iletişim bilgilerini başka bir telefon tabanlı kanalda bulur veya oluşturur ve uygulamanın geri kalanının onları aynı kişi olarak tanıması için ikisini birbirine bağlar.

### Başka bir kanala bağlantı kurma

`POST /contacts/{contactId}/link-channel`

| Alan | Zorunlu | Açıklama |
|---|---|---|
| `channel` | Evet | Bağlantı kurulacak kanal. `whatsapp`, `whatsapp_web`, `sms` değerlerinden biri. |
| `phoneNumber` | Hayır | Yeni kanalda kullanılacak telefon numarası. Varsayılan olarak kaynak kişinin kendi numarası kullanılır. |

```bash
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/link-channel?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "channel": "sms" }'
```

**Yanıt**

```json
{
  "success": true,
  "data": {
    "contact_id": "contact_def456",
    "person_id": "person_xyz789",
    "created": true
  }
}
```

`created`, hedef kanal için yeni bir kişi oluşturulup oluşturulmadığını veya mevcut bir kişinin bulunup bağlanıp bağlanmadığını size bildirir. Bunu ikinci kez çağırmak güvenlidir; kopya oluşturmak yerine `created: false` ile aynı `contact_id` değerini döndürür.

`422`, hesabın bu bağlantıyı şu anda gerçekleştiremeyeceği anlamına gelir: kişi zaten o kanal ailesindedir, kullanılacak bir telefon numarası yoktur veya hedef kanal için bağlı bir gönderici bulunmamaktadır. `409` ise iki kişinin zaten iki farklı kişiye bağlı olduğu anlamına gelir; önce birinin bağlantısını kesin.

### Bir kişinin bağlı görüşmelerini listeleme

`GET /contacts/{contactId}/linked`

Bu kişiyle aynı kişi olan diğer görüşmeleri döndürür. Bağlantısı olmayan bir kişi, `404` yerine boş bir dizi döndürür; "bu kişinin başka kanalı yok" durumu normal bir durumdur.

```bash
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/linked?apiKey=YOUR_API_KEY"
```

**Yanıt**

```json
{
  "success": true,
  "data": [
    {
      "contact_id": "contact_def456",
      "channel": "sms",
      "custom_channel": null,
      "first_name": "Jane",
      "last_name": "Smith",
      "phone_number": "+15551234567",
      "last_message": "Sounds good, thanks!",
      "last_message_timestamp": "2026-06-09T10:21:00.000Z",
      "linked_from": {
        "contact_id": "contact_abc123",
        "channel": "whatsapp",
        "linked_at": "2026-06-01T09:00:00.000Z",
        "reason": "continue_on_channel"
      }
    }
  ]
}
```

### Bir kişinin bağlantısını kesme

`DELETE /contacts/{contactId}/link`

Bu kişiyi, tek taraflı olarak bağlı olduğu kişiden ayırır; o kişiye bağlı olan diğer kişiler bağlantılarını korur, bu nedenle üç kişiden birinin bağlantısını kesmek grubu dağıtmaz.

```bash
curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/link?apiKey=YOUR_API_KEY"
```

**Yanıt**

```json
{ "success": true }
```

---

## Bir kişinin profil resmini getirme

`POST /contacts/{contactId}/profile-pic`

Kişinin WhatsApp veya Meta profil fotoğrafını talep üzerine getirir (ve önbelleğe alır); bu, [Kişi getirme](#get-a-contact-by-phone-or-email) işleminde `avatarUrl` olarak döndürülen fotoğrafın aynısıdır ve yenilenmiştir.

```bash
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/profile-pic?apiKey=YOUR_API_KEY"
```

**Yanıt**

```json
{
  "success": true,
  "avatar_url": "https://example.com/photo.jpg",
  "cached": false
}
```

`cached: true`, URL'nin yeni bir sağlayıcı sorgusu yerine yakın zamandaki bir getirme işleminden geldiği anlamına gelir; resimler 7 gün boyunca önbelleğe alınır ve sağlayıcının ulaşılabilir bir fotoğrafı olmadığını bildirdiği bir kişi, 24 saat boyunca kullanılamaz olarak önbelleğe alınır. Getirilecek bir resim olmadığında `avatar_url` atlanır ve `message` bunun nedenini açıklar.

---

## Kişileri yapay zeka ile otomatik etiketleme

Hesabınızın etiket kurallarını bir veya daha fazla kişinin tüm konuşma geçmişi üzerinde çalıştırır ve tıpkı canlı sohbet sırasında çalışan gerçek zamanlı etiketlemede olduğu gibi etiketleri uygular (veya kaldırır) — aynı kurallar, etiket başına aynı kredi maliyeti geçerlidir.

### Bir çalıştırma başlatın

`POST /contacts/auto-tag`

| Alan | Gerekli | Açıklama |
|---|---|---|
| `scope` | Evet | Belirli kişileri etiketlemek için `"contacts"` veya bir yapay zeka temsilcisi tarafından halihazırda yönetilen her konuşmayı etiketlemek için `"agent"`. |
| `contact_ids` | `scope`, `"contacts"` olduğunda gereklidir | 1 ila 500 arasında kişi kimliği dizisi. |
| `agent_id` | `scope`, `"agent"` olduğunda gereklidir | Konuşmaları etiketlenecek yapay zeka temsilcisi. `scope`, `"contacts"` olduğunda bu isteğe bağlıdır ve yalnızca temsilcinin hangi etiket kurallarının çalışacağını daraltır. |

```bash
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/auto-tag?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "scope": "contacts", "contact_ids": ["contact_abc123", "contact_def456"] }'
```

**Tek bir** kişi satır içi olarak çalışır ve sonucu hemen döndürür:

```json
{ "success": true, "result": { "tags_applied": 2, "tags_removed": 0 } }
```

**İki veya daha fazla** kişi (veya `scope: "agent"`) arka plan işi olarak çalışır ve hemen `202` döndürür:

```json
{ "success": true, "run_id": "m1x2y3-a1b2c3d4", "total": 214 }
```

### Bir çalıştırmayı sorgulayın

`GET /contacts/auto-tag/run`

Hesabın mevcut (veya en son) çalıştırmasını döndürür, böylece `run_id` takibini kendiniz yapmadan ilerlemeyi sorgulayabilirsiniz.

```bash
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/auto-tag/run?apiKey=YOUR_API_KEY"
```

**Yanıt**

```json
{
  "success": true,
  "run": {
    "run_id": "m1x2y3-a1b2c3d4",
    "status": "running",
    "total": 214,
    "processed": 58,
    "tagged_contacts": 12,
    "tags_applied": 15,
    "tags_removed": 2,
    "credits_charged": 15
  }
}
```

Hesap hiç çalıştırma başlatmadığında `run`, `null` değerindedir. `status`, `"running"` durumundan `"completed"` veya `"failed"` durumuna geçer.

Hesap başına aynı anda yalnızca bir toplu çalıştırma devam edebilir; başka bir çalıştırma devam ederken ikincisini başlatmak `error_code: "auto_tag_run_in_progress"` ile `409` döndürür. Tek kişilik bir çalıştırmada kredinin bitmesi `error_code: "insufficient_credits"` ile `402` döndürür; toplu çalıştırma ise bunun yerine erken durur ve `run` içinde ne kadar ilerlediğini bildirir.

---

## Bir kişiyi silin

`DELETE /contacts/{contactId}`

Bir kişiyi kimliğiyle birlikte mesaj geçmişiyle beraber kalıcı olarak siler. **Bu işlem geri alınamaz.** Tek bir çağrıda birden fazla kişiyi silmek için aşağıdaki [Kişileri sil](#delete-contacts) kısmını kullanın.

**cURL**

```bash
curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123", {
  method: "DELETE",
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.success);
```

**Python**

```python
import requests

res = requests.delete(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
print(res.json()["success"])
```

**Yanıt**

```json
{
  "success": true
}
```

Hesabınızda bulunmayan veya farklı bir hesaba ait olan bir kişi kimliği, `404` döndürür.

---

## Kişileri sil

`DELETE /contacts`

Tek bir çağrıda (500 kimliğe kadar) bir veya daha fazla kişiyi kimliklerine göre kalıcı olarak siler. Hesabınızda bulunmayan kimlikler atlanır ve `skipped` içinde sayılır. **Bu işlem geri alınamaz.**

| Alan | Açıklama |
|---|---|
| `contactIds` | Silinecek kişi kimlikleri dizisi (maks. 500). |

**cURL**

```bash
curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "contactIds": ["contactId1", "contactId2"] }'
```

**JavaScript**

```javascript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts", {
  method: "DELETE",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ contactIds: ["contactId1", "contactId2"] }),
});
const data = await res.json();
console.log(`Deleted ${data.deleted}, skipped ${data.skipped}`);
```

**Python**

```python
import requests

res = requests.delete(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"contactIds": ["contactId1", "contactId2"]},
)
data = res.json()
print(f"Deleted {data['deleted']}, skipped {data['skipped']}")
```

**Yanıt**

```json
{
  "success": true,
  "deleted": 2,
  "skipped": 0
}
```

---

## Özel bir alanı silme

`DELETE /contacts/custom-fields/{fieldKey}`

Hesabınızdaki **her** kişiden bir özel alan anahtarını kaldırır. Bunu, özel bir alanı yeniden adlandırdıktan veya kullanımdan kaldırdıktan sonra temizlik yapmak için kullanın. Anahtar yalnızca harfler, rakamlar, alt çizgiler ve kısa çizgiler içerebilir. Kaç kişinin güncellendiğini döndürür. **Bu işlem geri alınamaz.**

**cURL**

```bash
curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/custom-fields/webinar_date_nh?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/custom-fields/webinar_date_nh", {
  method: "DELETE",
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(`Removed from ${data.updated} contacts`);
```

**Python**

```python
import requests

res = requests.delete(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/custom-fields/webinar_date_nh",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
print(f"Removed from {res.json()['updated']} contacts")
```

**Yanıt**

```json
{
  "success": true,
  "updated": 42
}
```

::: note
**Not:** Desteklenmeyen karakterler içeren bir alan anahtarı `400` döndürür.
:::


---

## Listeler

Listeler kişileri gruplandırır. Bir liste ya **statik** (kimin listede olacağına siz karar verirsiniz) ya da **akıllı** (üyelik kurallara göre hesaplanır ve otomatik olarak güncel tutulur — bkz. [Listeleri ve Kişileri Düzenleme](../get-started/list-and-contact-management.md#smart-lists-auto-updating)) olabilir.

| Alan | Açıklama |
|---|---|
| `name` | Oluşturma sırasında gereklidir. En fazla 100 karakter. |
| `status` | `live` (varsayılan) veya `draft`. Küçük harf. |
| `contact_ids` | Listeye eklenecek kişi kimlikleri dizisi. **Yalnızca statik listeler.** |
| `type` | `static` (varsayılan) veya `smart`. |
| `smart_rules` | Kural kümesi — `type`, `smart` olduğunda gereklidir. Aşağıya bakın. |

### Liste oluşturma

`POST /lists`

```bash
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/lists?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "name": "Hot leads (active)",
        "type": "smart",
        "smart_rules": {
          "match": "all",
          "conditions": [
            { "field": "tags", "op": "has_any", "value": ["tagHotLead"] },
            { "field": "last_activity_at", "op": "within_last", "value": { "amount": 90, "unit": "days" } }
          ]
        }
      }'
```

**Yanıt**

```json
{
  "success": true,
  "list_id": "list_abc123",
  "evaluation": { "added": 3, "removed": 0, "total": 3 }
}
```

Akıllı bir liste, aynı istek içinde **satır içi** olarak değerlendirilir, bu nedenle `evaluation` size tam olarak kimin listede yer aldığını söyler. Statik bir listede `evaluation`, `null` değerindedir.

### Liste güncelleme

`PUT /lists/{listId}`

Yalnızca değiştirdiğiniz alanları gönderin. `smart_rules` değerini değiştirmek listeyi anında yeniden değerlendirir ve aynı `evaluation` nesnesini döndürür.

```bash
curl -X PUT "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/lists/list_abc123?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "smart_rules": { "match": "any", "conditions": [ { "field": "tags", "op": "has_any", "value": ["tagHotLead", "tagWebinar"] } ] } }'
```

Bir listeyi iki tür arasında değiştirebilirsiniz:

- **Statik → akıllı**: `{ "type": "smart", "smart_rules": { … } }` gönderin. Kurallar anında devreye girer.
- **Akıllı → statik**: `{ "type": "static" }` gönderin. Kurallar kaldırılır ve listede kim varsa orada kalmaya devam eder.

### `smart_rules` yapısı

```json
{
  "match": "all",
  "conditions": [
    { "field": "tags", "op": "has_any", "value": ["tagHotLead"] },
    { "field": "channel", "op": "is_any", "value": ["whatsapp", "sms"] },
    { "field": "last_incoming_message_at", "op": "not_within_last", "value": { "amount": 7, "unit": "days" } },
    { "field": "created_at", "op": "after", "value": "2026-01-01" },
    { "field": "is_bot_active", "op": "is", "value": true },
    { "field": "email", "op": "is_set" },
    { "field": "custom_field", "key": "Plan", "op": "eq", "value": "pro" }
  ]
}
```

- `match` — `all` (her koşul doğru olmalıdır) veya `any` (en az biri).
- `conditions` — 1 ila 20 koşul, her biri en fazla 100 değer, 200 karaktere kadar dizeler.

| `field` | `op` | `value` |
|---|---|---|
| `tags` | `has_any`, `has_all`, `has_none` | etiket kimlikleri dizisi |
| `lists` | `in_any`, `not_in_any` | liste kimlikleri dizisi (**yalnızca statik listeler** — akıllı bir liste başka bir akıllı listeden oluşturulamaz) |
| `channel` | `is_any`, `is_none` | kanal dizisi |
| `status` | `is_any`, `is_none` | kişi durumu dizisi |
| `created_at`, `last_activity_at`, `last_incoming_message_at`, `last_outgoing_message_at`, `first_ai_interaction_at`, `last_ai_interaction_at` | `within_last`, `not_within_last` | `{ "amount": 1–3650, "unit": "hours" \| "days" }` |
| aynı tarih alanları | `before`, `after` | ISO tarihi (`"2026-01-01"`, tam günler olarak karşılaştırılır) veya tam ISO tarih-saati (`"2026-01-01T14:30:00Z"`, tam ana göre karşılaştırılır) |
| aynı tarih alanları | `is_set`, `not_set` | — |
| `has_interacted_with_ai` | `is` | `true` / `false` — `true`, yapay zekanın en az bir kez (herhangi bir zamanda) mesaj gönderdiği kişileri eşleştirir |
| `is_bot_active`, `do_not_disturb`, `is_private`, `has_ever_responded` | `is` | `true` / `false` |
| `email`, `phone_number`, `first_name`, `last_name` | `is_set`, `not_set`, `contains`, `not_contains` | `contains` formları için dize |
| `current_campaign_id`, `assigned_agent` | `is_any`, `is_none`, `is_set`, `not_set` | `is_any` / `is_none` formları için kimlik dizisi |
| `custom_field` (artı bir `key`) | `eq`, `neq`, `contains`, `not_contains`, `is_set`, `not_set` | değer formları için dize |

`not_within_last` ayrıca tarihin hiç ayarlanmadığı kişileri de eşleştirir ("N'den daha önce, **veya hiç**"), ve metin karşılaştırmaları büyük/küçük harf duyarlılığını göz ardı eder.

**Yapay zeka etkileşimi.** `has_interacted_with_ai` yaşam boyu bayrağıdır: Yapay zekanızın en az bir mesaj gönderdiği her kişi için `true`, diğer herkes için (yalnızca ekibinizin yanıt verdiği kişiler dahil) `false`. Bu bayrak, yapay zekanın bir kişiye gönderdiği ilk mesaja damgalanır ve asla silinmez; bu nedenle kişinin yapay zeka yanıtlarını kapatmak veya onları başka bir kampanyaya taşımak bunu sıfırlamaz. Bir *dönem* için — "yapay zekamın bu ay ilgilendiği kişiler", yani genel faturalandırma sorusu — bunun yerine `last_ai_interaction_at` aralığını kullanın:

```json
{ "field": "last_ai_interaction_at", "op": "within_last", "value": { "amount": 30, "unit": "days" } }
```

Bunların hiçbirini `is_bot_active` (yapay zekanın yanıt vermesine *izin verilmiştir*, yanıt verdiği anlamına gelmez) veya `has_ever_responded` (kişi herhangi birine geri yazmıştır) ile karıştırmayın. Aynı iki damga her kişide `first_ai_interaction_at` / `last_ai_interaction_at` olarak döndürülür ve tüm kural kümesi `GET /contacts?rules=` üzerinde de çalışır, böylece bir liste oluşturmadan eşleşmeleri sayabilirsiniz.

### Bir kural kümesini önizleyin

`POST /lists/preview`

Hiçbir şeyi oluşturmadan veya değiştirmeden, bir kural kümesinin eşleşeceği kişileri sayar ve örneklendirir. Kuralları kaydetmeden önce doğruluğunu kontrol etmek için kullanın.

```bash
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/lists/preview?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "smart_rules": { "match": "all", "conditions": [ { "field": "tags", "op": "has_any", "value": ["tagHotLead"] } ] } }'
```

**Yanıt**

```json
{
  "success": true,
  "count": 3,
  "sample": [
    {
      "id": "contact_abc123",
      "first_name": "Sofia",
      "last_name": "Martinez",
      "phone_number": "+31600000000",
      "email": "sofia@example.com",
      "channel": "whatsapp"
    }
  ]
}
```

`sample`, en son aktif olandan başlayarak 10 kişiye kadar tutar.

### Akıllı listeyi şimdi yeniden çalıştırın

`POST /lists/{listId}/evaluate`

Anında yeniden değerlendirmeyi zorunlu kılar (paneldeki **Şimdi yenile** ile aynı işlevi görür). Akıllı listeler zaten bir kişi değiştiğinde ve zamana dayalı kurallar için her 15 dakikada bir güncellenir, bu nedenle bu işlem yalnızca sonucu *hemen şimdi* istediğinizde gereklidir.

**Yanıt**

```json
{
  "success": true,
  "list_id": "list_abc123",
  "evaluation": { "added": 2, "removed": 1, "total": 4 }
}
```

`evaluation.skipped: true`, aynı listenin başka bir değerlendirmesinin zaten çalışmakta olduğu ve bu çağrının hiçbir şey yapmadığı anlamına gelir.

### Akıllı listeler elle seçilen üyeleri kabul etmez

Üyelik uç noktaları, hedef liste akıllı olduğunda `"This is a smart list — its members are computed from its rules. Edit the rules instead."` ile **`409`** döndürür. Bu durum `POST /contacts/lists`, `DELETE /contacts/lists`, `POST /contacts/lists/batch`, `contact_ids` üzerindeki `POST /lists` ve `PUT /lists/{listId}` işlemlerini ve CSV içe aktarma hedefi olarak bir akıllı liste seçmeyi kapsar. Bunun yerine kuralları değiştirin.

**Statik** bir listede `POST /lists/{listId}/evaluate` çağırmak da bir `409` hatasıdır; çünkü çalıştırılacak kuralları yoktur.

---

## Kişiler API hataları

Kişi uç noktaları standart hata zarfını döndürür:

```json
{
  "success": false,
  "error": "Contact not found"
}
```

Bazı uç noktalar, genellikle HTTP durumuyla eşleşen `error_code` değerini de içerir; bunun tek istisnası, HTTP durumunun `200` olduğu ve yalnızca `error_code` değerinin `409` bilgisini taşıdığı aşağıdaki yinelenen kişi durumudur. Kişi uç noktalarına özgü kodlar şunlardır:

| Kod | Bir kişi uç noktasında gerçekleştiğinde |
|---|---|
| `400` | Hatalı istek — eksik/geçersiz alan, boş gövde, hatalı imleç veya toplu işlemde 500'den fazla kimlik. |
| `402` | Bir kişi üzerinde yapay zeka etiketleme işlemini tamamlamak için yeterli kredi yok (`error_code: "insufficient_credits"`). |
| `404` | Kişi, liste veya etiket hesabınızda bulunamadı. |
| `409` | Bu telefon numarasına sahip bir kişi zaten mevcut (oluşturma sırasında). Gövdede `error_code` olarak ve `200` HTTP durumuyla döndürülür, bu yüzden burada `error_code` üzerinden dallanma yapın. Ayrıca toplu otomatik etiketleme işlemi zaten devam ediyorsa (`error_code: "auto_tag_run_in_progress"`) veya bir kişiyi başka bir kanala bağlamak, halihazırda iki farklı kişiye bağlı olan iki kişiyi birleştirecekse döndürülür. |
| `422` | Kişi şu anda mesaj alamıyor (rahatsız etmeyin, gizli veya desteklenmeyen kanal). Kanal bağlantısı uç noktasında, telefon numarası olmaması, desteklenmeyen bir kanal eşleşmesi veya hedef kanal için bağlı bir gönderici olmaması durumlarını da kapsar. |

Bir kişi uç noktasındaki `403`, plan erişiminden ziyade kişi sınırı veya liste izni sorunu anlamına da gelebilir. Her uç noktanın döndürebileceği ortak kodlar — `401`, `403` (planınız API erişimini içermiyor), `429` (hız sınırı) ve `500` — yeniden deneme rehberliği ile birlikte [Hatalar ve Sayfalandırma](errors-and-pagination.md) bölümünde listelenmiştir.

---

## Sonraki adımlar

- [Mesajlar API'si](messages.md) — kanal kimliğine göre mesaj gönderin ve konuşmaları yönetin.
- [API Başvurusu](reference.md) — etiketler ve listeler dahil olmak üzere tam uç nokta listesi.
- [API Erişimi](../integrations/api-access.md) — kimlik doğrulama, hız sınırları ve hata işleme.
