# Limite și prețuri (/ro/docs/gateway/limits-pricing)

Rate limits, plafoane de cheltuieli, plafoane de sarcini, chitanța de cost și contractul de erori.

codai facturează per **sarcină verificată**, nu per token — comparația planurilor este pe [codai.ro/pricing](https://codai.ro/pricing), iar cheltuiala ta live e în [hub.codai.ro](https://hub.codai.ro). Pagina asta acoperă ce aplică gateway-ul la fiecare cerere și cum îți spune când ai lovit un zid.

## Rate limits [#rate-limits]

Limitele au fereastră glisantă și vin din planul tău. Fiecare cheie are propria fereastră (cheile emise de o aplicație împart o fereastră per abonament). Valorile pe plan:

<PlanLimitsTable locale="ro" />

- **Cereri pe oră** este o plasă de siguranță de 30 × limita pe minut.
- **Tokeni de input pe minut** este valoarea implicită pentru toate planurile; o cheie poate avea o limită mai mică, setată în hub.
- **Servere MCP proprii** înseamnă câte servere MCP ale tale poți conecta; o liniuță înseamnă că planul nu le include.
- Tabelul e generat din același catalog de planuri ca [codai.ro/pricing](https://codai.ro/pricing) și `codai.ro/pricing.json`.

Fiecare răspuns poartă starea curentă. Exemplu pentru o cheie Builder:

```text
x-ratelimit-limit-minute: 100
x-ratelimit-remaining-minute: 97
x-ratelimit-reset-minute: 1790000060
x-ratelimit-limit-hour: 3000
x-ratelimit-remaining-hour: 2951
x-ratelimit-reset-hour: 1790003600
```

Valorile `reset` sunt timestamp-uri Unix în secunde. Citește limitele din header-e în loc să le hardcodezi: o limită per cheie setată în hub sau o schimbare de plan se aplică fără nicio modificare în client.

Se aplică trei ferestre:

| Fereastră | Ce numără | Cod de eroare |
| --- | --- | --- |
| Cereri per minut / per oră | Fiecare cerere `/v1/*` și `/mcp`. | `rate_limit_exceeded` |
| Tokeni de input per minut | Tokenii de prompt înregistrați efectiv, cu **scrierile** în cache la 25 % greutate și **citirile** din cache excluse complet. 1 500 000/min, dacă cheia nu are o limită mai mică. | `rate_limit_exceeded` |
| Tokeni de output per minut | Tokeni de completion, per utilizator peste toate cheile: 20 000/min pe Free, 100 000/min pe planurile plătite. | `rate_limit_exceeded` |

Pentru că citirile din cache sunt gratuite în fereastra de tokeni, a ține [prompt caching](./headers.mdx#caching) pornit este și felul în care rămâi sub limită în sesiuni lungi de agent.

### Respectă `Retry-After` [#respectă-retry-after]

La fiecare `429` gateway-ul setează `Retry-After` la numărul **exact** de secunde până când cea mai veche intrare iese din fereastră — nu un 60 fix. Clienții care îl respectă găsesc un loc liber la prima reîncercare; clienții care îl ignoră bombardează gateway-ul și rămân blocați. [SDK-urile](../sdks/index.mdx) reîncearcă `429` și `5xx` cu backoff automat.

## Plafoane de sarcini [#plafoane-de-sarcini]

O **sarcină** începe la o tură proaspătă de utilizator; continuările cu rezultat de unealtă și follow-up-urile din aceeași conversație nu pornesc altele noi. Planurile includ un număr de **sarcini verificate pe lună**:

| Plan | Sarcini verificate pe lună |
| --- | --- |
| Free | 5 |
| Starter | 33 |
| Builder | 83 |
| Team | 250 |

Peste alocare, fiecare sarcină verificată se facturează ca depășire cu **1,20 €**, când facturarea ta permite depășirea. Cei 1,20 € acoperă până la 1,20 € consum de model pentru acea sarcină; sarcinile neobișnuit de mari (peste 1,20 € consum de model) plătesc diferența la tarifele standard pe tokeni, niciodată sub 1,2× costul upstream. Detalii în [sarcini și cheltuieli](../agents/tasks-and-spend.mdx). Când nimic nu plătește o sarcină nouă:

- Gateway-ul returnează `429` cu codul `quota_exceeded` și un `Retry-After` care indică resetarea.
- **Conversațiile pe care le-ai pornit deja continuă să funcționeze** — doar sarcinile nou-nouțe sunt puse în pauză.
- Apelurile utilitare pe `codai-fast` cu `X-Codai-No-Task: 1`, embeddings, audio și realtime nu contează niciodată.

`quota_exceeded` este intenționat un `429`, nu un `403`: clienții IDE îl tratează ca „back off și reîncearcă mai târziu” în loc să reîncerce la fiecare câteva secunde.

## Plafoane de cheltuieli [#plafoane-de-cheltuieli]

Conturile pot purta un plafon **zilnic** și unul **lunar** de cheltuieli, setat în EUR în hub și însumat peste toate cheile. Plafonul e o barieră de protecție, nu o factură: gateway-ul îl compară unu la unu cu costul upstream pe care îl măsoară, exprimat în USD — de aici numele header-elor cu `-usd`. Când e activ, fiecare răspuns raportează unde te afli:

```text
x-codai-spend-day-usd: 3.42
x-codai-spend-day-cap-usd: 20.00
x-codai-spend-month-usd: 41.90
x-codai-spend-month-cap-usd: 300.00
```

Depășirea unui plafon returnează `429 rate_limit_exceeded` cu un mesaj care numește fereastra (plafoanele zilnice se resetează la miezul nopții UTC, cele lunare pe 1 UTC). Setezi bugete per cheie în hub la **Keys** — bugetul cheii e un prag sub plafonul contului, niciodată peste el.

### Imagini [#imagini]

[Generarea și editarea de imagini](./embeddings-audio.mdx#generare-de-imagini) se facturează după **tokenii raportați de model**, la tarifele Vertex ale modelului care a servit apelul — tokenii imaginii generate, textul de intrare și imaginile de intrare/referință. Prețul aproximativ al unei imagini 1K fără imagini de referință:

| `model` | ≈ USD per imagine 1K |
| --- | --- |
| `codai-image` (implicit, UE) | 0,074 USD |
| `codai-image-fast` | 0,034 USD |
| `codai-image-pro` | 0,134 USD |

Valorile mai mari pentru `image_size` și imaginile de referință costă mai mult. Costul e raportat în `x-codai-cost-micro-usd`, apare în chitanță și **intră în plafoanele de cheltuieli zilnice și lunare** ca orice alt cost. Pe planurile preplătite, **portofelul în EUR e debitat** și pentru imagini, cu acest cost în USD convertit în EUR și un multiplicator de serviciu de 1,3 (≈ 0,083 € pentru o imagine implicită). Apelurile de imagine nu pornesc niciodată o sarcină, deci nu consumă din alocarea de sarcini. O cerere ale cărei imagini sunt toate blocate de filtrul de siguranță (`content_filtered`) nu costă nimic.

## Plafon per cerere [#plafon-per-cerere]

O singură cerere de nivel superior — inclusiv candidații best-of, apelurile de judecător și delegările către sub-agenți pe care gateway-ul le pornește pentru ea — se oprește devreme cu un răspuns parțial odată ce costul ei cumulat trece de **5 USD**. Chat-ul simplu nu se apropie niciodată de el; există ca o buclă de agent scăpată de sub control să nu poată factura o sumă nelimitată într-un singur apel.

## Verificarea politicii de utilizare [#verificarea-politicii-de-utilizare]

Pașii de agent care ar putea încălca politicile de utilizare ale furnizorilor de modele sunt verificați înainte să fie trimiși mai departe. Un pas evaluat ca fals pozitiv trece neschimbat. Altfel gateway-ul **nu** întoarce o eroare: răspunsul e un mesaj normal de asistent cu `200`, care îi spune agentului ce context legitim lipsește (al cui e sistemul, ce autorizare există, ce scop defensiv are) sau ce parte să renunțe. După **3 pași semnalați la rând** în 24 de ore, mesajul îi cere agentului să nu mai urmărească acel obiectiv, iar pașii suspecți următori sunt refuzați la fel până expiră fereastra; restul lucrului nu e afectat. Aceste răspunsuri au antetele `x-codai-policy` (`ambiguous`, `violating`, `refused`, `refused-remembered` sau `cleared` pentru un fals pozitiv verificat) și `x-codai-policy-strikes` și nu costă nimic. Reformularea unei cereri ca să ocolească verificarea contează ca încă un avertisment.

## Dimensiunea body-ului [#dimensiunea-body-ului]

Body-urile cererilor pe `/v1/*` sunt limitate la **12 MB**. Body-urile mai mari primesc `413` cu codul `payload_too_large`. Încărcările audio sunt limitate separat la 25 MB pe `/v1/audio/transcriptions`.

## Chitanța de cost [#chitanța-de-cost]

Fiecare răspuns de chat sau messages poartă costul *acelei* cereri când poate fi cunoscut înaintea primului byte:

```text
x-codai-upstream: claude-opus-5-5
x-codai-cost-micro-usd: 18420
```

Micro-USD sunt numere întregi — `18420` înseamnă 0,01842 $. Pe stream-urile native numărul nu e cunoscut la momentul header-elor, așa că primești în loc `x-codai-cost-estimate: pending`, iar cifra exactă ajunge în endpoint-ul de chitanță:

```bash
# ultimele 24 de ore (implicit)
curl https://ai.codai.ro/v1/receipt -H "Authorization: Bearer $CODAI_API_KEY"

# o sesiune
curl "https://ai.codai.ro/v1/receipt?session_id=my-project" -H "Authorization: Bearer $CODAI_API_KEY"

# de la un timestamp
curl "https://ai.codai.ro/v1/receipt?since=2026-09-01T00:00:00Z" -H "Authorization: Bearer $CODAI_API_KEY"
```

```json
{
  "events": 142,
  "tasks": 9,
  "cost_micro_usd_total": 1834200,
  "cost_usd": 1.8342,
  "prompt_tokens": 2210034,
  "completion_tokens": 41890,
  "cached_read_tokens": 1988001,
  "cache_write_tokens": 120433,
  "by_upstream": [
    { "upstream_model": "claude-opus-5-5", "events": 130, "cost_micro_usd": 1801000 },
    { "upstream_model": "claude-haiku-5-5", "events": 12, "cost_micro_usd": 33200 }
  ],
  "window": { "from": "2026-09-22T09:00:00.000Z", "to": "2026-09-23T09:00:00.000Z", "session_id": null }
}
```

`tasks` este numărul de porniri de sarcini facturabile din fereastră. `session_id` se potrivește fie cu `X-Codai-Session-Id` pe care l-ai trimis, fie cu cheia derivată de gateway pentru clienții fără header. Numărul de tokeni sunt cifrele **reale** de la upstream — parsate din `message_delta.usage` pe stream-urile Anthropic și din chunk-ul final de usage pe stream-urile OpenAI — nu numărul afișat de un client.

Prețurile per model upstream sunt afișate în hub lângă fiecare rând de usage; gateway-ul nu are un endpoint separat de prețuri.

## Contractul de erori [#contractul-de-erori]

Erorile folosesc anvelopa OpenAI pe fiecare suprafață, așa că un client OpenAI-compatibil le parsează neschimbat:

```json
{
  "error": {
    "message": "You're sending requests a little too fast — the limit is 100 requests per minute …",
    "type": "rate_limit_error",
    "code": "rate_limit_exceeded"
  }
}
```

`code` este stabil și citibil de mașină; `message` este pentru oameni și se poate schimba. Eșecurile de validare adaugă un obiect `details` cu căile câmpurilor care au picat. Numele providerilor upstream sunt curățate din mesaje — vezi ce a picat, niciodată care cloud a servit.

| HTTP | `code` | `type` | Când |
| --- | --- | --- | --- |
| 400 | `bad_request` | `invalid_request_error` | JSON invalid, încălcare de schemă (vezi `details`), funcție Responses nesuportată, `X-Codai-No-Task` pe un alias neutilitar, model audio sau de imagine necunoscut, `response_format` media diferit de `b64_json` sau `url`. |
| 400 | `content_filtered` | `invalid_request_error` | Filtrul de siguranță pentru imagini a blocat toate imaginile generate. Nu se taxează. |
| 401 | `invalid_api_key` | `invalid_request_error` | Cheie lipsă, malformată, revocată sau necunoscută; token efemer pe suprafața greșită. |
| 402 | `subscription_inactive` | `subscription_required` | Abonamentul cheii nu este activ. |
| 403 | `forbidden` | `invalid_request_error` | Model neinclus în allowlist-ul cheii; mod agent fără tier cu unelte; token efemer care încearcă să genereze tokeni. |
| 404 | `not_found` | `invalid_request_error` | Rută sau metodă necunoscută. Verifici base URL-ul — `/v1` versus rădăcină e cauza obișnuită. |
| 413 | `payload_too_large` | `invalid_request_error` | Body peste 12 MB. |
| 429 | `rate_limit_exceeded` | `rate_limit_error` | Fereastră de cereri, tokeni de input sau tokeni de output epuizată; plafon zilnic sau lunar de cheltuieli atins. Are `Retry-After`. |
| 429 | `quota_exceeded` | `rate_limit_error` | Alocarea de sarcini a planului consumată. Are `Retry-After` care indică resetarea. |
| 502 | `upstream_error` | `upstream_error` | Providerul upstream a picat după reîncercările și failover-ul gateway-ului. Sigur de reîncercat. |
| 500 | `internal_error` | `server_error` | Defect al gateway-ului. Raportat automat; sigur de reîncercat. |
| 503 | `assets_unavailable` | `invalid_request_error` | `response_format: "url"` sau `/v1/assets` pe un gateway fără stocare de asset-uri. Folosește `b64_json`. |

Eșecurile din mijlocul unui stream nu pot schimba codul de status (header-ele au fost deja trimise); gateway-ul închide stream-ul cu un frame de stop curat și înregistrează tura ca blocată. Reîncerci cererea — prompt caching o face ieftină.

### Ce se înregistrează la eșec [#ce-se-înregistrează-la-eșec]

Cererile eșuate sunt înregistrate și ele, cu codul de eroare și `is_task_start = 0` — o încercare eșuată nu facturează niciodată o sarcină, iar orice consum de sarcini rezervat înainte de dispatch este rambursat.
