# Begäranden

En begäran är ett anrop till en modell. Den har ett id (`req_…`), en status, sin kostnad i API-krediter (1000 = 1 USD) och, när den lyckas, de genererade filerna. Samma objekt returneras från varje ändpunkt nedan, för varje modell.

## Hitta en modell

Katalogen med alla 1 496 modeller är offentlig JSON (ingen nyckel behövs):

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

| Frågeparameter | Betydelse |
|---|---|
| `q` | Ord som alla måste finnas i namnet, id:t, tillverkaren eller taggarna, till exempel `kling 3`. |
| `category` | Ett kategori-id, till exempel `text-to-video` eller `upscale`. `GET https://api.doitong.com/v1/categories` listar alla 21 med deras antal. |
| `lab` | Modellens tillverkare, efter namn eller id, till exempel `Google` eller `black-forest-labs`. |
| `family` | Ett `family`-id från en tidigare rad: varje variant av en modell (pro, fast, image-to-video, …). |
| `mode` | `exact` (priset beräknas från indatan), `measured` (från längden eller storleken på indatafilerna), `estimate` (ett uppskattat pris per körning) eller `metered` (debiteras efter faktisk användning, upp till ett högsta pris per körning). |
| `limit`, `cursor` | Sidstorlek (1 till 100, standard 50) och föregående sidas `next_cursor`. |

Varje rad har `id`, `name`, `lab`, `category`, `family`, `summary`, `tags`, `output_kind`, `docs_url` och ett `price`-objekt (se [Prissättning](https://doitong.com/developers/docs/pricing#price-objects)). `GET https://api.doitong.com/v1/models/{model_id}` lägger till det fullständiga JSON Schema för indata och utdata, de kanoniska parameternamnen, prisreglerna och ett exempel på indata. En okänd `category` eller `mode` är `400 invalid_parameter`.

## Kör en modell

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

- Body är modellens indata, ett JSON-objekt. Varje modellsida listar dess parametrar.
- Indatan kontrolleras innan något debiteras. Ogiltig indata returnerar `422 invalid_input` med den felaktiga `param`, och kostar ingenting.
- `?wait=N` (upp till 20 sekunder) håller anropet öppet tills begäran är klar eller tiden tar slut.
- `?webhook_url=https://…` skickar en signerad POST till URL:en när begäran är klar (se [Webhooks](https://doitong.com/developers/docs/webhooks)).
- `?storage=permanent` eller `?storage=temporary` väljer hur länge utdatafilerna sparas; utan detta används kontots inställning (se [Var filer finns](#storage)).

Svaret är `202 Accepted` medan begäran fortfarande bearbetas och `200 OK` när den blev klar inom väntetiden (eller när det är en upprepning, se nedan). Header-parametrarna `Location` och `Doitong-Request-Id` innehåller begärans URL och id.

## Statusar

Begärans livscykel: `queued` → `running` → `succeeded` | `failed` | `canceled` (slutgiltig; misslyckade och avbrutna återbetalas).

| Status | Betydelse | Slutlig |
|---|---|---|
| `queued` | Accepterad och debiterad, väntar på en worker. `queue_position` kan visa platsen i kön. | nej |
| `running` | Modellen genererar. | nej |
| `succeeded` | Klar. `outputs` listar filerna. | ja |
| `failed` | Modellen eller en gräns stoppade den. `error` anger varför. API-krediterna återbetalas. | ja |
| `canceled` | Avbruten innan den producerade ett resultat. API-krediterna återbetalas. | ja |

En begäran som körs längre än sin tidsgräns misslyckas med koden `timeout` och återbetalas: 15 minuter för bilder, 60 minuter för video, 30 minuter för ljud och allt annat.

## Begärandeobjektet

```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` är samma för varje modell: en post per genererad fil med `type` (`image`, `video`, `audio`, `file` eller `3d`), en `url` i vår lagring, `content_type` och, när de är kända, `file_size`, `width`, `height`, `duration`.
- `output` är modellens eget resultatobjekt (dess fält listas på varje modellsida) med samma URL:er.
- `storage` anger hur filerna sparas: `mode` (`permanent` eller `temporary`), lagrade `bytes`, `expires_at` (när en tillfällig fil raderas, `null` för permanenta) och `expired` (`true` när filerna är borta).
- `cost.credits` är anropets pris i API-krediter (`cost.usd` i USD), `cost.charged` det som debiterades från API-saldot och `cost.refunded` det som återbetalades. För en `metered`-modell är `cost.credits` det högsta beloppet som reserverades vid starten (`cost.held`); när körningen lyckas anger `cost.settled` vad användningen uppgick till och resten av maxbeloppet finns i `cost.refunded` (se [Debiteras efter användning](https://doitong.com/developers/docs/pricing#metered)).
- När en begäran misslyckas är `error` `{ "type": …, "code": …, "message": … }`.

## Läs en begäran

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

- `?wait=N` (upp till 20 sekunder) använder long polling: anropet returnerar så snart begäran är slutlig, eller efter N sekunder med det aktuella tillståndet. Att upprepa detta är det enklaste sättet att vänta på ett resultat.
- `?logs=1` lägger till modellens förloppsloggrader (de senaste 50) som `logs`.

Du kan bara läsa begäranden från ditt eget konto; alla andra id:n är `404 request_not_found`.

## Lista begäranden

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

Nyast först. `limit` är 1 till 100 (standard 20), `status` och `model` filtrerar. Svaret är `{ "object": "list", "data": [ … ], "has_more": true, "next_cursor": "req_…" }`; skicka `cursor=<next_cursor>` för nästa sida.

## Avbryt en begäran

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

- Avbruten innan modellen startade: statusen blir `canceled`, API-krediterna återbetalas och du får `200`.
- Redan under generering: avbrytandet vidarebefordras och du får `202` med `"cancel_requested": true`. Om modellen ändå blir klar lyckas begäran normalt och debiteras.
- Redan slutlig: `409 not_cancelable` (en begäran som redan är `canceled` returnerar helt enkelt `200`).

## Ta bort en begärans filer

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

Tar omedelbart bort våra kopior av begärans utdatafiler och stoppar lagringsavgiften. Svaret är begärandeobjektet med `storage.expired: true`; URL:erna finns kvar i posten men fungerar inte längre. Om anropet görs igen ändras inget (`200`). En begäran som fortfarande är `queued` eller `running` har inga filer ännu: `409 request_active`. Kräver `models:run`.

## Idempotens: försök igen utan att betala två gånger

Nätverk kan sluta fungera. För att försöka köra igen på ett säkert sätt skickar du en `Idempotency-Key`-header (valfri sträng på upp till 255 tecken, unik per åtgärd, till exempel ditt eget order-id):

- Samma nyckel och samma body som tidigare: du får tillbaka den ursprungliga begäran (`200`, headern `Idempotent-Replayed: true`), och inget debiteras igen.
- Samma nyckel och body efter en körning som misslyckades innan den nådde modellen (`upstream_error` eller `internal_error` vid skickandet, `insufficient_credits`, `budget_exceeded`, `too_many_inflight`): inget producerades och inget debiterades, så försöket kör modellen igen i stället för att returnera felet.
- Samma nyckel med en annan body: `409 idempotency_mismatch`.
- Nycklarna gäller för den API-nyckel som skickade dem.

## Var filer finns

Varje utdatafil kopieras till vår lagring innan begäran markeras som `succeeded`, så URL:erna i `outputs` finns på våra egna värdar och du kan länka direkt till dem. Du väljer hur länge de ska finnas kvar:

| Läge | Hur länge | Pris |
|---|---|---|
| `permanent` (standard) | Tills du tar bort dem | 100 API-krediter (0,10 $) per GB och månad, debiteras dagligen från API-saldot |
| `temporary` | 7 dagar, därefter raderas de | Gratis |

- Kontots inställning avgör nya begäranden: reglaget "Spara filer för alltid" i [instrumentpanelen](https://doitong.com/developers/dashboard#balance), eller `PATCH https://api.doitong.com/v1/account/storage` med `{"mode": "temporary"}`. `GET https://api.doitong.com/v1/account` visar den under `storage`, tillsammans med antalet byte du behåller och månadsuppskattningen.
- `?storage=permanent|temporary` vid en körning (argumentet `storage` i MCP-verktyget `run`) åsidosätter den för den körningen.
- Att ändra inställningen påverkar aldrig filer du redan har; ta bort dem med [`DELETE /requests/{id}/files`](#delete-files).
- När API-saldot inte kan betala för lagring debiteras inget och du får ett e-postmeddelande: fyll på inom 30 dagar, annars blir de sparade filerna tillfälliga och raderas 7 dagar senare.

I det sällsynta fall att vår kopia misslyckas har posten `"stored": false` och URL:en är den ursprungliga, kortlivade URL:en: hämta den snart.
