
# Ajanslar için API

Bir ajans olarak, müşterilerinizin kullandığı REST API'nin aynısını kullanabilir, ancak bireysel istekleri kendi hesabınız yerine yönettiğiniz **alt hesaplardan** birine yönlendirebilirsiniz. Bu, bir müşteriyi uçtan uca sisteme dahil eden araçlar oluşturmanıza olanak tanır; kampanyalarını oluşturma, yapay zekalarını bir bilgi tabanı üzerinde eğitme, kişilerini içe aktarma, mesajlaşma kanallarını bağlama ve telefon numaraları satın alma işlemlerinin tümünü, her bir alt hesaba manuel olarak giriş yapmanıza gerek kalmadan gerçekleştirebilirsiniz.

Bu sayfa yalnızca ajansa özel davranışları kapsar: `sub_account_id` parametresi ile bir alt hesap adına nasıl işlem yapılacağı. Temel bilgiler (anahtar oluşturma, kimlik doğrulama, temel URL, hata formatı, hız sınırları) için [API Erişimi](../integrations/api-access.md) kılavuzu ile başlayın. Oradaki her şey burada da geçerlidir; **ajans hesabınızın** API anahtarı ile kimlik doğrulaması yaparsınız.

::: note
**Not:** Bu sayfa teknik içeriklidir. Geliştirici değilseniz, entegrasyonunuzu oluşturan kişiyle paylaşın.
:::


***

## "Adına işlem yapma" nasıl çalışır

Varsayılan olarak, her API isteği API anahtarının sahibi olan hesapta, yani ajans hesabınızda işlem yapar. Bunun yerine yönetilen bir müşteri hesabında işlem yapmak için, isteğe isteğe bağlı `sub_account_id` parametresini ekleyin ve bu parametreyi ilgili müşterinin hesap kimliğine (id) ayarlayın.

- **`sub_account_id` parametresini çıkarırsanız** → istek kendi ajans hesabınız üzerinde gerçekleştirilir.
- **`sub_account_id` parametresini eklerseniz** → istek ilgili alt hesap üzerinde gerçekleştirilir, ancak yalnızca platform alt hesabın gerçekten size ait olduğunu doğruladıktan sonra.

Her zaman **ajans hesabınızın** API anahtarı ile kimlik doğrulaması yaparsınız. Alt hesabın kendi anahtarına asla ihtiyaç duymazsınız ve alt hesabın kimlik bilgilerini asla yönetmezsiniz.

### Nereye eklenir

- **GET / DELETE uç noktaları** → bunu bir sorgu parametresi olarak iletin: `?sub_account_id=THE_SUB_ACCOUNT_ID` (sorgu ile kimlik doğrulaması yapıyorsanız `apiKey` parametrenizin yanında).
- **POST / PUT / PATCH uç noktaları** → bunu JSON istek gövdesine `"sub_account_id": "THE_SUB_ACCOUNT_ID"` olarak dahil edin.
- **Yapay zeka asistanları** → yapılandırılacak bir şey yok. [MCP sunucusu](../integrations/connect-ai-clients.md), aynı ayarı okuma araçlarında taşır, bu nedenle ajans anahtarınızla yapılan tek bir bağlantı her müşteri hakkında rapor verebilir: isteğinizde müşterinin adını belirtmeniz yeterlidir ("Bella's Bistro'nun kaç kişisi var?"). Yazma eylemleri de mevcuttur: `sub_account_id` kabul eden her uç nokta bir araç olarak sunulur, böylece aynı bağlantıdan bir müşteri adına oluşturabilir, değiştirebilir ve gönderebilirsiniz.

### Bir alt hesabın kimliğini (id) bulma

`sub_account_id`, müşteri hesabının benzersiz kimliğidir. Alt hesaplarınızın ve kimliklerinin listesini **SubAccounts** API uç noktalarından (bkz. [Alt Hesaplar](sub-accounts.md) kılavuzu) veya kenar çubuğundaki **Alt Hesaplar** sayfasından alabilirsiniz.

***

## Sahiplik her zaman doğrulanır

Bir `sub_account_id` gönderdiğinizde, platform hesabın gerçek bir alt hesap olduğunu **ve** ajansınıza ait olduğunu kontrol eder. İstek ancak o zaman işleme alınır.

Eğer kimlik bilinmiyorsa, bir alt hesap değilse veya başka bir ajansa aitse, istek **`404`** yanıtı ile başarısız olur:

```json
{
  "success": false,
  "error_code": 404,
  "error": "Sub-account not found."
}
```

> **Neden 403 değil de 404?** Bir "yasak" (forbidden) yanıtı, dışarıdan birine kimliğin var olduğunu ancak kendilerine ait olmadığını söyler. "Mevcut değil" ve "size ait değil" durumları için aynı `404` değerini döndürmek, uç noktanın hangi hesap kimliklerinin diğer ajanslara ait olduğunu keşfetmek için kullanılamayacağı anlamına gelir. Buradaki bir `404` değerini "bu, yönettiğiniz bir alt hesap değil" şeklinde değerlendirin.

***

## `sub_account_id` nerede desteklenir

`sub_account_id`, temelde her **kaynak** uç noktasında kabul edilir; yani bir hesabın kendi verilerini oluşturan, okuyan, güncelleyen veya silen her çağrıda kullanılabilir. Uygulamada, bir alt hesabın tüm kurulumunu ajans anahtarınızla sağlayabilir ve çalıştırabilirsiniz:

- **Yapay zeka kurulumu** — kampanyalar, temsilciler, SSS'ler, bilgi tabanı kaynakları (web sitesi tarama **ve** belge yükleme), bilgi tabanı grupları, yayınlar, özel işlevler, MCP sunucuları
- **Kişiler ve CRM** — kişiler (içe aktarma dahil), listeler, etiketler, görevler, fırsatlar, randevular, etkinlikler
- **Kanallar ve numaralar** — WhatsApp / WhatsApp Web / Telegram / Instagram ve Messenger / LINE bağlama, telefon numarası arama / satın alma / yönetme, WhatsApp şablonları, kanal yönlendirme
- **Mesajlaşma ve içerik** — mesaj gönderme, sohbet oturumları, sohbet dışa aktarımları, günlük özetler
- **Ayarlar ve entegrasyonlar** — web kancaları, sohbet penceresi yapılandırması, beyaz etiket (white-label) yapılandırması, BYOK SMS ve diğer hesap ayarları, analizler

Bunların her birinde parametre **isteğe bağlıdır** — parametreyi belirtmezseniz çağrı kendi ajans hesabınız üzerinde işlem yapar, böylece tek bir entegrasyon her ikisi için de kullanılabilir. Krediler ve kullanım her zaman hedeflediğiniz hesaptan düşülür: bir alt hesabın kampanyaları, mesajları, etiketleri ve numaraları için yapılan ücretlendirmeler **alt hesabın** bakiyesine yansır.

### Geçerli OLMADIĞI durumlar

Birkaç uç nokta ajans düzeyindedir veya doğrudan kendine yöneliktir ve `sub_account_id` parametresini dikkate almaz:

- **Alt hesapların yönetimi** — SubAccounts uç noktaları (alt hesap oluşturma / listeleme / güncelleme) ve BYOK harcama limiti uç noktası, alt hesabı kendi URL yolunda zaten belirtir. [Fiyatlandırma ve politika uç noktaları](#set-per-client-ai-pricing-and-policy) ve [sohbet izleme uç noktaları](#read-a-sub-accounts-conversations) da aynı modeli izler.
- **Bir Temsilciyi hesaplar arasında kopyalama** — `POST /v1/subaccounts/agents/copy`, hedefi `targetUserId` olarak alarak her iki hesabı da kendi içinde belirtir. Aşağıdaki [çalışma örneğine](#worked-example-ship-a-template-agent-into-every-new-client) bakın. (Daha eski olan `POST /v1/subaccounts/campaigns/copy` aynı şekilde çalışır ancak [Campaigns API](../api/campaigns.md)'nin geri kalanıyla birlikte kullanımdan kaldırılmıştır.)
- **Kredileri ayarlama ve ajans genelindeki iki özet** — [`POST /v1/subaccounts/credits`](#grant-or-deduct-credits-directly), alt hesabı bunun yerine `email` ile tanımlar; [`GET /v1/subaccounts/credit-usage`](#read-credit-usage-and-campaign-health-across-your-book) ve `GET /v1/subaccounts/campaign-status` tüm alt hesaplar hakkında aynı anda raporlama yapar, bu nedenle hedeflenecek tek bir hesap yoktur.
- **Ajansınızın kendi hesabı** — API anahtarı yönetimi, ajans kullanım raporlama, ekip yönetimi ve [fiyatlandırma kademeleriniz](#manage-your-pricing-tiers-over-the-api) her zaman ajans hesabınız üzerinde işlem yapar.
- **Gelen mesaj web kancaları** — harici sistemlerin *içeriye* gönderim yaptığı uç noktalar, bunları yapılandıran kimlik bilgilerine sahip hesaba bağlıdır, bu nedenle yönlendirilecek bir şey yoktur.

> Her uç noktanın hangi parametreleri kabul ettiğine dair her zaman güncel ve makine tarafından okunabilir liste, kontrol panelinizdeki API referansında (**Ayarlar → Entegrasyonlar → API Anahtarı**) ve `GET /v1/docs/openapi.yaml` adresindeki OpenAPI spesifikasyonunda yer alır. API değişikliklerini sık sık yayınlıyoruz; bunları temel doğruluk kaynağı olarak kabul edin.

::: master-only
<figure><img src="../.gitbook/assets/v2-api-access-key-section.png" alt="Maskelenmiş anahtar ve Yeniden Oluştur denetimi içeren API Anahtarı ayarları sayfası"><figcaption><p>Ayarlar → Entegrasyonlar → API Anahtarı — ajansınızın anahtarı, tam API referansına giden bağlantıyla birlikte burada bulunur.</p></figcaption></figure>
:::

***

## Çalışma örneği: bir alt hesap için Instagram ve Messenger bağlama

Instagram ve Messenger bağlama işlemi tarayıcı tabanlı bir akıştır. İşlemi API ile başlatır, döndürülen onay URL'sini müşteriye verir (veya onlar için açar), tarayıcılarında yetkilendirme yapmalarını beklersiniz, ardından bağlanacak sayfayı seçersiniz; tüm bunları `sub_account_id` ile alt hesaplarını hedefleyerek yaparsınız.

### 1. Adım — Bağlantıyı başlatma

Bağlantı uç noktasını, gövdede müşterinin `sub_account_id` değeri ile çağırın. Burada hiçbir kimlik bilgisi gönderilmez; platform, müşterinin bir tarayıcıda açması gereken bir onay URL'si ve tek kullanımlık bir ilişkilendirme belirteci döndürür.

**cURL**

```bash
curl -X POST "https://api.dmchamp.com/v1/channels/meta/connect?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sub_account_id": "abc123def456"
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.dmchamp.com/v1/channels/meta/connect", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    sub_account_id: "abc123def456",
  }),
});

const data = await res.json();
// data.oauth_url -> open this in the client's browser
```

**Python**

```python
import requests

res = requests.post(
    "https://api.dmchamp.com/v1/channels/meta/connect",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "sub_account_id": "abc123def456",
    },
)

data = res.json()
# data["oauth_url"] -> open this in the client's browser
```

**Yanıt:**

```json
{
  "success": true,
  "oauth_url": "https://www.facebook.com/v21.0/dialog/oauth?client_id=...&state=...",
  "state_token": "8sFq2yV0kQ7m4n1pZr3tWb6cXe9hJl2aD5gK7uN0oI",
  "expires_at": "2026-06-10T12:30:00.000Z"
}
```

Yetkilendirme için müşteriyi bir tarayıcıda `oauth_url` adresine yönlendirin. `state_token` değeri bu girişimi ilişkilendirir ve kısa ömürlü bir gizli bilgidir; günlüğe kaydetmeyin. Girişim `expires_at` tarihinde sona erer; süre dolarsa yeniden başlatın.

### 2. Adım — Sayfalar yüklenene kadar yoklama (polling) yapma

İstemci yetkilendirme yaptıktan sonra, bağlanabilir sayfalar görünene kadar durum uç noktasını (aynı `sub_account_id` ile, bu sefer bir sorgu parametresi olarak) yoklayın.

**cURL**

```bash
curl "https://api.dmchamp.com/v1/channels/meta/status?apiKey=YOUR_API_KEY&sub_account_id=abc123def456"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.dmchamp.com/v1/channels/meta/status?sub_account_id=abc123def456",
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);

const data = await res.json();
// Wait until data.status === "pages_loaded", then read data.pages
```

**Python**

```python
import requests

res = requests.get(
    "https://api.dmchamp.com/v1/channels/meta/status",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"sub_account_id": "abc123def456"},
)

data = res.json()
# Wait until data["status"] == "pages_loaded", then read data["pages"]
```

**Yanıt:**

```json
{
  "success": true,
  "status": "pages_loaded",
  "pages": [
    {
      "id": "1098765432101234",
      "name": "Acme Studio",
      "category": "Hair Salon",
      "instagram_business_account": {
        "id": "17841400000000000",
        "username": "acme.studio"
      }
    }
  ],
  "selected_page": null
}
```

`status` alanı `pending` → `token_received` → `pages_loaded` → `connected` boyunca ilerler. Bir sayfa seçmeden önce `pages_loaded` için bekleyin. İlerleme yerine iki terminal hata durumu da görünebilir: `failed` ve `expired` (istemci onayı reddetti veya durum belirtecinin ~30 dakikalık süresi doldu) — bunlardan biri gerçekleştiğinde bir `reason` alanı dahil edilir. Bunlardan birini görürseniz yoklamayı durdurun ve 1. Adımda yeniden başlatın; `pending` üzerinde sonsuza kadar beklemeyin. Sayfa erişim belirteçleri asla döndürülmez.

### Adım 3 — Bağlanacak sayfayı seçin

Adım 2'deki sayfa kimliklerinden birini seçin. Bir sayfa seçmek, o sayfa için hem Instagram hem de Messenger'ı bağlar. Gövdeye tekrar `sub_account_id` ekleyin.

**cURL**

```bash
curl -X POST "https://api.dmchamp.com/v1/channels/meta/select-page?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "page_id": "1098765432101234",
    "sub_account_id": "abc123def456"
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.dmchamp.com/v1/channels/meta/select-page", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    page_id: "1098765432101234",
    sub_account_id: "abc123def456",
  }),
});

const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.dmchamp.com/v1/channels/meta/select-page",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "page_id": "1098765432101234",
        "sub_account_id": "abc123def456",
    },
)

data = res.json()
```

**Yanıt:**

```json
{
  "success": true,
  "page_id": "1098765432101234",
  "instagram_business_account_id": "17841400000000000"
}
```

İşte bu kadar; Instagram ve Messenger artık istemcinin alt hesabına bağlandı. Siz sadece `page_id` değerini sağladınız; temel kimlik bilgisi sunucuda çözümlenir ve entegrasyonunuz üzerinden asla geçmez.

***

## Çalışma örneği: bir alt hesap için numara satın alma

Numara satın alma işlemi de aynı şekilde çalışır: sorguda `sub_account_id` ile arama yapın, ardından gövdede aynı değerle satın alma işlemini gerçekleştirin. Krediler **alt hesabın** bakiyesinden düşülür ve numara alt hesap üzerinde tahsis edilir.

**Arama (cURL):**

```bash
curl "https://api.dmchamp.com/v1/phone-numbers/available?apiKey=YOUR_API_KEY&country_code=US&sub_account_id=abc123def456"
```

**Satın Alma (JavaScript):**

```javascript
const res = await fetch("https://api.dmchamp.com/v1/phone-numbers", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    phone_number: "+14155551234",
    country_code: "US",
    display_name: "Support line",
    sub_account_id: "abc123def456",
  }),
});

const data = await res.json();
```

**Satın Alma (Python):**

```python
import requests

res = requests.post(
    "https://api.dmchamp.com/v1/phone-numbers",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "phone_number": "+14155551234",
        "country_code": "US",
        "display_name": "Support line",
        "sub_account_id": "abc123def456",
    },
)

data = res.json()
```

**Yanıt:**

```json
{
  "success": true,
  "phone_number": "+14155551234",
  "channel": "whatsapp",
  "whatsapp_status": "PURCHASED",
  "outgoing_status": "PURCHASED",
  "status": "PURCHASED",
  "purchase_credits": 11.5,
  "monthly_credits": 11.5
}
```

Numara `PURCHASED` durumunda sağlanır ve WhatsApp gönderen kaydı arka planda devam eder. Göndermeden önce durum `ONLINE` seviyesine ulaşana kadar `GET /v1/phone-numbers/{phoneNumber}/status?sub_account_id=abc123def456` öğesini yoklayın.

***

## Çalışma örneği: bir şablon Temsilciyi her yeni müşteriye gönderin

Genel ajans modeli, ajans hesabınızda her müşterinin başlamasını istediğiniz şekilde ayarlanmış bir ana Temsilci tutmak ve sağlama sırasında her yeni alt hesaba bunun bir kopyasını damgalamaktır. Bu üç çağrıdan oluşur ve sonrasında hiçbir şeyin tekrarlanmasına gerek yoktur: kopya, siz değiştirene kadar ayarlarını korur.

### Adım 1 — Temsilciyi kopyalayın

`POST /v1/subaccounts/agents/copy`

```bash
curl -X POST "https://api.dmchamp.com/v1/subaccounts/agents/copy?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agentId": "YOUR_TEMPLATE_AGENT_ID",
    "targetUserId": "abc123def456",
    "newName": "Inbound Instagram Leads",
    "copyFaqs": true
  }'
```

Yanıt, yeni Temsilcinin kimliğini `data.agent_id` adresinde taşır. SSS'ler, bilgi tabanı ve medya kütüphanesi birlikte gelir; kaynak hesabın WhatsApp şablonları, bağlı sosyal medya gönderileri ve kişileri kasıtlı olarak aktarılmaz. Tam alan listesi [AI Agents API](../api/agents.md#copy-an-agent-into-a-sub-account-agencies) içindedir.

Bu uç noktanın `sub_account_id` yerine `targetUserId` aldığını unutmayın; her iki hesabı da kendi içinde belirtir. Aşağıdaki iki çağrı normal `sub_account_id` parametresini kullanır.

### Adım 2 — Açın

Kopya her zaman duraklatılmış olarak gelir, bu nedenle siz söyleyene kadar kimseye mesaj gönderemez. Bu aynı zamanda müşteriyi dahil etmek istediğiniz yapay zeka kademesini sabitlemek için de doğru andır; orada kalır, bu nedenle bir program dahilinde tekrar uygulamaya gerek yoktur.

```bash
curl -X PATCH "https://api.dmchamp.com/v1/agents/NEW_AGENT_ID/active?apiKey=YOUR_API_KEY&sub_account_id=abc123def456" \
  -H "Content-Type: application/json" \
  -d '{ "active": true }'

curl -X PUT "https://api.dmchamp.com/v1/agents/NEW_AGENT_ID?apiKey=YOUR_API_KEY&sub_account_id=abc123def456" \
  -H "Content-Type: application/json" \
  -d '{ "anthropic_model": "max" }'
```

Müşterinin daha sonra kademeyi değiştirmesini durdurmak için, değeri tekrar göndermek yerine alt hesap üzerinde [izin verilen kademeleri kilitleyin](#set-per-client-ai-pricing-and-policy).

### 3. Adım — Müşterinin kanallarını ona yönlendirin

Kopya herhangi bir yönlendirme olmadan gelir, bu nedenle siz onu müşterinin bağladığı kanallarda yanıtlayıcı yapana kadar hiçbir şey ona ulaşmaz. Kanal başına bir çağrı:

```bash
curl -X PUT "https://api.dmchamp.com/v1/entry-points/channel-defaults?apiKey=YOUR_API_KEY&sub_account_id=abc123def456" \
  -H "Content-Type: application/json" \
  -d '{ "channel": "instagram", "agent_id": "NEW_AGENT_ID" }'
```

Buradan itibaren, o kanaldaki bilinmeyen bir kişiden gelen ilk mesaj, kopyalanan Temsilci tarafından otomatik olarak alınır. Diğer kanallar ve numara bazlı yönlendirme için [Bir kanalı bir Temsilciye yönlendirme](../api/entry-points.md#point-a-channel-at-an-agent) bölümüne bakın.

> **Alt hesabı oluştururken müşterinin saat dilimini ayarlayın.** `POST /v1/subaccounts` üzerinde `time_zone_id` değerini iletin. Kampanya aktif saatleri, alt hesabın kendi saat dilimine göre değerlendirilir; bu nedenle saat dilimi belirtilmeden oluşturulan bir müşterinin zamanlaması UTC'ye göre okunur — bu da asistanın yanıt vermesine izin verilen zamanı sessizce kaydırır.

***

## Kendiniz yapılandırdığınız bir müşteri için kurulum sihirbazını atlayın

`POST /v1/subaccounts`

Varsayılan olarak, yeni bir alt hesap sahibi ilk kez oturum açtığında, rehberli Kurulum Sihirbazı ile karşılanır. Sizin için yapılmış (done-for-you) müşteriler için — yani kampanyayı oluşturup müşteri oturum açmadan önce kanalları bağladığınız durumlar — hesabı oluştururken `guided_onboarding: false` değerini iletin. Bunun yerine doğrudan kontrol paneline yönlendirilirler ve **Kurulum Sihirbazı** girişi kenar çubuklarından gizlenir.

```bash
curl -X POST "https://api.dmchamp.com/v1/subaccounts" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "client@example.com",
    "first_name": "Alex",
    "last_name": "Client",
    "business_name": "Client Co",
    "guided_onboarding": false,
    "usage_limits": { "monthly_credits": 500 }
  }'
```

Alanı atlayın (veya `true` gönderin); sihirbaz her zamanki gibi davranacaktır, bu nedenle mevcut entegrasyonlarda herhangi bir değişiklik yapılmasına gerek yoktur. Bir müşteriye sihirbazı daha sonra geri vermek isterseniz, `PUT /v1/subaccounts/{subAccountUid}/menu-visibility` (aşağıda) ile `guided_onboarding` öğesini tekrar gösterin — menü görünürlüğü sihirbazın erişilebilir olup olmadığını kontrol eder, `guided_onboarding` ise yalnızca ilk girişteki yönlendirmeyi kontrol eder.

***

## Bir müşteri için Görevleri, Günlük Özetleri veya Medya Kitaplığını kapatma

`POST /v1/subaccounts`

Siz aksi belirtmedikçe bu üç özellik her yeni müşteri için açıktır ve bu kılavuzdaki diğer tüm özelliklerden farklı davranırlar: bunlar **isteğe bağlı (opt-out)** özelliklerdir, isteğe bağlı katılım (opt-in) değildirler. Bunları `features` dışında bırakmak tek başına yeterli değildir, çünkü eski bir entegrasyonun `features` listesi bunlardan hiç bahsetmemiş olabilir; bu yüzden "ajans bunu kapattı" ile "bu liste seçenek mevcut olmadan önce yazıldı" durumlarını ayırt edemeyiz.

Bu yüzden `feature_settings` ile bunu açıkça belirtin:

```bash
curl -X POST "https://api.dmchamp.com/v1/subaccounts" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "client@example.com",
    "first_name": "Alex",
    "last_name": "Client",
    "business_name": "Client Co",
    "feature_settings": {
      "tasks": false,
      "daily_summaries": false,
      "ai_media_library": true
    }
  }'
```

Her anahtar isteğe bağlıdır; dışarıda bıraktığınız her şey açık kalır. `tasks: false` ile yapay zeka o müşteri için görev oluşturmayı durdurur ve hiçbir "Yeni Görev Oluşturuldu" e-postası gönderilmez; `daily_summaries: false` ile gece özeti asla oluşturulmaz veya e-posta ile gönderilmez.

`feature_settings`, oluşturma sırasında bu üçünü kapatan tek şeydir. Bunları `features` dışında bırakmak, listenizin geri kalanı nasıl görünürse görünsün tek başına hiçbir işe yaramaz; bu kasıtlıdır, böylece eski bir entegrasyon sessizce bu üç özelliği birden kaybetmez.

Daha sonra bunlardan herhangi birini değiştirmek için tam `features` listesini `PUT /v1/subaccounts/{subAccountUid}/features` adresine gönderin; orada, listede bulunması bir özelliği açar, bulunmaması ise kapatır.

***

## Müşterilerinizin alt hesaplarına otomatik giriş yapın (SSO)

`POST /v1/subaccounts/{subAccountUid}/sso-link`

Ajans API anahtarınızla yapacağınız tek bir çağrı, müşteriyi doğrudan kendi alt hesabına giriş yaptıran, açılmaya hazır bir URL döndürür; giriş ekranı yok, parola adımı yok, üzerine bir şey inşa etmenize gerek yok. Bunu yeni bir sekmede, bir yönlendirme ile veya kendi ürününüzün içinde bir iframe olarak açın.

| Alan | Gerekli | Açıklama |
|---|---|---|
| `redirect` | Hayır | İstemcinin ulaşmasını istediğiniz uygulama içi sayfa, örn. `"/chats"` veya `"/agents"`. Yanıtta `deep_link_url` olarak döndürülür. |
| `app_base_url` | Hayır | Bağlantı için kontrol paneli ana bilgisayarı. Varsayılan olarak beyaz etiketli uygulama alan adınızdır (veya hiç yoksa platform alan adı). `https` olmalıdır. |

**cURL**

```bash
curl -X POST "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/sso-link" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "redirect": "/chats" }'
```

**Yanıt**

```json
{
  "success": true,
  "url": "https://app.yourdomain.com/auth?redirect=%2Fchats#token=eyJhbGciOi…",
  "deep_link_url": "https://app.yourdomain.com/chats",
  "expires_at": "2026-07-22T15:04:05.000Z",
  "sub_account_uid": "SUB_ACCOUNT_UID"
}
```

Nasıl verimli kullanılır:

- **Tek adım.** `url` açılması, istemcinin oturumunu açar ve onları doğrudan kontrol panelinin `redirect` sayfasına yönlendirir; giriş ekranı veya ara sayfa yoktur. `deep_link_url`, giriş yaptıktan sonra açıkça bir çerçevede gezinmeyi tercih eden entegratörler için aynı hedefi belirtir; oturum mevcut olduğunda, herhangi bir kontrol paneli yolu o tarayıcı bağlamında çalışır.
- **İsteğe bağlı oluşturun, hemen açın.** Bağlantı bir giriş kimlik bilgisi içerir ve yaklaşık bir saat sonra sona erer. Bunu, istemci tıkladığı anda sunucu tarafında talep edin ve asla saklamayın veya e-posta ile göndermeyin.
- Giriş belirteci, tarayıcıların asla sunuculara göndermediği URL parçasında (`#…`) taşınır ve tüketildiği anda adres çubuğundan kaldırılır.
- **Yalnızca kendi alt hesaplarınız.** Uç nokta, ajansınızın sahip olmadığı hiçbir hesabı kabul etmez.
- Süresi dolmuş bir bağlantı, yeniden deneme yoluyla net bir hata gösterir; yeni bir tane oluşturun.

***

## Bir alt hesapta gezinme öğelerini gizleyin

`PUT /v1/subaccounts/{subAccountUid}/menu-visibility`

Bir alt hesabın hangi kenar çubuğu ve ayar öğelerini göreceğini kontrol eder; kontrol panelini yerleştirdiğinizde ve yalnızca ürününüzün kapsamadığı yüzeylerin görünmesini istediğinizde kullanışlıdır. Listelenmeyen her şey görünür kalır; her şeyi görünür duruma getirmek için `menuVisibility` değerinin tamamı olarak `null` gönderin. Bir öğeyi gizlemek, menü girişini gizler; kesin kısıtlama için bunu alt hesaba verdiğiniz özelliklerle eşleştirin.

**cURL**

```bash
curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/menu-visibility" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "menuVisibility": {
      "side_nav": { "Dashboard": false, "Campaigns": false, "Automations": false },
      "settings_nav": { "team": false }
    }
  }'
```

**Yanıt**

```json
{
  "success": true,
  "data": {
    "subAccountUid": "SUB_ACCOUNT_UID",
    "menuVisibility": {
      "side_nav": { "Dashboard": false, "Campaigns": false, "Automations": false },
      "settings_nav": { "team": false }
    }
  }
}
```

`side_nav`, kenar çubuğu öğe adlarıyla eşleşen şu 13 anahtarı kabul eder: `Dashboard`, `DailySummaries`, `Chats`, `Contacts`, `Deals`, `Tasks`, `Automations`, `Campaigns`, `Appointments`, `Settings`, `Help`, `CreditsCounter` (kenar çubuğunda gösterilen kredi bakiyesi) ve `guided_onboarding` (Kurulum Sihirbazı). Üç anahtar daha — `AiInsights`, `Sub Accounts` ve `Agency Reselling` — kabul edilir ancak hiçbir işlevleri yoktur: bunlar yalnızca kullanımdan kaldırılan klasik kontrol paneli için geçerliydi, bu nedenle bunları ayarlamanın alt hesaplarınız üzerinde hiçbir etkisi yoktur. Eksik anahtarlar görünür anlamına gelir; alt hesapta kendiniz oturum açtığınızda, gizli öğeler geçici olarak gösterilir, böylece her zaman ayarları geri değiştirebilirsiniz.

Bir sayfayı menüden gizlemek, ona erişim izni vermez. `Automations`, alt hesapta `automations` özelliğinin tanımlanmış olmasını gerektirir; anahtarı `true` olarak ayarlasanız bile bu özellik olmadan sayfa görünmeyecektir. `Tasks` ve `DailySummaries` ise tam tersi şekilde çalışır: siz kapatmadığınız sürece her müşteri için açıktırlar (bkz. [Bir müşteri için Görevleri, Günlük Özetleri veya Medya Kitaplığını kapatma](#turn-tasks-daily-summaries-or-the-media-library-off-for-a-client)).

***

## Bir istemcinin hangi kanal türlerine bağlanabileceğini seçin

`PUT /v1/subaccounts/{subAccountUid}/features`

Bir plan kademesinde gördüğünüz **Kanal Türleri** anahtarları sıradan özellik kimlikleridir (feature ID), bu nedenle bunları kontrol paneli yerine API üzerinden istemci bazında ayarlayabilirsiniz. Bu, alt hesabı kendi URL'sinde adlandıran uç noktalardan biridir, bu yüzden herhangi bir `sub_account_id` almaz.

| Özellik Kimliği | Kanal |
|---|---|
| `channel_chat_widget` | Web Sitesi Sohbet Penceresi |
| `channel_whatsapp_api` | WhatsApp Business API |
| `channel_whatsapp_web` | WhatsApp Web (QR ile bağlanan numara) |
| `channel_instagram` | Instagram |
| `channel_messenger` | Facebook Messenger |
| `channel_telegram` | Telegram |
| `channel_line` | LINE |
| `channel_viber` | Viber |
| `channel_email` | E-posta posta kutusu |
| `channel_sms` | SMS |
| `channel_imessage` | iMessage |

```bash
curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/features" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "features": [
      "channels_3",
      "channel_chat_widget",
      "channel_whatsapp_web",
      "channel_instagram",
      "image_understanding",
      "contact_tagging",
      "incoming_campaigns",
      "webhooks"
    ]
  }'
```

Doğru yapılması gereken üç şey:

- **Çağrı, tüm özellik listesinin yerini alır.** Sadece değiştirdiklerinizi değil, istemcinin sahip olması gereken her özelliği gönderin. Aynı kimlikler, hesabı oluştururken `POST /v1/subaccounts` üzerindeki `features` ile aynı şekilde çalışır.
- **Kanal türleri ve kanal sayısı ayrı kısıtlamalardır ve her ikisi de geçerlidir.** `channels_1` / `channels_3` / `channels_unlimited` *kaç tane* bağlantı olacağını kontrol eder; `channel_*` kimlikleri ise *hangi türlerin* olacağını kontrol eder. Yukarıdaki örnek "en fazla 3 bağlantı ve sadece Sohbet Penceresi, WhatsApp Web veya Instagram" anlamına gelir.
- **Hiç `channel_*` kimliği göndermemek, kanal kısıtlaması olmadığı anlamına gelir.** Bu orijinal davranıştır ve bu özelliğin kullanıma sunulmasıyla mevcut istemcilerin etkilenmemesinin nedeni budur. Bir veya daha fazla kimlik gönderdiğinizde, diğer her şey istemcinin Kanallar sayfasında "Bağlan" düğmesi yerine bir yükseltme notuyla kilitli olarak görünür. İstemcinin halihazırda bağladığı kanallar çalışmaya devam eder.

> Kanal listesini bir **plan kademesi** üzerinde ayarlamak, böylece o kademeyi satın alan her istemcinin bunu devralmasını sağlamak, kontrol panelinizdeki ajans planı ayarları altında yapılır. Bu uç nokta, ayarı belirli bir alt hesap üzerinde yapar.

***

## Bir müşteri için tam bir ekip üyesi sınırı belirleyin

`PUT /v1/subaccounts/{subAccountUid}/limits`

`team_seats_*` özellikleri yalnızca önceden ayarlanmış kademeli adımlar (3 / 5 / 10 / sınırsız) sunar. Bir müşteriye **tam** bir ekip koltuğu sayısı — 2, 7, 15 veya herhangi bir sayı — vermek için bunun yerine `usage_limits.team_seats_limit` ayarını yapın. Bu ayar, ön ayarlara göre önceliklidir ve platform bunu her davet, doğrudan ekleme ve davet kabulünde zorunlu tutar: sınıra ulaşıldığında, daha fazla davet sunucu tarafında reddedilir.

- Pozitif bir tam sayı, tam sınırı ifade eder.
- `0`, ekip üyelerinin **dahil edilmediği** anlamına gelir; müşteri kimseyi davet edemez.
- `-1`, sınırsız anlamına gelir.
- `null`, özel sınırı temizler ve özellik listesindeki hangi `team_seats_*` ön ayarı varsa ona geri döner.

Sınırı düşürmek mevcut ekip üyelerini asla kaldırmaz; yalnızca yenilerinin eklenmesini durdurur.

```bash
curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/limits" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "usageLimits": { "team_seats_limit": 7 }
  }'
```

Bunu oluşturma sırasında da ayarlayabilirsiniz: `POST /v1/subaccounts`, aynı semantiklerle `usage_limits.team_seats_limit` kabul eder. Mevcut değeri okumak için, `GET /v1/subaccounts?email=...` ile alt hesabı getirin ve `usage_limits.team_seats_limit` değerine bakın (yok/`null` = ön ayarların karar verdiği anlamına gelir). Aynı uç nokta ayrıca `credits`, `monthly_credits`, `roll_over_to_next_month`, `rollover_cap_months`, `rollover_expiry_days` ve `byok_monthly_limit_usd` değerlerini de günceller — yalnızca değiştirmek istediğiniz anahtarları gönderin.

**Bunun SaaS planı kullanıcı sınırlarıyla etkileşimi.** SaaS planlarınız kendi kullanıcı kontenjanlarına sahip olabilir (plan düzenleyicide ayarlanır — bkz. [Bir plandaki ekip kullanıcıları](agency-accounts.md#step-3--set-up-pricing-tiers)) ve bu kontenjanlar bir müşteri abone olduğunda otomatik olarak uygulanır. Bu uç nokta aracılığıyla belirlediğiniz bir sınır, **manuel** bir tanımlama olarak sayılır: bir plan satın almak, bu sınırı planın kendi kullanıcı kontenjanıyla değiştirir (bu satın alma işlemi açık bir plan tercihidir), ancak katılımsız aylık **yenilemeler manuel bir sınırı asla üzerine yazmaz** — bu nedenle bir müşteriye tanıdığınız tek seferlik bir istisna, faturalandırma döngüsü boyunca geçerliliğini korur. Manuel sınırı `null` ile temizlemek, bir sonraki yenilemede kontrolü tekrar plana devreder.

**Bir müşterinin yenilemeler arasında neleri taşıyabileceğini sınırlayın.** `roll_over_to_next_month` yanında iki `usage_limits` anahtarı daha bulunur. Her ikisi de oluşturma sırasında `POST /v1/subaccounts` tarafından kabul edilir ve `null` her ikisini de temizler.

| Anahtar | Ne işe yarar |
|---|---|
| `rollover_cap_months` | Müşterinin elinde tutabileceği aylık ödenek miktarı. 0 ile 120 arasında bir sayı, kesirlere izin verilir (`0.5` = yarım ay). Her yenilemede, kullanılmayan bakiye, yeni krediler eklenmeden önce bu yenilemenin sağladığı ödeneğin en fazla bu kadar katına indirilir; `0` hiçbir şeyi devretmez. |
| `rollover_expiry_days` | 1 ile 3650 arasında tam bir gün sayısı. Bu süre boyunca kullanılmayan krediler, bu yaşa ulaştıktan sonraki ilk yenilemede silinir. Harcama her zaman en eski kredilerden düşülür, bu nedenle ödeneğini her ay harcayan bir müşteri asla kredi kaybetmez. |

Ayarlanmazsa, her ikisi de müşterinin planına geri döner; buraya gönderilen bir değer, planın değerine üstün gelir. Yalnızca yinelenen krediler (aylık ödenek ve plan kredileri) bunlara tabidir: eklemeler (top-up), otomatik şarjlar ve tek seferlik eklemeler asla sınırlandırılmaz veya süresi dolmaz. Her kırpma, müşterinin kredi geçmişine **Devir Sınırı Kredi Düzeltmesi** veya **Süresi Dolan Krediler Kredi Düzeltmesi** olarak yazılır ve asla kullanım olarak sayılmaz. Plan düzeyindeki eşdeğerleri, bir fiyatlandırma katmanındaki `rollover_cap_months` ve `rollover_expiry_days` değerleridir — bkz. [Bir katmandaki alanlar](#the-fields-on-a-tier) ve [Nelerin devredileceğini sınırlama](sub-accounts.md#capping-what-rolls-over).

***

## Müşteri bazlı yapay zeka fiyatlandırmasını ve politikasını ayarlayın

`PUT /v1/subaccounts/{subAccountUid}/max-tier` · `/ai-tiers` · `/max-rate` · `/action-pricing` · `/insider-rate` · `/locked-bot-fields` · `/notifications` · `/zero-credit-reply`

Yukarıdaki `/limits`, `/features` ve `/menu-visibility`'nin yanı sıra, müşteri başına sekiz anahtar daha. Her biri URL'de alt hesabın uid'sini alır (gövde/sorgu parametresi `sub_account_id` yoktur — hedef zaten yolda belirtilmiştir) ve aynı şekilde kapsamlandırılır: ajans anahtarınız ve alt hesabın ajansınıza ait olması gerekir.

**Bir müşterinin hangi yapay zeka modellerini kullanabileceği**

```bash
curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/max-tier" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": true }'
```

`{ "enabled": boolean }`, müşteriyi Max AI kademesine (platformun liste fiyatından altyapımız) dahil eder (veya çıkarır). Bunu bir BYOK müşterisi için açmak, yapay zeka maliyetlerini "kendi anahtarımda ücretsiz" durumundan "kredi havuzumdan tahsil edilir" durumuna getirir, bu nedenle ajans genelindeki bir varsayılan yerine müşteri bazlı bilinçli bir karardır.

Bir müşterinin kampanyalarının ve Temsilcilerinin hangi kademelerden seçim yapabileceğini (sadece Max'i sınırlamak yerine) tamamen kısıtlamak için `ai-tiers` kullanın:

```bash
curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/ai-tiers" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "allowed_ai_tiers": ["standard", "economy"] }'
```

`allowed_ai_tiers`, `standard`, `economy`, `max`, `mini`'ten alınan bir dizidir — müşterinin izin listesinin YERİNİ ALIR. Kısıtlamayı kaldırmak ve herhangi bir kademeyi seçmelerine izin vermek için `null` (veya `[]`) gönderin. Bu önemlidir çünkü kendi yapay zeka kademesini seçen bir alt hesap **sizin** kredi havuzunuzdan harcama yapar, bu nedenle bir bayi müşterisinin faturanızı ne kadar kabartabileceğini belirlemek için kullanılan bir kaldıraçtır.

**Müşterinin kredisi bittiğinde verilecek bir bekleme yanıtı**

```bash
curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/zero-credit-reply" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": true, "message": "Thanks for your message, we will get back to you shortly." }'
```

Müşterinin bakiyesi (veya havuzunuz) boşaldığında, yapay zeka yanıt veremez ve kişi hiçbir şey duymaz. `enabled: true` ile, kesinti sırasında yazan her kişi bir kez `message` alır (maksimum 500 karakter, her kanalda olduğu gibi gönderilir) ve krediler geri geldiğinde yapay zeka bu konuşmaları gerçekten yanıtlar. `enabled: false`, kaydedilen metni daha sonrası için saklar; `enabled: false` ve `message` olmadan ayar kaldırılır. Alt hesabın Düzenle modalındaki **Kredi bittiğinde bekleme yanıtı** ile aynı anahtardır — bkz. [Müşterinin kredisi bittiğinde bir bekleme yanıtı](sub-accounts.md#a-holding-reply-while-a-client-is-out-of-credits).

**Bir müşterinin yapay zeka eylemi başına ödediği ücret ve WhatsApp ücreti farkı**

Müşteriye yönelik oranınızı belirlemenin en basitten en ayrıntılıya iki yolu:

```bash
curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/max-rate" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "rate": 0.35 }'
```

`rate`, alt hesabın KENDİ bakiyesinin Max-model yapay zeka eylemi başına yaktığı kredi cinsinden fiyattır — havuzunuzun gerçekte ödediğinin üzerine eklediğiniz müşteri odaklı fark. `null`, geçersiz kılmayı platform liste fiyatına geri döndürür. Oran, en az bir Max eyleminin havuzunuza maliyeti kadar olmalı (böylece bir müşteriyi asla maliyetinizin altında fiyatlandıramazsınız) ve 10 krediden fazla olmamalıdır; bu aralığın dışındaki bir istek, hata mesajında hesaplanan taban fiyat ile reddedilir.

Tek bir sabit Max oranı yerine eylem türüne göre fiyatlandırma için `action-pricing` kullanın:

```bash
curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/action-pricing" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "actionPricing": {
      "AI_MESSAGE": 0.6,
      "CHAT_SUMMARY": 0.15,
      "wa_carrier_multiplier": null
    }
  }'
```

`actionPricing`, müşterinin mevcut haritası üzerine bir BİRLEŞTİRMEDİR — belirtmediğiniz bir anahtar olduğu gibi bırakılır ve `null` bu anahtarı varsayılan değerine döndürür. Tanınan anahtarlar:

| Anahtar | Fiyatlar |
|---|---|
| `AI_MESSAGE` | Bir yapay zeka yanıtı |
| `AI_TOOL_USE` | Bir yapay zeka araç çağrısı |
| `EVALUATION_CALL` | Bir sohbet değerlendirme geçişi |
| `INTERRUPTION_HANDLING` | Yanıt sırasında kesintinin yönetilmesi |
| `CONTACT_TAG` | Yapay zeka tarafından atanan bir kişi etiketi |
| `CHAT_SUMMARY` | Bir sohbet özeti |
| `wa_carrier_multiplier` | İstemcinin ödediği yapay zeka dışı her WhatsApp ücretine uygulanan bir işaretleme çarpanı: aylık numara kirası, yönetilen hat teslimat ücretleri ve Meta/Twilio şablon geçiş maliyetleri. |

Eylem başına oranlar 0'dan büyük ve 10'a kadar bir sayı olmalıdır; `wa_carrier_multiplier` en az `1` (maliyetin altında indirim yapılamaz) ve en fazla 10 olmalıdır. Tanınmayan bir anahtar veya aralık dışı bir değer gönderilmesi, TÜM isteği reddeder ve hatalı olan her anahtarı belirtir; böylece bir yazım hatası, aslında uygulanmayan bir fiyatı sessizce kaydedemez.

[Champions Circle](https://skool.com/dm-champions) üyesiyseniz, `insider-rate` %20'lik Max/Lead Finder indirim oranınızı ajans genelinde uygulamak yerine tek bir müşteriye aktarır:

```bash
curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/insider-rate" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": true }'
```

Bunu açmak, kendi ajans hesabınızın gerçekten Circle üyeliğine sahip olmasını gerektirir; kapatmak ise hiçbir zaman gerektirmez, bu nedenle üyeliği sona ermiş bir üye her zaman bir müşterinin ayarlarını geri alabilir.

**Bir müşterinin oyun kitabının bölümlerini kilitleyin**

```bash
curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/locked-bot-fields" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "locked_bot_fields": ["instructions", "rules"] }'
```

`locked_bot_fields`, `instructions`, `goal`, `rules`, `personality`, `conclude_unless` öğelerinden oluşan bir dizidir — müşterinin kilitli listesinin YERİNİ ALIR. Kilitli bir bölüm, ALT HESAP bunu (doğrudan veya API anahtarı ile) değiştirmeye çalışırsa sunucu tarafında reddedilir; ancak siz (`sub_account_id` aracılığıyla) ve müşterinin kendi kontrol paneli yönetici görünümü her şeyi düzenlemeye devam edebilir. Her şeyin kilidini açmak için `null` (veya `[]`) gönderin. Oyun kitabının size ait olduğu ve sonuçlardan sorumlu tutulduğunuz, sizin tarafınızdan yönetilen müşteriler için kullanışlıdır.

**Müşterinin bildirim tercihlerini onlar adına ayarlayın**

```bash
curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/notifications" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "notifications": {
      "settings": {
        "credit_alerts": { "enabled": true, "channels": ["email", "in_app"] },
        "new_contacts": { "enabled": false }
      }
    }
  }'
```

`notifications`, müşterinin tüm bildirim tercihi kümesinin yerini alır (anahtar bazlı bir birleştirme değildir — alt hesabın kendi Ayarlar sayfasının kaydetme şekliyle eşleşecek şekilde tutulmasını istediğiniz her kategoriyi gönderin). `settings` altındaki her kategori `enabled` (boolean) ve `email`, `in_app`, `webhook` arasından en fazla üç `channels` kabul eder. Platform varsayılanlarına sıfırlamak için `null` gönderin.

Yedi uç noktanın tümü `{ "success": true, "data": { "subAccountUid": "...", ...the field(s) you set... } }` yanıtını verir ve öncesi/sonrası değerleriyle denetim günlüğüne kaydedilir. Yaygın hatalar: Hesabınız Ajans/Geliştirici değilse veya alt hesap yönetmeniz için size ait değilse `403`, ajans alt hesabı değilse veya bir değer aralık dışındaysa `400` hatası alınır.

***

## Aboneliğini askıya alan bir müşteriyi duraklatın

`POST /v1/subaccounts/{subAccountUid}/pause` · `POST /v1/subaccounts/{subAccountUid}/unpause`

Bir müşteri sizinle olan aboneliğini askıya aldığında, hesabını silmek yerine duraklatın: gönderdikleri her şey (giden mesajlar, yayınlar, tüm kanallardaki yapay zeka yanıtları) anında durur ve giriş yaptıklarında uygulama yerine tam ekran bir **Hesap duraklatıldı** kilidi (isteğe bağlı mesajınızla birlikte) görürler. Hiçbir şey silinmez veya bağlantısı kesilmez: temsilciler, kampanyalar, bağlı kanallar, kişiler ve sohbet geçmişi tam olarak oldukları gibi kalır, bu nedenle duraklatmayı kaldırmak müşteriyi tam olarak kaldığı yere geri getirir; yeniden kurulum yapılması gerekmez.

| Alan | Zorunlu | Açıklama |
|---|---|---|
| `message` | Hayır | Kilit ekranında müşteriye gösterilir. Varsayılan ifade için boş bırakın. |
| `reason` | Hayır | Duraklatma ile birlikte saklanan ve denetim günlüğünde yer alan ajans içi not — müşteriye asla gösterilmez. |

**cURL**

```bash
curl -X POST "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/pause" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "message": "Your account is on hold — contact us to reactivate it.", "reason": "Subscription suspended per client email" }'
```

**Yanıt**

```json
{
  "success": true,
  "data": {
    "subAccountUid": "SUB_ACCOUNT_UID",
    "paused": true,
    "level": "hard_blocked"
  }
}
```

Müşteri geri döndüğünde, `POST /v1/subaccounts/SUB_ACCOUNT_UID/unpause` (gövdesiz) kilidi kaldırır; gönderim ve yapay zeka yanıtları hemen devam eder.

Bilinmesi gerekenler:

- **Bu, kontrol panelindeki Sert engelleme (Hard blocked) düğmesiyle aynı durumdur** ([Alt Hesabı Engelleme / Duraklatma](sub-accounts.md#blocking-pausing-a-sub-account)) — API üzerinden duraklatılan bir müşteri kontrol panelinde engellenmiş olarak görünür ve bunun tersi de geçerlidir; duraklatmayı kaldırmak her iki taraftan konulan engeli de temizler. Mevcut durum, `GET /v1/subaccounts` üzerindeki `agency_block` alanından okunabilir (`"none"`, `"soft_blocked"` veya `"hard_blocked"`'in `level`'si).
- **Her iki çağrı da eş değerdir (idempotent).** Zaten duraklatılmış bir müşteriyi duraklatmak sadece mesajı, nedeni ve zaman damgasını yeniler; aktif bir müşterinin duraklatmasını kaldırmak hiçbir şeyi değiştirmez.
- **Müşteriye otomatik olarak e-posta gönderilmez** — birçok ajans beyaz etiket (white-label) kullandığından, müşteriye bildirimde bulunma işi size bırakılmıştır.
- **Kendi DM Champ faturalandırmanız etkilenmez.** Bir müşteriyi duraklatmak yalnızca sizin onlarla olan ilişkinizi etkiler.
- **Yapay zeka asistanları da bunu yapabilir**: [MCP sunucusu](../integrations/connect-ai-clients.md), bu uç noktaları `pause_subaccount` ve `unpause_subaccount` araçları olarak sunar.

***

## Doğrudan kredi verin veya düşün

`POST /v1/subaccounts/credits`

Bir alt hesabın bakiyesine tam bir kredi miktarı ekler veya çıkarır — kontrol panelindeki manuel kredi düzeltmesinin API karşılığıdır. Bu, [`PUT /v1/subaccounts/{subAccountUid}/limits`](#set-an-exact-team-member-limit-for-a-client) üzerindeki yinelenen `monthly_credits`, `roll_over_to_next_month`, `rollover_cap_months` ve `rollover_expiry_days` ayarlarından farklı, tek seferlik bir bakiye değişikliğidir.

Bu sayfada alt hesabı `sub_account_id` yerine **e-posta** ile tanımlayan tek uç nokta budur.

| Alan | Gerekli | Açıklama |
|---|---|---|
| `email` | Evet | Alt hesabın ajansınız altındaki e-posta adresi. |
| `amount` | Evet | Sıfır olmayan kredi miktarı. Pozitif değerler ekler, negatif değerler düşer. |
| `description` | Hayır | Müşterinin kredi geçmişindeki ayarlamada gösterilir. Varsayılan olarak genel bir "Ajans tarafından API aracılığıyla ayarlandı" satırı kullanılır. |

**cURL**

```bash
curl -X POST "https://api.dmchamp.com/v1/subaccounts/credits" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "email": "client@example.com", "amount": 500, "description": "Q3 bonus credits" }'
```

**Yanıt**

```json
{
  "success": true,
  "data": {
    "email": "client@example.com",
    "previous_balance": 1200,
    "adjustment": 500,
    "new_balance": 1700
  }
}
```

Bakiyeyi sıfırın altına düşürecek negatif bir `amount`, mevcut bakiyeyi ve düşmeye çalıştığınız miktarı belirten bir `400` ile reddedilir. Müşteri kendi Stripe faturalandırmasındaysa (yeniden satış modu), eklenen bir miktar aynı zamanda satın aldıkları krediler olarak sayılır, bu nedenle gerçek bir ekleme (top-up) gibi bir sonraki aylık sıfırlamalarında da varlığını korur; standart tahsisli bir müşteride ise yinelenen ödeneklerinin bir parçası olarak kabul edilir. Her iki durumda da bunlar tek seferlik eklemelerdir, bu nedenle hesapta (veya planında) ayarlanan bir devir sınırı veya son kullanma tarihi bunları asla kırpmaz — yalnızca yinelenen ödenek ve plan kredileri bunlara tabidir.

***

## Bir alt hesabın konuşmalarını okuyun

`GET /v1/subaccounts/{subAccountUid}/chats` · `GET /v1/subaccounts/{subAccountUid}/chats/{contactId}/messages`

Müşterinin hesabına giriş yapmanıza gerek kalmadan, konuşmalarının bir izleme veya destek görünümünü oluşturmanıza olanak tanır. Önce en son mesajın önizlemesiyle birlikte kişilerini listeleyin, ardından bir kişinin tüm mesaj geçmişini okuyun.

**Kişileri listele**

```bash
curl "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/chats?apiKey=YOUR_AGENCY_API_KEY&pageSize=25"
```

| Sorgu parametresi | Gerekli | Açıklama |
|---|---|---|
| `pageSize` | Hayır | Sayfa başına kişi sayısı. Varsayılan 25, maksimum 50. |
| `lastActivityAt` | Hayır | Sayfalandırma imleci — devam etmek için önceki sayfanın `lastActivityAt` değerini iletin. |
| `searchQuery` | Hayır | Kişi adına veya telefon numarasına göre filtreleyin. |

**Yanıt**

```json
{
  "success": true,
  "data": {
    "contacts": [
      {
        "contactId": "contact456",
        "firstName": "Jamie",
        "lastName": "Lee",
        "phoneNumber": "+14155551234",
        "email": "jamie@example.com",
        "channel": "whatsapp",
        "lastActivityAt": "2026-08-30T14:22:00.000Z",
        "lastMessage": { "body": "Thanks, that fixed it!", "direction": "inbound", "timestamp": "2026-08-30T14:22:00.000Z" },
        "isBotActive": true,
        "markChatClosed": false
      }
    ],
    "subAccountName": "Client Co",
    "subAccountEmail": "client@example.com",
    "hasMore": true,
    "lastActivityAt": "2026-08-30T14:22:00.000Z"
  }
}
```

Kişiler, en son etkinlikten başlayacak şekilde sıralanır. `hasMore` değeri `true` olduğu sürece `lastActivityAt` ile sayfalamaya devam edin.

**Bir kişinin mesajlarını oku**

```bash
curl "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/chats/contact456/messages?apiKey=YOUR_AGENCY_API_KEY&pageSize=30"
```

| Sorgu parametresi | Gerekli | Açıklama |
|---|---|---|
| `pageSize` | Hayır | Sayfa başına mesaj sayısı. Varsayılan 30, maksimum 100. |
| `beforeTimestamp` | Hayır | Sayfalandırma imleci — bu ISO zaman damgasından daha eski mesajları getirin. |

**Yanıt**

```json
{
  "success": true,
  "data": {
    "messages": [
      {
        "messageId": "msg789",
        "body": "Thanks, that fixed it!",
        "direction": "inbound",
        "timestamp": "2026-08-30T14:22:00.000Z",
        "status": "received",
        "channel": "whatsapp",
        "botReply": false,
        "mediaUrl": null,
        "mediaContentType": null,
        "name": "Jamie Lee",
        "role": null
      }
    ],
    "contactInfo": { "firstName": "Jamie", "lastName": "Lee", "phoneNumber": "+14155551234", "channel": "whatsapp" },
    "hasMore": false,
    "oldestTimestamp": "2026-08-30T14:22:00.000Z"
  }
}
```

Mesajlar en yeniden eskiye doğru gelir; geçmişte geriye doğru sayfalamak için `beforeTimestamp` kullanın.

***

## Portföyünüz genelindeki kredi kullanımını ve kampanya sağlığını okuyun

`GET /v1/subaccounts/credit-usage` · `GET /v1/subaccounts/campaign-status`

Her bir müşteriye tek tek tıklamak yerine kendi ajans raporlamanızı oluşturmanız için yönettiğiniz tüm alt hesaplar üzerinde iki adet gösterge paneli tarzı özet.

**Kredi kullanımı**

```bash
curl "https://api.dmchamp.com/v1/subaccounts/credit-usage?apiKey=YOUR_AGENCY_API_KEY&from=2026-08-01&to=2026-08-31"
```

| Sorgu parametresi | Gerekli | Açıklama |
|---|---|---|
| `from` / `to` | Evet | ISO tarih aralığı. |
| `subAccountId` | Hayır | Ajans genelinde bir özet için boş bırakın, alt hesap başına bir satır oluşturur. Detay moduna geçmek için dahil edin: o alt hesabın özeti artı ham, sayfalandırılmış kullanım kayıtları. |
| `limitCount` | Hayır | Yalnızca detay modu. Varsayılan 500, maksimum 2000. |
| `startAfterTimestamp` | Hayır | Yalnızca detay modu — sayfalandırma imleci. |

```json
{
  "success": true,
  "data": {
    "subAccounts": [
      {
        "subAccountId": "abc123def456",
        "subAccountName": "Client Co",
        "subAccountEmail": "client@example.com",
        "totalCreditsUsed": 842,
        "totalCostUsd": 3.15,
        "byReason": { "AI reply": 620, "Chat summary": 80 },
        "topCampaigns": [{ "campaignName": "Inbound Leads", "creditsUsed": 500 }]
      }
    ],
    "totals": { "totalCreditsUsed": 842, "totalCostUsd": 3.15, "totalRecords": 214 },
    "dateRange": { "from": "2026-08-01", "to": "2026-08-31" },
    "hasMore": false,
    "lastTimestamp": null
  }
}
```

`subAccountId` değerini ilettiğinizde yanıt, `amount`, `reason`, `campaignName`, `contactName` ve `timestamp` içeren bireysel ücretlendirmeler olan `records` verisini de taşır. Kendi kredileriniz yerine kendi BYOK anahtarı üzerinden harcama yapan bir müşterinin maliyet/token rakamları gizlenir (`costsRedacted: true`) — bu platform maliyeti telemetrisidir, bir bayi görüntüleyiciye sunulacak bir şey değildir.

**Kampanya durumu**

```bash
curl "https://api.dmchamp.com/v1/subaccounts/campaign-status?apiKey=YOUR_AGENCY_API_KEY&pageSize=20"
```

| Sorgu parametresi | Gerekli | Açıklama |
|---|---|---|
| `pageSize` | Hayır | Sayfa başına alt hesap sayısı. Varsayılan 10, maksimum 50. |
| `lastDocumentId` | Hayır | Sayfalandırma imleci. |
| `searchQuery` | Hayır | Alt hesap adına veya e-postasına göre filtrele. |

```json
{
  "success": true,
  "data": {
    "totalSubAccounts": 34,
    "subAccountsWithIssues": 3,
    "totalLiveCampaigns": 51,
    "totalPausedCampaigns": 6,
    "subAccounts": [
      {
        "userId": "abc123def456",
        "email": "client@example.com",
        "displayName": "Jamie Lee",
        "businessName": "Client Co",
        "totalCampaigns": 2,
        "liveCampaigns": 1,
        "pausedCampaigns": 1,
        "hasIssues": true,
        "issueDetails": ["1 campaign paused"],
        "lastCampaignActivity": "2026-08-29T09:00:00.000Z"
      }
    ],
    "hasMore": true,
    "lastDocumentId": "abc123def456",
    "pageSize": 20
  }
}
```

`hasIssues` / `issueDetails` bayrağı, duraklatılmış bir kampanya veya yönlendirilmiş kanalı olmayan bir kampanya gibi, göz atılmaya değer alt hesapları işaretler. Bunu, her bir müşteriyi tek tek açıp duraksayan bir kampanya olup olmadığını kontrol etmek yerine, tüm portföy genelinde bir sağlık kontrolü panosu oluşturmak için kullanın.

> Tüm müşteriler genelindeki zaman serisi mesajlaşma ve kredi etkinliği için (belirli bir anlık görüntü yerine grafik oluşturmaya hazır bir seri), Analytics API kılavuzundaki `GET /analytics/agency-rollup` bölümüne bakın.

***

## Hâlihazırda kurulmuş bir müşteri hesabı gönderin

`PUT /v1/snapshots/default` · `POST /v1/snapshots/{snapshotId}/apply`

Bir [anlık görüntü](snapshots.md), kendi hesabınızdan alınan bir veya daha fazla yapay zeka temsilcisi ile bunların bilgi tabanı, araçları ve medyasını içeren yeniden kullanılabilir bir şablondur. İki uç nokta, bunu tedarik akışınıza dahil eder.

**Otomatik — her yeni müşteri bununla doğar.** Bir anlık görüntüyü varsayılan olarak bir kez işaretleyin; o andan itibaren oluşturduğunuz her hesap, bu anlık görüntü yüklü olarak gelir. Bu, `POST /v1/subaccounts` aracılığıyla oluşturulan hesapları, kontrol panelinde oluşturduğunuz hesapları ve bir müşteri ödeme bağlantınız üzerinden ödeme yaptığında otomatik olarak oluşturulan hesapları kapsar.

Öncelikle, anlık görüntünün kimliğini (id) bulun:

```bash
curl "https://api.dmchamp.com/v1/snapshots" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY"
```

Ardından bunu varsayılan olarak ayarlayın:

```bash
curl -X PUT "https://api.dmchamp.com/v1/snapshots/default" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "snapshot_id": "SNAPSHOT_ID" }'
```

Entegrasyonun tamamı budur. Tekrar kapatmak için `{"snapshot_id": null}` gönderin. Aynı işlemi **Anlık Görüntüler** sayfasındaki yıldıza tıklayarak kontrol panelinden de yapabilirsiniz.

Şu anda nelerin yıldızlandığını okumak için (örneğin, bir sağlama betiği birini ayarlayıp ayarlamayacağına karar vermeden önce), `GET /v1/snapshots/default`, `{ "success": true, "data": { "default_snapshot_id": "SNAPSHOT_ID" } }` değerini döndürür; hiçbir şey yıldızlanmadığında ise `null` değerini döndürür. `GET /v1/snapshots` (yukarıdaki kimliği bulmak için kullanılır), tam `snapshots` dizisiyle birlikte aynı `default_snapshot_id` değerini döndürür, bu nedenle çoğu entegrasyonun yalnızca tek bir çağrıya ihtiyacı vardır. Tam anlık görüntü nesnesi alanları [Anlık Görüntüler](snapshots.md) kılavuzundadır.

**İsteğe bağlı — tek bir hesaba yükleyin.** Mevcut bir müşteriyi sisteme dahil etmek veya daha sonra bir müşteriye ikinci bir şablon vermek için kullanışlıdır.

```bash
curl -X POST "https://api.dmchamp.com/v1/snapshots/SNAPSHOT_ID/apply" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "sub_account_id": "SUB_ACCOUNT_UID" }'
```

`sub_account_id` parametresini atlarsanız, bunun yerine kendi ajans hesabınıza yüklenir. `/subaccounts` uç noktaları gibi, bunlar da hedef hesabı ortamdaki `sub_account_id` parametresi yerine yol veya gövde içinde belirtir.

Üzerine inşa etmeden önce bilmeniz gerekenler:

- **Yüklenen temsilciler duraklatılmış olarak başlar.** Önce müşterinin kanallarını bağlayın, ardından temsilciyi etkinleştirin. Bu, hem otomatik hem de isteğe bağlı yol için geçerlidir.
- **Tedarik süreci, bir anlık görüntü nedeniyle asla başarısız olmaz.** Yükleme tamamlanamazsa, müşteri hesabı yine de oluşturulur ve kullanılabilir durumdadır; sadece boş gelir ve anlık görüntüyü daha sonra uygulayabilirsiniz.
- **Kanallar, takvimler ve OAuth bağlantıları asla kopyalanmaz.** Her hesap kendi bağlantısını kurar. Düz bir API anahtarı kullanan araçlar hemen çalışmaya devam eder.
- **İki kez uygulamak ikinci bir kopya oluşturur.** Hiçbir şeyin üzerine yazılmaz.

***

## Şablonun kendisini API üzerinden oluşturun

`POST /v1/snapshots` · API üzerinden aracılar, özel işlevler ve medya

Yukarıdaki bölüm, birinin kontrol panelinde oluşturduğu bir anlık görüntüyü dağıtır. Yazarlık kısmı da açıktır, böylece tüm döngü — ana kurulumu bir kez birleştirin, yakalayın ve her müşteriye iletin — kod üzerinden çalıştırılabilir.

Bir sağlama betiğinin kullandığı sırayla parçalar:

1. **Özel işlevlerinizi oluşturun.** `POST /v1/custom-functions` bir tane oluşturur; `GET /v1/custom-functions` sahip olduklarınızı listeler ve `GET`, `PUT` ve `DELETE` üzerindeki `/v1/custom-functions/{customFunctionId}` bir tanesini okur, günceller ve kaldırır. `POST /v1/custom-functions/test`, kaydetmeden önce bir tanımı deneme amaçlı çalıştırır.
2. **Aracıyı oluşturun ve şekillendirin.** `POST /v1/agents` onu oluşturur, `PUT /v1/agents/{agentId}` günceller ve `PATCH /v1/agents/{agentId}/active` ile `{ "active": false }` siz çalışırken onu duraklatılmış tutar (aynı çağrı `true` ile canlıya geçer). `GET /v1/agents` onları listeler.
3. **Aracıya yeteneklerini kazandırın.** `POST /v1/agents/{agentId}/custom-functions` ile `{ "custom_function_id": "..." }`, aracıya bir işlev ekler; eşleşen `DELETE /v1/agents/{agentId}/custom-functions/{customFunctionId}` ise onu ayırır.
4. **Medya kütüphanesini doldurun.** `POST /v1/agents/{agentId}/media-library` bir öğe yükler (`base64Data`, `mimeType`, `title`, `description` içeren JSON); `GET` aracının öğelerini listeler ve `/{itemId}` üzerindeki `PATCH`/`DELETE` bir tanesini günceller veya kaldırır.
5. **Onu bir anlık görüntü olarak yakalayın.**

```bash
curl -X POST "https://api.dmchamp.com/v1/snapshots" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Master setup v1",
    "agent_ids": ["AGENT_ID"],
    "include_knowledge": true,
    "include_tools": true,
    "include_media": true
  }'
```

Oradan sonrası önceki bölümdür: varsayılan olarak işaretleyin, böylece her yeni müşteri onunla doğar veya isteğe bağlı olarak uygulayın. İdari işlemler de yan tarafta yer alır: `PATCH /v1/snapshots/{snapshotId}` ile `{ "name": "..." }` birini yeniden adlandırır, `DELETE /v1/snapshots/{snapshotId}` birini siler (ve varsayılan ise işaretini kaldırır) ve `GET /v1/snapshots/apply-targets` yükleme yapabileceğiniz her hesabı listeler.

Aracı, özel işlev ve medya uç noktalarının tümü `sub_account_id` kabul eder, bu nedenle aynı çağrılar bir müşterinin hesabı içindeki bir aracıyı doğrudan koruyabilir. Anlık görüntü çağrıları her zaman ajans hesabınız üzerinde işlem yapar — şablon sizinle birlikte yaşar. Bunların tümü için tam istek ve yanıt şemaları [API Referansı](../api/reference.md) içindedir.

***

## Fiyatlandırma kademelerinizi API üzerinden yönetin

`GET /v1/agency/pricing-tiers` · `POST /v1/agency/pricing-tiers` · `PATCH /v1/agency/pricing-tiers/{tierIndex}` · `DELETE /v1/agency/pricing-tiers/{tierIndex}`

**SaaS Modu → Fiyatlandırma Kademeleri** bölümünde sattığınız planlar kod üzerinden okunabilir ve değiştirilebilir; böylece kendi yönetici paneliniz veya sağlama betiğiniz, kimsenin paneli açmasına gerek kalmadan bir plan ekleyebilir, fiyat ayarlayabilir veya ödeme bağlantısı verebilir. Bu sayfadaki diğer tüm çağrılarda olduğu gibi ajans API anahtarınızla kimlik doğrulaması yapın; bu uç noktalar ajans düzeyindedir, bu nedenle herhangi bir `sub_account_id` almazlar. Her yazma işlemi, paneldeki kaydetme işlemiyle aynı doğrulamayı ve aynı Stripe ürün ve fiyat senkronizasyonunu çalıştırır, bu nedenle burada oluşturulan bir plan, elle kurduğunuz bir plandan farksızdır.

### Kademelerinizi listeleyin

```bash
curl "https://api.dmchamp.com/v1/agency/pricing-tiers" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY"
```

**Yanıt**

```json
{
  "success": true,
  "data": {
    "tiers": [
      {
        "tierIndex": 0,
        "credits": 1000,
        "price_cents": 2900,
        "currency": "usd",
        "label": "Starter",
        "billing_interval": "month",
        "trial_days": 14,
        "trial_credits": 250,
        "trial_card_required": false,
        "trial_hard_expiry": true,
        "stripe_price_id": "price_1PxAbC…",
        "stripe_product_id": "prod_QxAbC…",
        "checkout_url": "https://app.yourdomain.com/v1/checkout?id=YOUR_AGENCY_UID&tierIndex=0"
      }
    ],
    "count": 1,
    "max_tiers": 20
  }
}
```

Her kademe, Planlar listenizdeki konumu olan **`tierIndex`** (diğer üç çağrının onu nasıl adreslediği budur) ve **Ödemeler** sekmesinin size verdiği, halihazırda o planın satıldığı [beyaz etiketli alana](white-labeling.md) işaret eden, paylaşılmaya hazır bir **`checkout_url`** ile birlikte döner.

### Kademe ekleyin

Gövde bir kademe nesnesidir; listenizin sonuna eklenir.

```bash
curl -X POST "https://api.dmchamp.com/v1/agency/pricing-tiers" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "label": "Starter",
    "credits": 1000,
    "price_cents": 2900,
    "currency": "usd",
    "billing_interval": "month",
    "trial_days": 14,
    "trial_credits": 250,
    "trial_card_required": false,
    "trial_hard_expiry": true,
    "features": ["channels_3", "channel_whatsapp_web", "webhooks"]
  }'
```

Yanıt, yerleştiği `tierIndex` ve `checkout_url` dahil olmak üzere oluşturulan kademeyi taşır.

### Kademe düzenleyin

Yalnızca değiştirmek istediğiniz alanları gönderin; plandaki diğer her şey olduğu gibi bırakılır.

```bash
curl -X PATCH "https://api.dmchamp.com/v1/agency/pricing-tiers/0" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "price_cents": 3900, "trial_hard_expiry": true }'
```

API'nin tanımadığı bir alan göz ardı edilmek yerine reddedilir ve hata mesajında belirtilir; böylece bir yazım hatası, canlı görünen ancak hiçbir şey yapmayan bir ayarı sessizce yazamaz. Fiyatı, kredileri, para birimini veya faturalandırma sıklığını değiştirmek Stripe'ınızda yeni bir fiyat oluşturur; halihazırda abone olan müşteriler kaydoldukları planda kalmaya devam ederler.

### Kademe silin

```bash
curl -X DELETE "https://api.dmchamp.com/v1/agency/pricing-tiers/2" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY"
```

Panel ile aynı kural: hala aktif aboneleri olan bir plan silinemez. İstek reddedilir ve üzerinde kaç abone olduğu size bildirilir; önce onları iptal edin veya taşıyın. Başarılı bir silme işlemi, halihazırda yeniden numaralandırılmış kalan kademelerinizle yanıt verir.

### Bir kademedeki alanlar

| Alan | Ne olduğu |
|---|---|
| `label` / `description` | Planın adı ve ödeme sayfanızda gösterilen isteğe bağlı satır. |
| `credits` | Müşterinin aylık veya yıllık planda **ayda**, haftalık planda ise **fatura dönemi başına** aldığı krediler. |
| `price_cents` | En küçük para birimi cinsinden fatura aralığı başına fiyat (`2900` = 29,00 $). Yıllık planda bu, tüm yılın fiyatıdır. |
| `currency` | Küçük harfli ISO kodu — `usd`, `eur`, `gbp` vb. |
| `billing_interval` / `billing_interval_count` | `month` (varsayılan), `year` veya "her N haftada bir" için 1–52 arası bir sayıyla `week`. |
| `trial_days` | Ücretsiz deneme süresi, 0 ile 90 arası. `0` (veya boş bırakmak) deneme süresi olmadığı anlamına gelir. |
| `trial_credits` | Müşterinin denemeye başladığı kredi miktarı. Varsayılan olarak planın `credits` değeridir. |
| `trial_card_required` | `false`, müşterinin kart girmeden denemeye başlamasını sağlar. Varsayılan olarak `true` değeridir. |
| `trial_hard_expiry` | `true`, deneme süresi yükseltme olmadan bittiğinde kullanılmayan deneme kredilerini havuzunuza iade eder ve müşterinin hesabını kilitler. Varsayılan olarak `false` değeridir — bkz. [Deneme sonrası katı son kullanma](agency-accounts.md#step-3--set-up-pricing-tiers). |
| `rollover_cap_months` | Plan kapsamındaki müşterilerin yenilemeler arasında taşıyabileceği ödenek ayları — 0 ile 120 arasında bir sayı, kesirlere izin verilir. `0` hiçbir şeyi devretmez; `null` (varsayılan) sınır olmadığı anlamına gelir. Bkz. [Nelerin devredileceğini sınırlama](sub-accounts.md#capping-what-rolls-over). |
| `rollover_expiry_days` | Kullanılmayan kredilerin bir sonraki yenilemede silineceği gün sayısı — 1 ile 3650 arasında tam bir sayı. `null` (varsayılan) asla süresi dolmayacağı anlamına gelir. |
| `features` / `feature_settings` | Plan kapsamındaki müşterilerin neleri aldığı — [Müşterinin hangi kanal türlerini bağlayabileceğini seçin](#choose-which-channel-types-a-client-can-connect) ile aynı özellik kimlikleri. |
| `team_seats_limit` | Planın sağladığı ekip koltukları: tam bir sayı, hiçbiri için `0`, sınırsız için `-1`. |
| `white_label_config` | Planın hangi [beyaz etiket alan adlarınızda](white-labeling.md#up-to-three-white-labels) satıldığı. |

Deneme alanları yalnızca denemesi olan bir planda anlam ifade eder: `trial_days: 0` ile bir katmanı kaydederseniz bu alanlar kaldırılır. Planın Stripe ürün ve fiyat kimlikleri sizin için yönetilir ve manuel olarak ayarlanamaz.

Doğru yapılması gereken üç şey:

- **Katman indeksleri kalıcı kimlikler değil, konumlardır.** Bir planı silmek, ondan sonra gelen tüm planları bir sıra öne kaydırır; bu nedenle herhangi bir değişiklikten sonra listeyi yeniden getirin ve yayınladığınız ödeme bağlantılarını, tıpkı kontrol panelinde bir planı sildikten sonra yapacağınız gibi yeniden kopyalayın.
- **SaaS Modu önce ayarlanmalıdır.** Bu uç noktalar, beyaz etiketleme özelliğine sahip bir ajans hesabı ve halihazırda kaydedilmiş bir Stripe anahtarı gerektirir; bunlar olmadan, planın ürünü ve fiyatının üzerinde barınacağı bir Stripe hesabı bulunmaz.
- **Yirmi plan sınırı vardır**, tıpkı kontrol panelindeki gibi. Liste yanıtındaki `max_tiers` alanı size mevcut sınırı bildirir.

Tam istek ve yanıt şemaları, **Ajans** başlığı altında [API Referansı](../api/reference.md) kısmında yer almaktadır.

***

## Kredi başına fiyatınızı API üzerinden ayarlayın

`GET /v1/agency/credit-price` · `PATCH /v1/agency/credit-price`

Müşterilerin anlık yüklemeler için ödediği fiyat (**SaaS Modu → Kredi Başına Fiyatlandırma**) kod üzerinden de okunabilir ve değiştirilebilir. Bu özellik, fiyatın kendi kendine değişmesi gereken durumlar için oluşturulmuştur: kredileri bir para biriminde satan ancak başka bir para biriminde ücretlendiren bir ajans, birinin her hafta manuel olarak düzenlemesi yerine, zamanlanmış bir işin döviz kuru değiştikçe fiyatı güncellemesini sağlayabilir.

### Mevcut fiyatı okuyun

```bash
curl "https://api.dmchamp.com/v1/agency/credit-price" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY"
```

**Yanıt**

```json
{
  "success": true,
  "data": {
    "price_per_credit_cents": 125,
    "price_per_credit_currency": "brl",
    "note": "USD 0.25 per credit at our reference rate",
    "minimum_cents": 60
  }
}
```

`minimum_cents`, platformun o para biriminde izin verdiği en düşük fiyattır, bu nedenle bir iş, yeni bir fiyat göndermeden önce bunu kontrol edebilir. Bir fiyat belirlenene kadar her üç değer de `null` şeklindedir.

### Değiştirin

```bash
curl -X PATCH "https://api.dmchamp.com/v1/agency/credit-price" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "price_per_credit_cents": 130, "currency": "brl" }'
```

Yalnızca değiştirmek istediğiniz veriyi gönderin. `price_per_credit_cents`, en küçük para birimi cinsinden fiyattır (`130` = 1,30 R$); `currency`, küçük harfli bir ISO kodudur; `note`, müşterilere Faturalandırma sayfalarında kredi başına fiyatın hemen altında gösterilen, 200 karaktere kadar isteğe bağlı bir satırdır — *"Referans kurumuz üzerinden kredi başına 0,25 USD"* gibi başka bir para birimindeki referans fiyatı için kullanışlıdır. Kaldırmak için `"note": ""` gönderin. Yanıt, yukarıdaki okuma ile aynı şekildedir, bu sayede bir iş karşılaştırma yapabilir ve hiçbir şey değişmediğinde yazma işlemini atlayabilir.

Kontrol panelindeki kuralların aynısı burada da geçerlidir: fiyat, o para birimi için platform minimumunun altına düşemez ve hesabın beyaz etiketleme (white labeling) özelliğine sahip olması gerekir. Fiyatlandırma kademesi uç noktalarının aksine, bu değeri okumak veya değiştirmek için Stripe anahtarı gerekmez.

### Bir işe başka hiçbir şey yapamayan bir anahtar verin

Tam yetkili ajans anahtarınızı bir zamanlayıcıya koymak, bir fiyat güncellemesinin ihtiyaç duyduğundan daha fazla erişim sağlar. Bunun yerine, **Ajans Kredi Fiyatı** alanıyla sınırlı **kapsamlı bir anahtar** oluşturun: bu anahtar kredi başına fiyatı okuyabilir ve değiştirebilir, başka hiçbir şeyi değiştiremez; alt hesaplara, planlara, kredilere veya Stripe bağlantınıza dokunamaz.

```bash
curl -X POST "https://api.dmchamp.com/v1/api-keys" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "label": "FX price updater", "scopes": { "read_only": false, "tags": ["Agency Credit Price"] } }'
```

Yanıt, yeni anahtarı `api_key` içinde **yalnızca bir kez** taşır; bir daha asla gösterilmez, bu yüzden hemen kaydedin. Yalnızca fiyatı okuması gereken bir anahtar için `"read_only": true` ayarını yapın ve kendi kendine çalışmayı durdurmasını istiyorsanız `"expires_at"` (bir ISO tarihi) ekleyin. Yalnızca hesap sahibinin anahtarı kapsamlı anahtarlar oluşturabilir; bunları `GET /v1/api-keys` ve `DELETE /v1/api-keys/{id}` ile listeleyin veya iptal edin.

***

## Bir alt hesabın fiyatlandırmanızı okumasına izin verin

`GET /v1/subaccounts/agency-pricing`

Bu sayfadaki diğer tüm uç noktalar, isteğe bağlı olarak `sub_account_id` aracılığıyla bir müşteriyi hedefleyerek **ajans anahtarınızla** çağrılır. Bu uç nokta ise tam tersidir: **alt hesabın kendi API anahtarıyla** çağrılır, `sub_account_id` içermez; böylece bir müşterinin kendi yükleme sayfası (veya onlar için oluşturduğunuz bir entegrasyon), ajans hesabınızı hiçbir zaman görmeden onlara ne kadar ücret yansıttığınızı görüntüleyebilir.

```bash
curl "https://api.dmchamp.com/v1/subaccounts/agency-pricing" \
  -H "X-API-Key: THE_SUB_ACCOUNTS_OWN_API_KEY"
```

**Yanıt**

```json
{
  "success": true,
  "data": {
    "tiers": [{ "credits": 1000, "price_cents": 2900, "currency": "usd" }],
    "price_per_credit_cents": 125,
    "price_per_credit_currency": "brl",
    "price_per_credit_note": "USD 0.25 per credit at our reference rate",
    "agency_display_name": "Client Co's Growth Partner"
  }
}
```

Bu, ajans olarak sizin için [`GET /v1/agency/pricing-tiers`](#list-your-tiers) ve [`GET /v1/agency/credit-price`](#read-the-current-price) tarafından döndürülenlerin aynısını, müşterinin görmesine gerek olmayan (Stripe kimlikleri, `max_tiers` vb.) şeyler hariç olacak şekilde yansıtır. Yalnızca bağlı bir ajansı olan bir alt hesap için çalışır; kendi ajans hesabınızdan çağırmak bir izin hatası döndürür.

***

## Dikkat edilmesi gerekenler

- **Ajans anahtarınızı kullanın.** Her çağrıyı alt hesabın değil, ajans hesabınızın API anahtarı ile doğrulayın. İşlemi yönlendiren parametre `sub_account_id` parametresidir.
- **Krediler alt hesaptan düşülür.** Satın almalar ve yinelenen ücretler, sizin değil, hedeflenen alt hesabın kredi bakiyesine yansır.
- **`404` hatası "sizin alt hesabınız değil" anlamına gelir.** Kimlik numarasını ve hesabın yönettiğiniz bir hesap olduğunu tekrar kontrol edin.
- **Parametre kabul edildiği her yerde isteğe bağlıdır.** Bu parametreyi atlarsanız aynı uç nokta ajans hesabınız üzerinde işlem yapar, böylece tek bir entegrasyonu her ikisi için de kullanabilirsiniz.

***

## İlgili

- [API Erişimi](../integrations/api-access.md) — kimlik doğrulama, temel URL, hatalar, hız sınırları.
- [Alt Hesaplar](sub-accounts.md) — hedefleyebileceğiniz hesapları listeleyin ve yönetin.
- [Alt Hesap Otomatik Yükleme](sub-account-auto-recharge.md) — webhook + API aracılığıyla bir alt hesaba kredi verin.
- [Kampanyalar API'si](../api/campaigns.md) — tam alan referansı dahil olmak üzere kampanyalar oluşturun, güncelleyin ve kopyalayın.
- [Kanal Bağlantısı API'si](../api/channels.md) — bir müşterinin kanallarını bağlayın ve bunları bir kampanyaya yönlendirin.
- Analytics API kılavuzu (API bölümünde) — ajans alt hesap toplamı ve diğer tüm raporlama uç noktaları.
- [Anlık Görüntüler](snapshots.md) — bir anlık görüntünün neleri yakaladığı ve panoda nasıl oluşturulacağı.
