Auth API (OIDC)
The public integrator surface of auth.codai.ro: discovery, authorization code + PKCE, device flow, tokens, logout and /connect/key.
auth.codai.ro is a standard OpenID Provider; read /.well-known/openid-configuration first and let your OIDC library drive the rest. The one codai-specific endpoint is GET /connect/key: exchange the access token for a scoped inference key (base_url: https://ai.codai.ro/v1). Only the endpoints an integrator calls are listed — the login/consent UI, account API and native app routes are first-party internals. OIDC errors are { "error", "error_description" }. Flow walkthrough: connect flow, scopes: scopes.
Provider metadata.
application/json- response
Subset of the discovery document that integrators rely on; the live document contains more keys.
issuer*stringuriauthorization_endpoint*stringuritoken_endpoint*stringuriuserinfo_endpoint?stringurijwks_uri*stringuriintrospection_endpoint?stringurirevocation_endpoint?stringuridevice_authorization_endpoint?stringuriend_session_endpoint?stringuriregistration_endpoint?stringDynamic client registration for public MCP clients (not documented here).
uriresponse_types_supported*array<string>grant_types_supported?array<string>token_endpoint_auth_methods_supported?array<string>scopes_supported?array<string>claims_supported?array<string>code_challenge_methods_supported?array<string>acr_values_supported?array<string>subject_types_supported*array<string>id_token_signing_alg_values_supported*array<string>backchannel_logout_supported?booleancurl -X GET 'https://auth.codai.ro/.well-known/openid-configuration'{ "issuer": "https://auth.codai.ro", "authorization_endpoint": "http://example.com", "token_endpoint": "http://example.com", "userinfo_endpoint": "http://example.com", "jwks_uri": "http://example.com", "introspection_endpoint": "http://example.com", "revocation_endpoint": "http://example.com", "device_authorization_endpoint": "http://example.com", "end_session_endpoint": "http://example.com", "registration_endpoint": "http://example.com", "response_types_supported": [ "string" ], "grant_types_supported": [ "string" ], "token_endpoint_auth_methods_supported": [ "string" ], "scopes_supported": [ "string" ], "claims_supported": [ "string" ], "code_challenge_methods_supported": [ "S256" ], "acr_values_supported": [ "string" ], "subject_types_supported": [ "string" ], "id_token_signing_alg_values_supported": [ "string" ], "backchannel_logout_supported": true}JSON Web Key Set.
application/json- response
keys*array<>curl -X GET 'https://auth.codai.ro/jwks'{ "keys": [ { "kty": "RSA", "kid": "string", "use": "sig", "alg": "RS256", "n": "string", "e": "string" } ]}response_type*"code"Must be code.
"code"client_id*stringRegistered client identifier.
redirect_uri*stringOne of the client's registered redirect URIs (exact match).
uriscope*stringSpace-separated scopes; must include openid.
state?stringOpaque CSRF value echoed back on the redirect. Strongly recommended.
code_challenge*stringBASE64URL(SHA-256(code_verifier)) — PKCE is required for every client.
code_challenge_method*"S256"Only S256 is supported.
"S256"nonce?stringReplay protection echoed into the ID token.
prompt?stringStandard OIDC prompt values (login, consent, none, select_account).
acr_values?stringRequested authentication context; passkey/mfa trigger step-up.
resource?stringRFC 8707 resource indicator. https://ai.codai.ro/mcp yields a JWT access token with the mcp scope.
urimode?"signup"codai extension — signup opens the sign-up form directly.
"signup"ref?stringcodai extension — referral code (codai.ro/r/<username>, 3–20 chars [A-Za-z0-9_]) pre-filled on sign-up.
^[A-Za-z0-9_]{3,20}$lang?stringUI language of the login pages. Defaults from the NEXT_LOCALE cookie, then Accept-Language.
"ro""en"Redirect to the codai login/consent UI, or back to redirect_uri with code+state (or error).
curl -X GET 'https://auth.codai.ro/auth?response_type=code&client_id=metu&redirect_uri=http%3A%2F%2Fexample.com&scope=openid+email+profile+inference+keys%3Amanage&code_challenge=string&code_challenge_method=S256'application/x-www-form-urlencoded- body
client_id*stringscope?stringSpace-separated scopes.
resource?stringOptional RFC 8707 resource indicator.
uriDevice authorization issued.
application/json- response
device_code*stringuser_code*stringShown to the user; format ****-****.
verification_uri*stringuriverification_uri_complete*stringverification_uri with the user_code pre-filled.
uriexpires_in*integerSeconds until the device code expires.
interval?integerMinimum seconds between /token polls.
curl -X POST 'https://auth.codai.ro/device/auth' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'client_id=codai-cli'{ "device_code": "string", "user_code": "BCDF-GHJK", "verification_uri": "https://auth.codai.ro/device", "verification_uri_complete": "http://example.com", "expires_in": 0, "interval": 5}clientSecretBasicAuthorizationBasic <token>client_secret_basic client authentication. client_secret_post and private_key_jwt go in the form body instead; public clients send only client_id.
application/x-www-form-urlencoded- body
Form-encoded body. Fields depend on grant_type; client credentials depend on the client's authentication method.
grant_type*string"authorization_code""refresh_token""urn:ietf:params:oauth:grant-type:device_code"code?stringauthorization_code — the code from the redirect.
redirect_uri?stringauthorization_code — must equal the value used at /auth.
uricode_verifier?stringauthorization_code — PKCE verifier (43–128 chars) whose S256 hash was sent as code_challenge.
refresh_token?stringrefresh_token grant.
device_code?stringdevice_code grant — from /device/auth.
scope?stringOptional down-scoping on refresh.
resource?stringRFC 8707 resource indicator.
uriclient_id?stringPublic clients (none) and client_secret_post.
client_secret?stringclient_secret_post only.
client_assertion_type?stringprivate_key_jwt only.
client_assertion?stringprivate_key_jwt — JWT signed with a key from the client's registered jwks / jwks_uri.
Tokens issued.
application/json- response
access_token*stringOpaque (1 h), or an RS256 JWT when resource=https://ai.codai.ro/mcp.
token_type*stringexpires_in*integerscope?stringGranted scopes, space-separated.
id_token?stringPresent when openid was granted. Includes sub, role, sid, auth_time, acr, amr, nonce.
refresh_token?stringOnly when the client allows refresh_token and offline_access was granted. Rotated on every refresh for public clients.
curl -X POST 'https://auth.codai.ro/token' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'grant_type=authorization_code'{ "access_token": "string", "token_type": "Bearer", "expires_in": 3600, "scope": "string", "id_token": "string", "refresh_token": "string"}clientSecretBasicAuthorizationBasic <token>client_secret_basic client authentication. client_secret_post and private_key_jwt go in the form body instead; public clients send only client_id.
application/x-www-form-urlencoded- body
token*stringtoken_type_hint?string"access_token""refresh_token"client_id?stringFor client_secret_post / none.
client_secret?stringFor client_secret_post.
client_assertion_type?stringFor private_key_jwt.
client_assertion?stringIntrospection result (also for inactive tokens).
application/json- response
active*booleanscope?stringclient_id?stringsub?stringUser id (UUID).
token_type?stringexp?integeriat?integeriss?stringuriaud?stringResource indicator the token was minted for.
jti?stringcurl -X POST 'https://auth.codai.ro/token/introspection' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'token=string'{ "active": true, "scope": "string", "client_id": "string", "sub": "string", "token_type": "string", "exp": 0, "iat": 0, "iss": "http://example.com", "aud": "string", "jti": "string"}clientSecretBasicAuthorizationBasic <token>client_secret_basic client authentication. client_secret_post and private_key_jwt go in the form body instead; public clients send only client_id.
application/x-www-form-urlencoded- body
token*stringtoken_type_hint?string"access_token""refresh_token"client_id?stringclient_secret?stringclient_assertion_type?stringclient_assertion?stringToken revoked (or already invalid). Empty body.
curl -X POST 'https://auth.codai.ro/token/revocation' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'token=string'bearerAuthAuthorizationBearer <token>OAuth access token issued by /token (used by /me and /connect/key).
Claims for the token's subject.
application/json- response
sub*stringcodai user id (UUID).
email?stringemailemail_verified?booleanname?stringpicture?stringuricurl -X GET 'https://auth.codai.ro/me'{ "sub": "string", "email": "user@example.com", "email_verified": true, "name": "string", "picture": "http://example.com"}id_token_hint?stringThe ID token previously issued to this client; identifies the session and client.
post_logout_redirect_uri?stringRegistered post-logout redirect URI of the client.
uristate?stringOpaque value appended to the post-logout redirect.
client_id?stringRequired when id_token_hint is absent and a post_logout_redirect_uri is given.
ui_locales?stringStandard OIDC parameter; the codai UI reads ?lang=ro|en instead.
Logout confirmation page (or "signed out" page).
response?stringtext/htmlcurl -X GET 'https://auth.codai.ro/session/end'"string"bearerAuthAuthorizationBearer <token>OAuth access token issued by /token (used by /me and /connect/key).
X-Codai-Device-Name?stringFirst-party clients only — label (≤ 60 chars) for the per-device key; defaults to Desktop.
length <= 60Key minted (first call) or already issued.
application/json- response
api_key*|Plaintext key, returned only once per grant (null afterwards). Store it sealed.
api_key_id*stringStable id of the minted key (revocable from the console).
uuidbase_url*stringOpenAI-compatible base URL to use the key against.
urimodel*stringalready_issued*booleantrue when the plaintext was already handed out on an earlier call.
curl -X GET 'https://auth.codai.ro/connect/key'{ "api_key": "codai_xxxxxxxxxxxxxxxxxxxxxxxx", "api_key_id": "b0dd218e-3bcf-4bdb-a1e3-0689d60a8afd", "base_url": "https://ai.codai.ro/v1", "model": "codai", "already_issued": true}curl -X OPTIONS 'https://auth.codai.ro/connect/key'Process is up.
application/json- response
ok*booleancurl -X GET 'https://auth.codai.ro/health'{ "ok": true}Database reachable.
application/json- response
ok*booleanchecks*curl -X GET 'https://auth.codai.ro/health/ready'{ "ok": true, "checks": { "db": { "ok": true, "error": "string" } }}Last updated: