# Požadavky

Požadavek je jedno volání jednoho modelu. Má id (`req_…`), stav, cenu v API kreditech (1000 = 1 USD) a po úspěšném dokončení vygenerované soubory. Stejný objekt se vrací z každého níže uvedeného endpointu pro každý model.

## Najít model

Katalog všech 1 496 modelů je veřejný JSON (klíč není potřeba):

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

| Parametr dotazu | Význam |
|---|---|
| `q` | Slova, která se musí všechna objevit v názvu, id, výrobci nebo štítcích, například `kling 3`. |
| `category` | Jedno id kategorie, například `text-to-video` nebo `upscale`. `GET https://api.doitong.com/v1/categories` vypíše všech 21 kategorií s jejich počty. |
| `lab` | Výrobce modelu podle názvu nebo id, například `Google` nebo `black-forest-labs`. |
| `family` | Id `family` z předchozího řádku: každá varianta jednoho modelu (pro, fast, image-to-video, …). |
| `mode` | `exact` (cena se vypočítá ze vstupu), `measured` (z délky nebo velikosti vstupních souborů), `estimate` (odhadovaná cena za spuštění) nebo `metered` (účtováno podle skutečného využití, až do maximální částky za spuštění). |
| `limit`, `cursor` | Velikost stránky (1 až 100, výchozí 50) a `next_cursor` předchozí stránky. |

Každý řádek obsahuje `id`, `name`, `lab`, `category`, `family`, `summary`, `tags`, `output_kind`, `docs_url` a objekt `price` (viz [Ceník](https://doitong.com/developers/docs/pricing#price-objects)). `GET https://api.doitong.com/v1/models/{model_id}` přidává úplné vstupní a výstupní JSON Schema, kanonické názvy parametrů, pravidla účtování a příklad vstupu. Neznámá hodnota `category` nebo `mode` vrací `400 invalid_parameter`.

## Spustit model

```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": "..."}'
```

- Tělo požadavku je vstup modelu, objekt JSON. Každá stránka modelu uvádí jeho parametry.
- Vstup se kontroluje před účtováním. Neplatný vstup vrací `422 invalid_input` s problematickým `param` a nic nestojí.
- `?wait=N` (až 20 sekund) podrží volání, dokud požadavek neskončí nebo nevyprší čas.
- `?webhook_url=https://…` pošle na danou URL podepsaný POST, jakmile požadavek skončí (viz [Webhooky](https://doitong.com/developers/docs/webhooks)).
- `?storage=permanent` nebo `?storage=temporary` určuje, jak dlouho se uchovávají výstupní soubory; bez tohoto parametru se použije nastavení účtu (viz [Kde jsou soubory uložené](#storage)).

Odpověď je `202 Accepted`, dokud požadavek stále probíhá, a `200 OK`, když skončil během čekání (nebo jde o opakované doručení, viz níže). Hlavičky `Location` a `Doitong-Request-Id` obsahují URL a id požadavku.

## Stavy

Životní cyklus požadavku: `queued` → `running` → `succeeded` | `failed` | `canceled` (dokončeno; neúspěšné a zrušené požadavky se refundují).

| Stav | Význam | Konečný |
|---|---|---|
| `queued` | Přijatý a zpoplatněný, čeká na pracovníka. `queue_position` může zobrazovat místo ve frontě. | ne |
| `running` | Model generuje. | ne |
| `succeeded` | Dokončeno. `outputs` uvádí soubory. | ano |
| `failed` | Model nebo limit proces zastavil. `error` uvádí důvod. API kredity se refundují. | ano |
| `canceled` | Zrušeno před vytvořením výsledku. API kredity se refundují. | ano |

Požadavek, který běží déle než povolený čas, selže s kódem `timeout` a částka se refunduje: 15 minut pro obrázky, 60 minut pro video, 30 minut pro zvuk a vše ostatní.

## Objekt požadavku

```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` má stejnou podobu pro každý model: jednu položku pro každý vygenerovaný soubor s `type` (`image`, `video`, `audio`, `file` nebo `3d`), `url` v našem úložišti, `content_type` a, pokud jsou známy, `file_size`, `width`, `height`, `duration`.
- `output` je vlastní objekt výsledku modelu (jeho pole jsou uvedena na stránce každého modelu) se stejnými URL.
- `storage` uvádí, jak se soubory uchovávají: `mode` (`permanent` nebo `temporary`), uložené `bytes`, `expires_at` (kdy se dočasný soubor smaže, u trvalých souborů `null`) a `expired` (`true`, jakmile soubory zmizí).
- `cost.credits` je cena volání v API kreditech (`cost.usd` v USD), `cost.charged` částka stržená ze zůstatku API, `cost.refunded` vrácená částka. U modelu `metered` je `cost.credits` maximální částka zablokovaná na začátku (`cost.held`); po úspěšném dokončení `cost.settled` uvádí skutečné využití a zbytek maximální částky je v `cost.refunded` (viz [Účtování podle využití](https://doitong.com/developers/docs/pricing#metered)).
- Když požadavek selže, `error` je `{ "type": …, "code": …, "message": … }`.

## Načíst požadavek

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

- `?wait=N` (až 20 sekund) používá dlouhé dotazování: volání se vrátí, jakmile je požadavek dokončen, nebo po N sekundách s aktuálním stavem. Opakované volání je nejjednodušší způsob, jak čekat na výsledek.
- `?logs=1` přidá řádky protokolu průběhu modelu (posledních 50) jako `logs`.

Můžete načítat pouze požadavky vlastního účtu; jakékoli jiné id je `404 request_not_found`.

## Vypsat požadavky

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

Od nejnovějších. `limit` je 1 až 100 (výchozí 20), `status` a `model` filtrují výsledky. Odpověď je `{ "object": "list", "data": [ … ], "has_more": true, "next_cursor": "req_…" }`; pro další stránku předejte `cursor=<next_cursor>`.

## Zrušit požadavek

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

- Zrušeno před spuštěním modelu: stav se změní na `canceled`, API kredity se refundují a obdržíte `200`.
- Probíhá generování: zrušení se předá dál a obdržíte `202` s `"cancel_requested": true`. Pokud model přesto dokončí práci, požadavek normálně uspěje a bude zpoplatněn.
- Již dokončené: `409 not_cancelable` (požadavek, který je již `canceled`, jednoduše vrátí `200`).

## Smazat soubory požadavku

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

Okamžitě smaže naše kopie výstupních souborů požadavku a zastaví účtování úložiště. Odpověď je objekt požadavku s `storage.expired: true`; jeho URL zůstanou v záznamu, ale přestanou fungovat. Opakované volání nic nezmění (`200`). Požadavek ve stavu `queued` nebo `running` zatím žádné soubory nemá: `409 request_active`. Vyžaduje `models:run`.

## Idempotence: opakování bez dvojího účtování

Sítě selhávají. Chcete-li spuštění bezpečně zopakovat, odešlete hlavičku `Idempotency-Key` (libovolný řetězec o délce až 255 znaků, jedinečný pro každou operaci, například vlastní id objednávky):

- Stejný klíč a stejné tělo jako předtím: obdržíte původní požadavek (`200`, hlavička `Idempotent-Replayed: true`) a nic se znovu neúčtuje.
- Stejný klíč a tělo po spuštění, které selhalo před předáním modelu (`upstream_error` nebo `internal_error` při odeslání, `insufficient_credits`, `budget_exceeded`, `too_many_inflight`): nic nebylo vytvořeno a nic se neúčtuje, takže opakovaný požadavek znovu spustí model místo vrácení chyby.
- Stejný klíč s jiným tělem: `409 idempotency_mismatch`.
- Klíče platí pro API klíč, který je odeslal.

## Kde jsou soubory uložené

Každý výstupní soubor se před označením požadavku jako `succeeded` zkopíruje do našeho úložiště, takže URL v `outputs` vedou na naše vlastní hostitele a můžete na ně přímo odkazovat. Jak dlouho zůstanou uložené, je na vás:

| Režim | Jak dlouho | Cena |
|---|---|---|
| `permanent` (výchozí) | Dokud je nesmažete | 100 API kredity (0,10 $) za GB měsíčně, účtováno denně ze zůstatku API |
| `temporary` | 7 dnů, poté smazáno | Zdarma |

- Nastavení účtu určuje chování nových požadavků: přepínač „Uchovávat soubory navždy“ v [dashboardu](https://doitong.com/developers/dashboard#balance), nebo `PATCH https://api.doitong.com/v1/account/storage` s `{"mode": "temporary"}`. `GET https://api.doitong.com/v1/account` ho zobrazuje pod `storage` spolu s počtem uchovávaných bajtů a měsíčním odhadem.
- `?storage=permanent|temporary` při spuštění (argument `storage` nástroje MCP `run`) toto nastavení pro dané spuštění přepíše.
- Změna nastavení se nikdy nedotkne souborů, které již máte; smažte je pomocí [`DELETE /requests/{id}/files`](#delete-files).
- Když zůstatek API nemůže úložiště zaplatit, nic se neúčtuje a obdržíte e-mail: dobijte účet do 30 dnů, jinak se uchovávané soubory změní na dočasné a o 7 dnů později se smažou.

Ve vzácném případě, že naše kopie selže, má položka `"stored": false` a URL je původní s krátkou platností: stáhněte ji co nejdříve.
