# Užklausos

Užklausa yra vienas vieno modelio iškvietimas. Ji turi ID (`req_…`), būseną, kainą API kreditais (1000 = 1 USD) ir, kai
sėkminga, sugeneruotus failus. Tas pats objektas grąžinamas iš kiekvieno toliau pateikto galinio taško, kiekvienam modeliui.

## Rasti modelį

Visų 1 496 modelių katalogas yra viešas JSON (rakto nereikia):

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

| Užklausos parametras | Reikšmė |
|---|---|
| `q` | Žodžiai, kurie visi turi būti pavadinime, ID, kūrėjo pavadinime arba žymose, pavyzdžiui, `kling 3`. |
| `category` | Vienas kategorijos ID, pavyzdžiui, `text-to-video` arba `upscale`. `GET https://api.doitong.com/v1/categories` pateikia visas 21 kategorijas ir jų skaičių. |
| `lab` | Modelio kūrėjas pagal pavadinimą arba ID, pavyzdžiui, `Google` arba `black-forest-labs`. |
| `family` | `family` ID iš ankstesnės eilutės: visi vieno modelio variantai (pro, fast, image-to-video, …). |
| `mode` | `exact` (kaina apskaičiuojama pagal įvestį), `measured` (pagal įvesties failų trukmę arba dydį), `estimate` (apskaičiuota kaina už vykdymą) arba `metered` (mokama pagal faktinį naudojimą, iki didžiausios kainos už vykdymą). |
| `limit`, `cursor` | Puslapio dydis (nuo 1 iki 100, numatytasis 50) ir ankstesnio puslapio `next_cursor`. |

Kiekvienoje eilutėje yra `id`, `name`, `lab`, `category`, `family`, `summary`, `tags`, `output_kind`, `docs_url` ir `price`
objektas (žr. [Kainodara](https://doitong.com/developers/docs/pricing#price-objects)). `GET https://api.doitong.com/v1/models/{model_id}` papildomai pateikia
visą įvesties ir išvesties JSON Schema, kanoninius parametrų pavadinimus, kainos taisykles ir įvesties pavyzdį. Nežinoma
`category` arba `mode` reikšmė grąžina `400 invalid_parameter`.

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

- Užklausos turinys yra modelio įvestis — JSON objektas. Kiekvieno modelio puslapyje pateikiami jo parametrai.
- Įvestis patikrinama prieš nuskaičiuojant mokestį. Netinkama įvestis grąžina `422 invalid_input` su klaidingu
  `param` ir nieko nekainuoja.
- `?wait=N` (iki 20 sekundžių) laiko iškvietimą, kol užklausa baigiama arba baigiasi laikas.
- `?webhook_url=https://…` užklausai baigus vykdyti siunčia pasirašytą POST į tą URL (žr. [Webhook](https://doitong.com/developers/docs/webhooks)).
- `?storage=permanent` arba `?storage=temporary` nurodo, kiek laiko saugoti išvesties failus; jei nenurodyta, taikoma paskyros
  nuostata (žr. [Kur saugomi failai](#storage)).

Kol užklausa dar vykdoma, atsakymas yra `202 Accepted`, o kai ji baigiama per laukimo laiką — `200 OK` (arba kai tai
pakartotinis atsakymas, žr. toliau). Antraštėse `Location` ir `Doitong-Request-Id` pateikiamas užklausos URL ir ID.

## Būsenos

Užklausos gyvavimo ciklas: `queued` → `running` → `succeeded` | `failed` | `canceled` (baigta; už nesėkmingas ir atšauktas užklausas grąžinami API kreditai).

| Būsena | Reikšmė | Galutinė |
|---|---|---|
| `queued` | Priimta ir apmokestinta, laukianti vykdytojo. `queue_position` gali rodyti vietą eilėje. | ne |
| `running` | Modelis generuoja. | ne |
| `succeeded` | Baigta. `outputs` pateikia failus. | taip |
| `failed` | Modelis arba apribojimas sustabdė vykdymą. `error` nurodo priežastį. API kreditai grąžinami. | taip |
| `canceled` | Atšaukta prieš sugeneruojant rezultatą. API kreditai grąžinami. | taip |

Užklausa, vykdoma ilgiau nei leidžiama, baigiama kodu `timeout`, o lėšos grąžinamos: 15 minučių vaizdams,
60 minučių vaizdo įrašams, 30 minučių garsui ir viskam kitam.

## Užklausos objektas

```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` visiems modeliams yra vienodas: po vieną įrašą kiekvienam sugeneruotam failui su `type` (`image`, `video`, `audio`,
  `file` arba `3d`), `url` mūsų saugykloje, `content_type` ir, jei žinomi, `file_size`, `width`, `height`,
  `duration`.
- `output` yra paties modelio rezultatų objektas (jo laukai pateikiami kiekvieno modelio puslapyje) su tais pačiais URL.
- `storage` nurodo, kaip saugomi failai: `mode` (`permanent` arba `temporary`), saugomi `bytes`, `expires_at` (kada
  laikinas failas ištrinamas, nuolatiniams failams — `null`) ir `expired` (`true`, kai failų nebelieka).
- `cost.credits` yra iškvietimo kaina API kreditais (`cost.usd` — USD), `cost.charged` — iš API likučio nuskaičiuota suma,
  `cost.refunded` — grąžinta suma. `metered` modeliui `cost.credits` yra pradžioje sulaikyta didžiausia suma
  (`cost.held`); kai vykdymas sėkmingas, `cost.settled` nurodo faktinę naudojimo kainą, o likusi didžiausios sumos dalis yra
  `cost.refunded` (žr. [Mokestis pagal naudojimą](https://doitong.com/developers/docs/pricing#metered)).
- Kai užklausa nepavyksta, `error` yra `{ "type": …, "code": …, "message": … }`.

## Skaityti užklausą

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

- `?wait=N` (iki 20 sekundžių) vykdo ilgą apklausą: iškvietimas grįžta, kai užklausa tampa galutinė, arba po N sekundžių
  su dabartine būsena. Kartoti šį iškvietimą yra paprasčiausias būdas laukti rezultato.
- `?logs=1` prideda modelio eigos žurnalo eilutes (paskutines 50) kaip `logs`.

Galite skaityti tik savo paskyros užklausas; bet kuris kitas ID grąžina `404 request_not_found`.

## Išvardyti užklausas

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

Nuo naujausių. `limit` yra nuo 1 iki 100 (numatytasis 20), o `status` ir `model` filtruoja. Atsakymas yra
`{ "object": "list", "data": [ … ], "has_more": true, "next_cursor": "req_…" }`; kitam puslapiui perduokite
`cursor=<next_cursor>`.

## Atšaukti užklausą

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

- Atšaukta prieš pradedant modeliui: būsena tampa `canceled`, API kreditai grąžinami ir gaunate `200`.
- Jau generuojama: atšaukimas perduodamas modeliui ir gaunate `202` su `"cancel_requested": true`. Jei modelis
  vis tiek baigia vykdyti, užklausa sėkmingai užbaigiama ir apmokestinama.
- Jau galutinė: `409 not_cancelable` (jau `canceled` užklausa tiesiog grąžina `200`).

## Ištrinti užklausos failus

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

Dabar ištrina mūsų užklausos išvesties failų kopijas ir sustabdo jų saugojimo mokestį. Atsakymas yra užklausos
objektas su `storage.expired: true`; jo URL lieka įraše, bet nebeveikia. Pakartotinis iškvietimas nieko nekeičia
(`200`). Užklausa, kuri vis dar yra `queued` arba `running`, failų dar neturi: `409 request_active`. Reikalinga `models:run`.

## Idempotentiškumas: kartoti nemokant du kartus

Tinklai sutrinka. Norėdami saugiai pakartoti vykdymą, siųskite `Idempotency-Key` antraštę (bet kokią iki 255 simbolių
ilgio eilutę, unikalią kiekvienai operacijai, pavyzdžiui, savo užsakymo ID):

- Tas pats raktas ir tas pats turinys kaip anksčiau: gaunate pradinę užklausą (`200`, antraštė
  `Idempotent-Replayed: true`), o mokestis dar kartą nenuskaičiuojamas.
- Tas pats raktas ir turinys po vykdymo, kuris nepavyko prieš pasiekiant modelį (`upstream_error` arba `internal_error` siunčiant,
  `insufficient_credits`, `budget_exceeded`, `too_many_inflight`): niekas nesugeneruota ir mokestis nenuskaičiuotas, todėl
  kartotinė užklausa vėl vykdo modelį, užuot grąžinusi klaidą.
- Tas pats raktas su kitu turiniu: `409 idempotency_mismatch`.
- Raktai taikomi API raktui, kuris juos išsiuntė.

## Kur saugomi failai

Kiekvienas išvesties failas nukopijuojamas į mūsų saugyklą prieš pažymint užklausą kaip `succeeded`, todėl `outputs` URL yra
mūsų serveriuose ir galite tiesiogiai į juos pateikti nuorodas. Kiek laiko jie saugomi, pasirenkate jūs:

| Režimas | Trukmė | Kaina |
|---|---|---|
| `permanent` (numatytasis) | Kol juos ištrinsite | 100 API kreditai (0,10 $) už GB per mėnesį, kasdien nuskaičiuojami iš API likučio |
| `temporary` | 7 dienos, tada ištrinami | Nemokamai |

- Paskyros nuostata taikoma naujoms užklausoms: jungiklis „Saugoti failus neribotą laiką“ [valdymo skydelyje](https://doitong.com/developers/dashboard#balance)
  arba `PATCH https://api.doitong.com/v1/account/storage` su `{"mode": "temporary"}`. `GET https://api.doitong.com/v1/account` ją pateikia
  skiltyje `storage` kartu su saugomų baitų skaičiumi ir mėnesio sąmata.
- `?storage=permanent|temporary` vykdant užklausą (MCP `run` įrankio `storage` argumentas) nepaiso šios nuostatos tame vykdyme.
- Pakeitus nuostatą, jau turimi failai nekeičiami; ištrinkite juos naudodami
  [`DELETE /requests/{id}/files`](#delete-files).
- Kai API likučio nepakanka saugyklai apmokėti, mokestis nenuskaičiuojamas ir gaunate el. laišką: papildykite likutį per
  30 dienas arba saugomi failai taps laikini ir bus ištrinti po 7 dienų.

Retu atveju, kai mūsų kopijavimas nepavyksta, įraše yra `"stored": false`, o URL yra pradinis, trumpai galiojantis:
atsisiųskite failą kuo greičiau.
