Referință API
Cum citești referința — URL-uri de bază, autentificare, plicul de eroare, convențiile SSE și unde se anunță schimbările.
Referința e generată din documente OpenAPI 3.1 scrise de mână, care oglindesc codul rută cu rută. Un test de paritate din repo pică ori de câte ori o rută publică există fără documentație sau o rută documentată nu mai există, așa că ce citești aici e ce înregistrează serverele.
Trei servicii, trei URL-uri de bază
| Serviciu | URL de bază | Referință | Autentificare |
|---|---|---|---|
| Gateway (inferență + platformă) | https://ai.codai.ro | Gateway | Authorization: Bearer codai_… |
| Resolve (fix-uri verificate) | https://resolve.codai.ro | Resolve | aceeași cheie codai_ |
| Auth (OpenID Provider) | https://auth.codai.ro | Auth | OAuth 2.1 / OIDC |
Panourile „încearcă” din fiecare operație trimit cereri reale din browserul tău. Lipește o cheie cu care ești dispus să cheltuiești câțiva cenți; panourile nu o stochează niciodată.
Autentificare
Fiecare apel către gateway și Resolve poartă o cheie API codai în header-ul bearer. Cheile încep cu codai_, sunt afișate o singură dată în hub și pot fi revocate de acolo. /v1/messages acceptă și header-ul x-api-key în stil Anthropic. Tokenurile efemere de la POST /v1/tokens sunt acceptate doar de WebSocket-ul realtime — o cheie brută în query string e refuzată.
Aplicațiile care autentifică utilizatori obțin o cheie cu scope-uri prin fluxul connect OIDC, în loc să ceară una.
Plicul de eroare
Gateway-ul răspunde la orice eșec cu o singură formă JSON:
{
"error": {
"message": "Invalid request body",
"type": "invalid_request_error",
"code": "bad_request",
"details": { "fieldErrors": { "messages": ["Required"] } }
}
}| Status | code | Când |
|---|---|---|
| 400 | bad_request | Body-ul sau query-ul a picat validarea — details conține erorile pe câmpuri |
| 401 | invalid_api_key | Cheie lipsă, revocată sau pusă pe pauză |
| 402 | subscription_inactive | Abonamentul din spatele cheii e inactiv |
| 403 | forbidden | A picat verificarea de allow-list de modele, rol sau proprietate |
| 404 | not_found | Resursa nu există sau aparține altcuiva |
| 409 | lease_held, seq_conflict, task_not_confirmable, host_offline | Conflicte de concurență optimistă pe sesiuni, task-uri și host-uri |
| 413 | payload_too_large | Body-ul cererii depășește 12 MB |
| 429 | rate_limit_exceeded, quota_exceeded | Limită de rată / plafon de cheltuieli sau cotă de task-uri — citește Retry-After |
| 502 | upstream_error | Toate lane-urile upstream au picat după failover |
| 503 | search_unavailable | Serviciul de căutare din spatele /v1/tools/search e căzut |
| 500 | internal_error | Defect neașteptat; ne-a fost deja raportat |
Resolve și Auth sunt servicii diferite, cu forme proprii, mai simple: Resolve returnează { "error": "<string>" }, Auth returnează perechea OAuth { "error", "error_description" }. Fiecare pagină de referință o documentează pe a sa.
Convenții de streaming
- Endpoint-urile SSE răspund cu
text/event-stream. Chat Completions, Messages și Responses folosesc framing-ul formatului lor wire; chunk-ul de usage pe un stream Chat Completions e emis mereu, indiferent ce spunestream_options. - Stream-urile proprii codai (agenți, sesiuni, host-uri) folosesc frame-uri
event:numite, documentate la fiecare operație, plus comentarii: pingca heartbeat acolo unde e notat. - Niciun stream nu emite linii
id:șiLast-Event-IDnu e citit. Reiei cu cursorul oferit de endpoint (afterla sesiuni) sau accepți un replay complet (agenți). - Header-ele de cost pe un stream arată
x-codai-cost-estimate: pending; costul măsurat ajunge mai târziu înGET /v1/receipt.
Versionare și schimbări
Gateway-ul nu e versionat dincolo de prefixul /v1. Schimbările aditive (câmpuri noi, header-e noi, endpoint-uri noi) se livrează fără anunț; orice elimină sau redenumește e anunțat întâi în changelog. Numele câmpurilor sunt returnate exact cum le trimite codul — câteva obiecte amestecă camelCase și snake_case, iar referința reflectă asta în loc s-o ascundă.