# İstekler

Bir istek, bir modelin tek bir çağrısıdır. Bir kimliği (`req_…`), durumu, API kredisi cinsinden maliyeti (1000 = 1 USD) ve başarılı olduğunda oluşturulan dosyaları vardır. Aşağıdaki her uç noktadan her model için aynı nesne döner.

## Model bulma

Tüm 1.496 modelin kataloğu herkese açık JSON'dır (anahtar gerekmez):

```bash
curl "https://api.doitong.com/v1/models?category=text-to-video&lab=Google&limit=20"
```

| Sorgu parametresi | Açıklama |
|---|---|
| `q` | Ad, kimlik, üretici veya etiketlerde tümünün geçmesi gereken kelimeler; örneğin `kling 3`. |
| `category` | Bir kategori kimliği; örneğin `text-to-video` veya `upscale`. `GET https://api.doitong.com/v1/categories`, sayılarıyla birlikte tüm 21 kategoriyi listeler. |
| `lab` | Modelin üreticisi; ada veya kimliğe göre, örneğin `Google` veya `black-forest-labs`. |
| `family` | Önceki satırdan bir `family` kimliği: tek bir modelin her varyantı (pro, fast, image-to-video, …). |
| `mode` | `exact` (fiyat girdiye göre hesaplanır), `measured` (girdi dosyalarının uzunluğuna veya boyutuna göre), `estimate` (çalıştırma başına tahmini fiyat) veya `metered` (çalıştırma başına bir üst sınıra kadar gerçek kullanıma göre ücretlendirilir). |
| `limit`, `cursor` | Sayfa boyutu (1-100, varsayılan 50) ve önceki sayfanın `next_cursor` değeri. |

Her satırda `id`, `name`, `lab`, `category`, `family`, `summary`, `tags`, `output_kind`, `docs_url` ve bir `price` nesnesi bulunur ([Fiyatlandırma](https://doitong.com/developers/docs/pricing#price-objects) bölümüne bakın). `GET https://api.doitong.com/v1/models/{model_id}`, tam girdi ve çıktı JSON Schema'sını, standart parametre adlarını, fiyat kurallarını ve örnek bir girdiyi ekler. Bilinmeyen bir `category` veya `mode`, `400 invalid_parameter` döndürür.

## Model çalıştırma

```bash
curl -X POST "https://api.doitong.com/v1/run/{model_id}?wait=20" \
  -H "Authorization: Bearer $DOITONG_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1842-cover" \
  -d '{"prompt": "..."}'
```

- Gövde, bir JSON nesnesi olan model girdisidir. Her model sayfasında parametreleri listelenir.
- Girdi, ücretlendirme yapılmadan önce doğrulanır. Geçersiz girdi, hataya neden olan `param` ile birlikte `422 invalid_input` döndürür ve hiçbir ücret alınmaz.
- `?wait=N` (en fazla 20 saniye), istek tamamlanana veya süre dolana kadar çağrıyı bekletir.
- `?webhook_url=https://…`, istek tamamlandığında bu URL'ye imzalı bir POST gönderir ([Webhook'lar](https://doitong.com/developers/docs/webhooks) bölümüne bakın).
- `?storage=permanent` veya `?storage=temporary`, çıktı dosyalarının ne kadar süre tutulacağını seçer; belirtilmezse hesap ayarı uygulanır ([Dosyalar nerede tutulur](#storage) bölümüne bakın).

İstek hâlâ işleniyorsa yanıt `202 Accepted`, bekleme süresi içinde tamamlandıysa (veya aşağıya bakın, yeniden oynatma ise) `200 OK` olur. `Location` ve `Doitong-Request-Id` başlıkları istek URL'sini ve kimliğini taşır.

## Durumlar

İstek yaşam döngüsü: `queued` → `running` → `succeeded` | `failed` | `canceled` (tamamlandı; başarısız ve iptal edilen işlemlerde API kredileri iade edilir).

| Durum | Açıklama | Son durum |
|---|---|---|
| `queued` | Kabul edildi ve ücretlendirildi; bir çalışanı bekliyor. `queue_position` sıradaki yerini gösterebilir. | hayır |
| `running` | Model oluşturuyor. | hayır |
| `succeeded` | Tamamlandı. `outputs`, dosyaları listeler. | evet |
| `failed` | Model veya bir sınır işlemi durdurdu. `error` nedenini belirtir. API kredisi iade edilir. | evet |
| `canceled` | Sonuç üretmeden önce iptal edildi. API kredisi iade edilir. | evet |

Çalışma süresi sınırını aşan bir istek `timeout` koduyla başarısız olur ve iade edilir: görseller için 15 dakika, video için 60 dakika, ses ve diğer her şey için 30 dakika.

## İstek nesnesi

```json
{
  "id": "req_8k2m4q7x1z9c3v5b6n0p2r4t",
  "object": "request",
  "model": "flux/schnell",
  "status": "succeeded",
  "created_at": "2026-10-20T12:00:00Z",
  "started_at": "2026-10-20T12:00:01Z",
  "completed_at": "2026-10-20T12:00:02Z",
  "queue_position": null,
  "cost": { "credits": 3, "usd": "0.003", "charged": 3, "refunded": 0 },
  "input": { "prompt": "..." },
  "output": { "images": [ { "url": "https://content.doitong.com/dev-api/…/0-output.jpeg", "width": 1024, "height": 768 } ] },
  "outputs": [
    { "type": "image", "url": "https://content.doitong.com/dev-api/…/0-output.jpeg", "content_type": "image/jpeg",
      "width": 1024, "height": 768, "file_size": 183920, "stored": true }
  ],
  "error": null,
  "metrics": { "inference_seconds": 1.2 },
  "storage": { "mode": "permanent", "bytes": 183920, "expires_at": null, "expired": false },
  "urls": {
    "self": "https://api.doitong.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t",
    "cancel": "https://api.doitong.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t/cancel"
  }
}
```

- `outputs`, her model için aynıdır: oluşturulan her dosya için `type` (`image`, `video`, `audio`, `file` veya `3d`), depolamamızdaki bir `url`, `content_type` ve biliniyorsa `file_size`, `width`, `height`, `duration` içeren bir giriş.
- `output`, modelin aynı URL'leri içeren kendi sonuç nesnesidir (alanları her model sayfasında listelenir).
- `storage`, dosyaların nasıl tutulduğunu belirtir: `mode` (`permanent` veya `temporary`), depolanan `bytes`, `expires_at` (geçici bir dosyanın silineceği zaman; kalıcı dosyalarda `null`) ve `expired` (dosyalar silindikten sonra `true`).
- `cost.credits`, çağrının API kredisi cinsinden fiyatıdır (`cost.usd`, USD cinsinden), `cost.charged` API bakiyesinden düşülen miktardır, `cost.refunded` geri dönen miktardır. `metered` bir modelde `cost.credits`, başlangıçta bloke edilen maksimum tutardır (`cost.held`); çalışma başarılı olduğunda `cost.settled`, kullanımın tuttuğu miktarı belirtir ve maksimumun geri kalanı `cost.refunded` içindedir ([Kullanıma göre ücretlendirme](https://doitong.com/developers/docs/pricing#metered) bölümüne bakın).
- Bir istek başarısız olduğunda `error`, `{ "type": …, "code": …, "message": … }` olur.

## İstek okuma

```bash
curl "https://api.doitong.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t?wait=20" \
  -H "Authorization: Bearer $DOITONG_API_KEY"
```

- `?wait=N` (en fazla 20 saniye) uzun yoklama yapar: çağrı, istek son duruma ulaştığında veya N saniye sonra mevcut durumla döner. Sonuç beklemenin en basit yolu bunu döngüde kullanmaktır.
- `?logs=1`, modelin ilerleme günlüğü satırlarını (son 50 satır) `logs` olarak ekler.

Yalnızca kendi hesabınızın isteklerini okuyabilirsiniz; başka bir kimlik `404 request_not_found` döndürür.

## İstekleri listeleme

```bash
curl "https://api.doitong.com/v1/requests?limit=20&status=succeeded&model=flux/schnell" \
  -H "Authorization: Bearer $DOITONG_API_KEY"
```

Yeniden eskiye doğru. `limit` 1-100 arasındadır (varsayılan 20); `status` ve `model` filtreler. Yanıt `{ "object": "list", "data": [ … ], "has_more": true, "next_cursor": "req_…" }` biçimindedir; sonraki sayfa için `cursor=<next_cursor>` gönderin.

## İsteği iptal etme

```bash
curl -X POST "https://api.doitong.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t/cancel" \
  -H "Authorization: Bearer $DOITONG_API_KEY"
```

- Model başlamadan önce iptal edilirse durum `canceled` olur, API kredisi iade edilir ve `200` alırsınız.
- Zaten oluşturuluyorsa iptal iletilir ve `"cancel_requested": true` ile `202` alırsınız. Model yine de tamamlanırsa istek normal şekilde başarılı olur ve ücretlendirilir.
- Zaten son durumdaysa `409 not_cancelable` döner (zaten `canceled` olan bir istek yalnızca `200` döndürür).

## İsteğin dosyalarını silme

```bash
curl -X DELETE "https://api.doitong.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t/files" \
  -H "Authorization: Bearer $DOITONG_API_KEY"
```

İsteğin çıktı dosyalarının kopyalarını depolamamızdan hemen siler ve depolama ücretini durdurur. Yanıt, `storage.expired: true` içeren istek nesnesidir; URL'leri kayıtta kalır ancak artık çalışmaz. Tekrar çağrılması hiçbir şeyi değiştirmez (`200`). Hâlâ `queued` veya `running` durumundaki bir isteğin henüz dosyası yoktur: `409 request_active`. `models:run` gerektirir.

## İdempotensi: iki kez ödeme yapmadan yeniden deneme

Ağlar başarısız olabilir. Bir çalıştırmayı güvenle yeniden denemek için bir `Idempotency-Key` başlığı gönderin (255 karaktere kadar herhangi bir dize; işlem başına benzersiz olmalı, örneğin kendi sipariş kimliğiniz):

- Aynı anahtar ve öncekiyle aynı gövde: özgün isteği geri alırsınız (`200`, `Idempotent-Replayed: true` başlığıyla) ve tekrar ücret alınmaz.
- Model ulaşılmadan önce başarısız olan bir çalıştırmanın ardından aynı anahtar ve gövde (`submit` sırasında `upstream_error` veya `internal_error`, `insufficient_credits`, `budget_exceeded`, `too_many_inflight`): hiçbir şey üretilmediği ve ücret alınmadığı için yeniden deneme, hatayı döndürmek yerine modeli yeniden çalıştırır.
- Farklı bir gövdeyle aynı anahtar: `409 idempotency_mismatch`.
- Anahtarlar, onları gönderen API anahtarı kapsamında geçerlidir.

## Dosyalar nerede tutulur

Her çıktı dosyası, istek `succeeded` olarak işaretlenmeden önce depolamamıza kopyalanır; böylece `outputs` içindeki URL'ler kendi sunucularımızdadır ve bunlara doğrudan bağlantı verebilirsiniz. Ne kadar süre tutulacaklarını siz seçersiniz:

| Mod | Süre | Fiyat |
|---|---|---|
| `permanent` (varsayılan) | Siz silene kadar | GB başına aylık 100 API kredisi ($0,10), API bakiyesinden günlük olarak alınır |
| `temporary` | 7 gün, ardından silinir | Ücretsiz |

- Hesap ayarı yeni istekler için geçerlidir: [dashboard](https://doitong.com/developers/dashboard#balance) içindeki "Dosyaları sonsuza kadar sakla" anahtarı veya `{"mode": "temporary"}` ile `PATCH https://api.doitong.com/v1/account/storage`. `GET https://api.doitong.com/v1/account`, bunu `storage` altında, tuttuğunuz baytlar ve aylık tahminle birlikte gösterir.
- Bir çalıştırmadaki `?storage=permanent|temporary` (MCP `run` aracının `storage` bağımsız değişkeni), o çalıştırma için bu ayarı geçersiz kılar.
- Ayarın değiştirilmesi, zaten sahip olduğunuz dosyalara dokunmaz; bunları [`DELETE /requests/{id}/files`](#delete-files) ile silin.
- API bakiyesi depolama ücretini karşılayamadığında ücret alınmaz ve e-posta alırsınız: 30 gün içinde bakiye yükleyin; aksi takdirde tutulan dosyalar geçici olur ve 7 gün sonra silinir.

Kopyamızın başarısız olduğu nadir durumlarda girişte `"stored": false` bulunur ve URL, kısa süre geçerli olan özgün URL'dir: kısa sürede indirin.
