# Zahteve

Zahteva je en klic enega modela. Ima id (`req_…`), stanje, ceno v kreditih API (1000 = 1 USD) in, ko je uspešna, ustvarjene datoteke. Isti objekt se vrne iz vsake spodnje končne točke za vsak model.

## Iskanje modela

Katalog vseh 1496 modelov je javni JSON (ključ ni potreben):

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

| Parameter poizvedbe | Pomen |
|---|---|
| `q` | Besede, ki se morajo vse pojaviti v imenu, id-ju, izdelovalcu ali oznakah, na primer `kling 3`. |
| `category` | En id kategorije, na primer `text-to-video` ali `upscale`. `GET https://api.doitong.com/v1/categories` prikaže vseh 21 kategorij z njihovimi števili. |
| `lab` | Izdelovalec modela po imenu ali id-ju, na primer `Google` ali `black-forest-labs`. |
| `family` | Id `family` iz prejšnje vrstice: vsaka različica enega modela (pro, fast, image-to-video, …). |
| `mode` | `exact` (cena se izračuna iz vhoda), `measured` (iz dolžine ali velikosti vhodnih datotek), `estimate` (ocenjena cena na izvajanje) ali `metered` (zaračunano glede na dejansko uporabo, do največje vrednosti na izvajanje). |
| `limit`, `cursor` | Velikost strani (od 1 do 100, privzeto 50) in `next_cursor` prejšnje strani. |

Vsaka vrstica ima `id`, `name`, `lab`, `category`, `family`, `summary`, `tags`, `output_kind`, `docs_url` in objekt `price` (glejte [Cene](https://doitong.com/developers/docs/pricing#price-objects)). `GET https://api.doitong.com/v1/models/{model_id}` doda celotno vhodno in izhodno shemo JSON Schema, kanonična imena parametrov, pravila cen in primer vhoda. Neznana `category` ali `mode` vrne `400 invalid_parameter`.

## Izvajanje modela

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

- Telo je vhod modela, objekt JSON. Vsaka stran modela navaja njegove parametre.
- Vhod se preveri, preden se karkoli zaračuna. Neveljaven vhod vrne `422 invalid_input` z zadevnim `param` in ne stane nič.
- `?wait=N` (do 20 sekund) zadrži klic, dokler se zahteva ne konča ali čas ne poteče.
- `?webhook_url=https://…` pošlje podpisan POST na ta URL, ko se zahteva konča (glejte [Webhooki](https://doitong.com/developers/docs/webhooks)).
- `?storage=permanent` ali `?storage=temporary` določi, kako dolgo se izhodne datoteke hranijo; brez tega velja nastavitev računa (glejte [Kje so datoteke](#storage)).

Odgovor je `202 Accepted`, ko zahteva še poteka, in `200 OK`, ko se je končala v času čakanja (ali ko gre za ponovitev, glejte spodaj). Glavi `Location` in `Doitong-Request-Id` vsebujeta URL in id zahteve.

## Stanja

Življenjski cikel zahteve: `queued` → `running` → `succeeded` | `failed` | `canceled` (končno; neuspešne in preklicane seje se povrnejo).

| Stanje | Pomen | Končno |
|---|---|---|
| `queued` | Sprejeto in zaračunano, čaka na izvajalca. `queue_position` lahko prikaže mesto v vrsti. | ne |
| `running` | Model ustvarja vsebino. | ne |
| `succeeded` | Končano. `outputs` vsebuje datoteke. | da |
| `failed` | Model ali omejitev ga je ustavila. `error` pove zakaj. Krediti API se vrnejo. | da |
| `canceled` | Preklicano, preden je ustvarilo rezultat. Krediti API se vrnejo. | da |

Zahteva, ki traja dlje od časovne omejitve, spodleti s kodo `timeout` in se povrne: 15 minut za slike, 60 minut za video, 30 minut za zvok in vse drugo.

## Objekt zahteve

```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` je enak za vsak model: en vnos na ustvarjeno datoteko s `type` (`image`, `video`, `audio`, `file` ali `3d`), `url` v naši shrambi, `content_type` ter, ko so znani, `file_size`, `width`, `height`, `duration`.
- `output` je lasten rezultat modela (njegova polja so navedena na vsaki strani modela) z istimi URL-ji.
- `storage` pove, kako se datoteke hranijo: `mode` (`permanent` ali `temporary`), shranjeni `bytes`, `expires_at` (ko se začasna datoteka izbriše, `null` za trajne) in `expired` (`true`, ko datotek ni več).
- `cost.credits` je cena klica v kreditih API (`cost.usd` v USD), `cost.charged` je znesek, odtegnjen od stanja API, `cost.refunded` pa vrnjeni znesek. Pri modelu `metered` je `cost.credits` največji znesek, zadržan na začetku (`cost.held`); ko je izvajanje uspešno, `cost.settled` pove, koliko je znašala uporaba, preostanek največjega zneska pa je v `cost.refunded` (glejte [Zaračunavanje glede na uporabo](https://doitong.com/developers/docs/pricing#metered)).
- Ko zahteva spodleti, je `error` `{ "type": …, "code": …, "message": … }`.

## Branje zahteve

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

- `?wait=N` (do 20 sekund) uporablja dolgo čakanje: klic se vrne takoj, ko je zahteva končna, ali po N sekundah s trenutnim stanjem. Ponavljanje tega je najpreprostejši način čakanja na rezultat.
- `?logs=1` doda vrstice dnevnika napredka modela (zadnjih 50) kot `logs`.

Berete lahko samo zahteve svojega računa; vsak drug id je `404 request_not_found`.

## Seznam zahtev

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

Najprej so najnovejše. `limit` je od 1 do 100 (privzeto 20), `status` in `model` filtrirata. Odgovor je `{ "object": "list", "data": [ … ], "has_more": true, "next_cursor": "req_…" }`; za naslednjo stran posredujte `cursor=<next_cursor>`.

## Preklic zahteve

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

- Preklic pred začetkom modela: stanje postane `canceled`, krediti API se vrnejo in prejmete `200`.
- Če se ustvarjanje že izvaja: preklic se posreduje naprej in prejmete `202` z `"cancel_requested": true`. Če se model vseeno konča, je zahteva običajno uspešna in zaračunana.
- Če je zahteva že končna: `409 not_cancelable` (zahteva, ki je že `canceled`, preprosto vrne `200`).

## Brisanje datotek zahteve

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

Takoj izbriše naše kopije izhodnih datotek zahteve in ustavi strošek shranjevanja. Odgovor je objekt zahteve z `storage.expired: true`; njeni URL-ji ostanejo v zapisu, vendar ne delujejo več. Ponovni klic ne spremeni ničesar (`200`). Zahteva, ki je še `queued` ali `running`, še nima datotek: `409 request_active`. Potrebuje `models:run`.

## Idempotentnost: ponovitev brez dvojnega plačila

Omrežja odpovedujejo. Za varen ponovni poskus pošljite glavo `Idempotency-Key` (poljuben niz do 255 znakov, edinstven za operacijo, na primer lasten id naročila):

- Isti ključ in isto telo kot prej: prejmete prvotno zahtevo (`200`, glava `Idempotent-Replayed: true`), nič se ne zaračuna znova.
- Isti ključ in telo po izvajanju, ki je spodletelo, preden je doseglo model (`upstream_error` ali `internal_error` pri oddaji, `insufficient_credits`, `budget_exceeded`, `too_many_inflight`): nič ni bilo ustvarjeno in nič zaračunano, zato ponovni poskus znova izvede model namesto vrnitve napake.
- Isti ključ z drugačnim telesom: `409 idempotency_mismatch`.
- Ključi veljajo za ključ API, ki jih je poslal.

## Kje so datoteke

Vsaka izhodna datoteka se kopira v našo shrambo, preden je zahteva označena kot `succeeded`, zato so URL-ji v `outputs` na naših gostiteljih in jih lahko neposredno povežete. Kako dolgo ostanejo, izberete sami:

| Način | Trajanje | Cena |
|---|---|---|
| `permanent` (privzeto) | Dokler jih ne izbrišete | 100 kreditov API (0,10 $) na GB na mesec, dnevno zaračunano od stanja API |
| `temporary` | 7 dni, nato izbrisano | Brezplačno |

- Nastavitev računa določa vrednost za nove zahteve: stikalo »Datoteke shrani za vedno« na [nadzorni plošči](https://doitong.com/developers/dashboard#balance) ali `PATCH https://api.doitong.com/v1/account/storage` z `{"mode": "temporary"}`. `GET https://api.doitong.com/v1/account` jo prikaže pod `storage`, skupaj z bajti, ki jih hranite, in mesečno oceno.
- `?storage=permanent|temporary` pri izvajanju (argument `storage` orodja MCP `run`) to preglasi za to izvajanje.
- Spreminjanje nastavitve se nikoli ne dotakne datotek, ki jih že imate; izbrišite jih z [`DELETE /requests/{id}/files`](#delete-files).
- Ko stanje API ne more plačati shrambe, se nič ne zaračuna in prejmete e-pošto: v 30 dneh izvedite dopolnitev dobroimetja, sicer shranjene datoteke postanejo začasne in se izbrišejo 7 dni pozneje.

V redkem primeru, ko naša kopija spodleti, ima vnos `"stored": false`, URL pa je prvotni in kratkotrajni: kmalu ga prenesite.
