Authentication
Every Radient API request carries exactly one credential in the Authorization header, as a Bearer token:
Authorization: Bearer YOUR_API_KEY
There is no x-api-key header and no query-string key. A request without a credential is answered 401 with {"error":"missing Authorization header"}.
There are three credential types, each for a different caller:
| Credential | Who uses it | Lifetime |
|---|---|---|
Application API key (rad-prod-…) | Your servers and tools calling the API | Until you revoke it |
| User token (access + refresh) | The console, the CLI, and any app you sign in to with your Radient account | Access token: 1 hour; refresh rotates |
| Client token | Anonymous browser contexts using the contact form | 30 minutes |
#API keys
Create a key from the console's Applications page, or programmatically with a user token:
curl https://api.radienthq.com/v1/tenants/{tenant_id}/applications \
-H "Authorization: Bearer $RADIENT_USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "my-app", "description": "production key"}'
The response (201) contains the key itself, shown once:
{
"msg": "Application created successfully",
"result": {
"id": "e095204a-…",
"name": "my-app",
"api_key": "rad-prod-<64 hex characters, shown once>",
"...": "…"
}
}
Store it then — later reads of the application list return the application's metadata and a keyed hash of the key, never the key itself.
- Use it as
Authorization: Bearer rad-prod-…. - List / rename / delete keys with
GET,PATCHandDELETEon/v1/tenants/{tenant_id}/applications[/{application_id}](user token required — an API key cannot manage keys). - Revocation lag: authentication results are cached briefly, so a key that was just deleted can keep authenticating for up to about five minutes; it starts answering
401only once its cache entry expires. If you need access to stop immediately, revoke your other credentials for the account too.
Unrecognised credentials are refused with a specific message, all 401:
| Body | Cause |
|---|---|
{"error":"invalid API key format"} | The bearer is not a user token and not three dash-separated rad-… segments |
{"error":"invalid API key"} | Well-formed key, but unknown or revoked |
{"error":"API key is not a Radient key"} | Key-shaped, but without the rad- prefix |
#User tokens
Signing in with Google or Microsoft mints a user token pair: an access token (1 hour) and a refresh token. Access tokens are accepted anywhere the API expects "user token"; refresh tokens are used only with the refresh endpoints. Refresh tokens last 7 days from a sign-in and up to 90 days when rotated.
Endpoints (all unauthenticated unless noted):
| Endpoint | Purpose |
|---|---|
POST /v1/auth/google, POST /v1/auth/microsoft | Sign in with a provider token |
POST /v1/auth/google/refresh, POST /v1/auth/microsoft/refresh, POST /v1/auth/token | Exchange a refresh token for a new pair |
POST /v1/auth/revoke | Revoke a refresh token |
Applications that sign users in to Radient use the OAuth 2.0 authorization-code flow with PKCE (/v1/auth/oauth/request, /v1/auth/oauth/code, /v1/auth/oauth/token). Client registrations for this flow are managed by Radient — contact us if you are building an integration. POST /v1/auth/oauth/token accepts authorization_code and refresh_token grants; anything else answers 400 {"error":"Unsupported grant_type: <value>"}.
If a token is expired or invalid, the API answers 401 — {"error":"invalid or expired token"} on routes that accept only user tokens. One quirk worth knowing: on routes that accept either credential, the bearer is interpreted as a user token first, so an expired user token on such a route is reported as {"error":"invalid API key format"}. Re-authenticate and retry.
#Which credential reaches which routes
| Route group | API key | User token |
|---|---|---|
Inference, tools, media, decisions, GET /v1/models | ✓ | ✓ |
GET /v1/usage (account usage summary) | ✓ | ✓ |
/v1/tenants/{tenant_id}/… (usage, billing, ledger, auto-reload, transfers, members, invites, plan, applications) | — | ✓ |
/v1/me, /v1/me/memberships, /v1/me/billing-sources… | — | ✓ |
/v1/accounts/{account_id}, notifications | — | ✓ |
POST /v1/email/self/send | ✓ | — |
Sign-in, OAuth token, /v1/web/client-token | unauthenticated | unauthenticated |
An API key presented to a user-token-only route answers 401 {"error":"invalid or expired token"}. A user token presented to the email route answers 401 as well.
#Client tokens
POST /v1/web/client-token issues a 30-minute token for the contact form on the marketing site. Send a JSON body with the site's client id:
curl https://api.radienthq.com/v1/web/client-token \
-H "Content-Type: application/json" \
-d '{"radient_client_id": "YOUR_CLIENT_ID"}'
{"msg": "Client token created", "result": {"token": "…", "expires_in": 1800}}
- Missing id →
400 {"error":"Radient client ID is required"}; unknown id →404 {"error":"Client ID not found"}. - The token is consumed only by
POST /v1/web/contact({name, email, inquiryType, message, subscribe}).
#Keeping credentials safe
- API keys and user tokens are secrets: keep them server-side. Never ship a key in a browser bundle, a mobile app, a public repository or a screenshot.
- If a key may have leaked, delete it and create a new one; expect the revocation lag above.
- Use separate applications (keys) per environment or service so one can be rotated without touching the others.
See also: Usage and credits API for how usage is attributed to accounts and keys.