# Header-e de cerere (/ro/docs/gateway/headers)

Fiecare header pe care gateway-ul îl citește și fiecare header pe care îl trimite înapoi — autentificare, identitate de client, caching, effort, thinking, sesiuni, sarcini, cost.

Toate header-ele codai sunt opționale și insensibile la majuscule. Le trimiți pe `POST /v1/chat/completions`, `POST /v1/messages` și `POST /v1/responses` (ruta Responses trimite mai departe fiecare header `X-Codai-*` către ruta de chat în care reintră). Tot ce trimiți și gateway-ul nu înțelege este ignorat.

## Autentificare [#autentificare]

| Header | Valoare |
| --- | --- |
| `Authorization` | `Bearer codai_…` — cheia ta API, sau un token efemer `codai_eph_v1.…` pe suprafețele media. Obligatoriu peste tot, cu excepția endpoint-urilor publice `/vscode/*`, `/copilot/*`, `/health` și `/status`. |
| `x-api-key` | Acceptat doar pe `POST /v1/messages`, pentru SDK-urile Anthropic. `Authorization` câștigă dacă sunt prezente ambele. |
| `anthropic-version`, `anthropic-beta`, `openai-beta` | Acceptate și ignorate. Gateway-ul construiește singur header-ele către upstream și își setează propriile beta Anthropic; valoarea `anthropic-beta` a clientului nu e trimisă mai departe. |

O cheie lipsă sau necunoscută dă `401 invalid_api_key`. O cheie dintr-un abonament inactiv dă `402 subscription_inactive`.

## Identitatea clientului [#identitatea-clientului]

| Header | Efect |
| --- | --- |
| `X-Codai-Client` | Cine apelează, ca `<suprafață>/<versiune>` — `desktop/1.4.0`, `phone-android/0.9.2`, `codai-cli/0.3.0`, `hub/…`. Determină atribuirea sarcinilor: `desktop` și `cli` pot raporta singure rezultatul sarcinii; tot restul (IDE-uri, SDK-uri brute, curl) este `proxy` și sarcinile lui se închid doar prin confirmare explicită a utilizatorului în hub. Cade pe `User-Agent` când lipsește. |
| `X-Request-Id` | Id-ul tău de corelare. Reflectat înapoi ca `x-codai-trace-id`, trimis către upstream și utilizabil ca `client_request_id` în `POST /v1/feedback`. |
| `X-Codai-Repo` | Identificator de repository pentru scoparea memoriei. Când lipsește, gateway-ul deduce scopul din transcript. |
| `X-Codai-Agent-Id` | Id de atribuire înregistrat pe apelurile de tool în flote de agenți. `[A-Za-z0-9._:-]`, maximum 128 caractere. |

### Versiuni minime de client [#versiuni-minime-de-client]

Pe fiecare rută `/v1/*`, gateway-ul compară versiunea din `X-Codai-Client` (`<aplicație>/<semver>`, aplicațiile `desktop`, `phone-android` — `phone` e acceptat ca alias — `web` și `cli`) cu două minime configurate pe server, per aplicație: `CODAI_MIN_CLIENT` (obligatoriu) și `CODAI_RECOMMENDED_CLIENT` (recomandat), de ex. `desktop=0.9.0,phone-android=3.0.0`. Ridicarea unui minim e o schimbare de configurație, nu un deploy de cod.

- Sub minimul **obligatoriu**, cererea e respinsă cu **`426 client_outdated`**; `error.details` conține `app`, `min_version` și `download_url`.
- Sub minimul **recomandat**, cererea e servită normal, iar răspunsul poartă `x-codai-upgrade: recommended; min=<versiune>`.
- Un `X-Codai-Client` lipsă, necunoscut sau imposibil de interpretat (SDK-uri terțe, curl, build-uri de dezvoltare) nu e blocat niciodată.

```json
{ "error": { "type": "invalid_request_error", "code": "client_outdated", "message": "This codai app is too old (minimum 0.9.0). Update it to continue.", "details": { "app": "desktop", "min_version": "0.9.0", "download_url": "https://codai.ro/download" } } }
```

`x-codai-upgrade` e destinat aplicațiilor codai și nu apare în lista CORS de header-e expuse de mai jos.

## Caching [#caching]

| Header | Efect |
| --- | --- |
| `X-Codai-Cache` | Prompt caching este **pornit implicit** pentru fiecare model. `0` sau `false` îl oprește — **cu excepția** alias-urilor `codai*`, unde opt-out-ul este ignorat. Citirile din cache costă aproximativ a zecea parte din input-ul proaspăt, iar o buclă de agent necache-uită cu 170 k tokeni a costat odată un utilizator mii de dolari pe zi, așa că alias-ul router nu te lasă să-l dezactivezi. |

Pe răspuns: `x-codai-cache-read` și `x-codai-cache-write` poartă numărul de tokeni din cache când e cunoscut înaintea primului byte; `usage.prompt_tokens_details.cached_tokens` poartă numărul final de citiri în body.

## Effort și thinking [#effort-și-thinking]

| Header | Efect |
| --- | --- |
| `X-Codai-Effort` | `minimal` · `low` · `medium` (implicit) · `high` · `max`. Câștigă peste `reasoning_effort` din body. Vezi [modele](./models.mdx#effort-și-thinking). |
| `X-Codai-Thinking` | `1` sau `true` activează explicit extended thinking. |
| `X-Codai-Thinking-Budget` | Buget de thinking în tokeni (întreg pozitiv, implicit 16 384). |
| `X-Codai-Thinking-Pin` | `1` păstrează bugetul complet de thinking pe turele de continuare cu tool. Fără el, gateway-ul limitează bugetele injectate la 4 096 tokeni pe turele al căror ultim mesaj e un rezultat de tool, ca buclele de agent să nu plătească `max` la fiecare pas. |

Pe răspuns: `x-codai-effort`, `x-codai-effort-applied`, `x-codai-effort-continuation-dampened`.

## Sesiuni și memorie [#sesiuni-și-memorie]

| Header | Efect |
| --- | --- |
| `X-Codai-Session-Id` | Id stabil pentru o conversație logică. Activează sticky routing (ține prompt cache-urile calde), totaluri de cost per sesiune în `GET /v1/receipt` și memorie de sesiune. Header-ul bate `body.user`. Clienții IDE îl omit de obicei; gateway-ul derivă atunci o cheie din transcript. |
| `X-Codai-New-Session` | `1` pornește o sesiune persistentă nouă cu id proaspăt, ignorând orice `X-Codai-Session-Id`. |
| `X-Codai-No-Recall` | `1` sare citirea memoriei anterioare pentru această tură, dar o persistă totuși. |
| `X-Codai-Incognito` | `1` face tura complet stateless — nimic citit, nimic scris, fără sticky routing. |
| `X-Codai-Compact` | `auto` activează compactarea deterministă server-side a contextului (trunchiază rezultatele vechi de tool din afara cozii protejate, fără apel de model). `off` o dezactivează. Răspuns: `x-codai-compacted: true|false`. |

## Comportament de agent [#comportament-de-agent]

| Header | Efect |
| --- | --- |
| `X-Codai-Mode` | `agent` comută pe modul agent plan-and-execute (limită de adâncime ridicată, mesaj de sistem de planificare). Necesită un tier cu unelte și sub-agenți; altfel `403 forbidden`. Reflectat ca `x-codai-mode: agent`. |
| `X-Codai-Disable-Subagents` | `1` sare injectarea uneltei `delegate_to_model`. Configurația VS Code îl setează — Copilot își deține propria orchestrare. |
| `X-Codai-Best-Of` | `3` forțează best-of-N pe această cerere; `0` dezactivează auto-gate-ul. Răspuns: `x-codai-best-of-status`. |
| `X-Codai-Cascade` | `verify` forțează draft-and-verify pe această cerere. Răspuns: `x-codai-cascade-status`. |

## Sarcini și facturare [#sarcini-și-facturare]

codai facturează per **sarcină verificată**, nu per token. Aceste header-e leagă o cerere de sarcina ei.

| Header | Efect |
| --- | --- |
| `X-Codai-Task-Id` | Id-ul tău de sarcină (`[A-Za-z0-9._:-]`, maximum 128). Corelează toate turele unei sarcini; fără el gateway-ul derivă o cheie din transcript. |
| `X-Codai-Task-Outcome` | `pass` sau `fail`. Respectat doar de pe suprafețele `desktop` și `cli` **și** doar cu dovadă automată — altfel ignorat și logat. |
| `X-Codai-Task-Evidence` | `exec_verdict` sau `reexec` — ce dovedește rezultatul. Obligatoriu ca `X-Codai-Task-Outcome` să aibă efect. |
| `X-Codai-No-Task` | `1` scoate un apel utilitar din numărătoarea de sarcini. Respectat doar pe alias-uri utilitare precum `codai-fast`; pe o cerere `codai` completă este respins cu `400`, ca plafonul de sarcini să nu poată fi ocolit. |
| `X-Codai-Device`, `X-Codai-Device-Platform`, `X-Codai-Device-Name` | Înregistrarea dispozitivului pentru protocolul de sesiuni partajate (desktop, telefon). Nu e nevoie pentru apeluri API simple. |

Pe răspuns: `x-codai-task-id` (sarcina la care s-a atașat tura), `x-codai-event-id` (rândul de usage — îl trimiți la `POST /v1/feedback`).

## Header-e de răspuns [#header-e-de-răspuns]

| Header | Semnificație |
| --- | --- |
| `x-codai-routed-to` | Modelul upstream concret care a servit. |
| `x-codai-provider` | Tipul adaptorului de provider, de ex. `vertex-anthropic`. |
| `x-codai-upstream` | La fel ca `routed-to`, setat împreună cu chitanța de cost. |
| `x-codai-trace-id` | `X-Request-Id` al tău sau un UUID generat. |
| `x-codai-event-id` | Id-ul rândului `usage_events` pentru această cerere. |
| `x-codai-task-id` | Sarcina la care s-a atașat cererea. |
| `x-codai-cost-micro-usd` | Micro-USD întregi pentru această cerere, când e cunoscut la momentul header-elor. |
| `x-codai-cost-estimate` | `pending` pe stream-urile native — vezi `GET /v1/receipt`. |
| `x-codai-ai-generated` | `true` pe fiecare răspuns care conține output de model — chat, messages, responses, imagini, audio (vorbire și transcriere), muzică, video, randări, rulări de agent. Marcaj de conținut generat de AI, citibil automat (AI Act UE, art. 50 alin. (2)). Nu e setat niciodată pe erori. |
| `x-codai-generator` | `codai/<model upstream>` care a produs output-ul, de ex. `codai/claude-sonnet-5`; `codai/codai` când modelul nu e cunoscut la momentul header-elor. Trimis împreună cu `x-codai-ai-generated`. |
| `x-codai-cache-read`, `x-codai-cache-write` | Numărul de tokeni de cache când e cunoscut dinainte. |
| `x-codai-spend-day-usd`, `x-codai-spend-day-cap-usd`, `x-codai-spend-month-usd`, `x-codai-spend-month-cap-usd` | Cheltuiala ta curentă față de plafon, când plafoanele de cheltuieli sunt active pe contul tău. |
| `x-codai-exec-verify` | `passed` · `refined` · `refine_failed` · `skipped` · `error` pe răspunsurile `codai-labs` verificate prin execuție. |
| `x-codai-embed-fallback` | `<cerut>-><servit>` când un model de embedding a fost înlocuit. |
| `x-ratelimit-limit-minute`, `x-ratelimit-remaining-minute`, `x-ratelimit-reset-minute`, `x-ratelimit-limit-hour`, `x-ratelimit-remaining-hour`, `x-ratelimit-reset-hour` | Limite de cereri cu fereastră glisantă. `reset` este un timestamp Unix în secunde. |
| `Retry-After` | Pe `429`: secunde până când cea mai veche intrare iese din fereastră. Respectă-l — este exact, nu un 60 fix. |

Toate acestea sunt în lista CORS `Access-Control-Expose-Headers`, așa că codul din browser le poate citi.

## Idempotență [#idempotență]

Cererile de chat nu au `Idempotency-Key`. Reîncercarea unei cereri de chat creează o cerere nouă și un rând de usage nou; prompt caching face reîncercarea ieftină. Pentru o identitate stabilă peste reîncercări, trimiți același `X-Request-Id` — devine `client_request_id` pe rândul de usage și lasă `POST /v1/feedback` să țintească tura.

POST-urile Studio facturate (`/v1/videos`, `/v1/audio/music`, `/v1/studio/renders`, `/v1/studio/timelines`, `/v1/studio/documents/*`, randările și exporturile din `/v1/studio/creatives/*`, `/v1/studio/batches`) și rulările din sandbox acceptă `Idempotency-Key` (1-255 caractere ASCII tipăribile, păstrat 24 h):

- aceeași cheie + același corp: primești din nou primul răspuns, cu `idempotent-replayed: true`, și nu se mai taxează nimic;
- aceeași cheie + alt corp: `422 idempotency_key_mismatch`;
- prima cerere încă rulează: `409 idempotency_in_progress` — reîncearcă mai târziu.

O cerere eșuată eliberează cheia, deci o reîncercare cu aceeași cheie rulează din nou. În SDK-uri: `ext: { headers: { 'Idempotency-Key': key } }` (TypeScript), `ext={"headers": {"Idempotency-Key": key}}` (Python).

## Rezervarea din portofel pentru Studio [#rezervarea-din-portofel-pentru-studio]

Fiecare acțiune Studio plătită rezervă întâi prețul ei în portofel. Când soldul disponibil (portofel minus rezerva de compute minus rezervările deschise) nu ajunge, primești `402 insufficient_funds` cu `quote_micro_eur` și `balance_micro_eur`, iar nimic nu pornește și nu se taxează. Rezervarea se închide cu suma facturată când jobul se termină și se eliberează când eșuează. `GET /v1/studio/quote?action=video&seconds=8` îți arată prețul și `sufficient` înainte să rulezi ceva; e gratuit.
