Cookies keep FreeInd working. Optional analytics require your permission; ads for free accounts are served by Google, which shows its own consent message where required. Read our cookie policy.
Every /v1 endpoint is authenticated with a dashboard session cookie or a scoped API key. This page covers keys, scopes, workspace scoping, and errors.
All /v1 endpoints accept a dashboard session cookie or an API key:
Authorization: Bearer fi_live_<64-char-key>Keys are created in the dashboard (or with POST /v1/api-keys), hashed at rest (SHA-256), and the plaintext is shown exactly once. A revoked or expired key returns 401 unauthenticated.
Keys carry scopes; the all scope grants everything. Grant the minimum scopes each service needs:
| generations.write | Create + cancel generations |
| generations.read | List/detail generations, model catalog |
| files.write | Upload URLs, upload completion, asset mutate/delete |
| assets.read | Asset list/detail/download |
| usage.read | Usage, credits, storage, wallet reads |
| wallet.write | Wallet deposits (top-ups) |
| webhooks.manage | Webhook endpoints + delivery history |
| all | Everything |
A request missing the required scope returns 403 forbidden. API keys cannot create or revoke other API keys — that is dashboard-only.
API keys belong to one workspace. Every request must target that workspace's id in the body or query (workspaceId); targeting any other workspace returns 403 forbidden. Team members share the workspace's keys, credits, and wallet.
Requests made with an API key are attributed to the key in usage reporting (GET /v1/api-keys/:id/usage and GET /v1/usage) and in generations.apiKeyId. Keys are stamped with lastUsedAt (throttled to once per minute).
Errors use a stable envelope so clients can branch on code, not messages:
{
"error": {
"code": "insufficient_credits",
"message": "...",
"requestId": "..."
}
}Common codes:
| 400 | validation_error |
| 401 | unauthenticated |
| 402/422 | insufficient_credits, plan_limit_reached, free_model_limit_reached, wallet_pending_minimum, wallet_insufficient_balance |
| 403 | forbidden |
| 404 | not_found |
| 409 | conflict |
| 429 | rate_limited |
| 500 | internal_error |
Tip
Rate limits are enforced per key with X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset response headers. See API reference for details.