Authentication & keys
API keys, per-key limits, and the free tier.
Every request to /v1/* (except the public GET /v1/models) authenticates
with a bearer key:
Authorization: Bearer sk-gpm-...
Keys are stored as SHA-256 hashes — the raw key is shown exactly once at creation and cannot be recovered. Treat it like a password; if it leaks, disable it and mint a new one.
Per-key controls
Each key can carry its own limits, enforced at admission time:
| Control | Default | Behavior when exceeded |
|---|---|---|
| Spend cap (lifetime, day or month) | none | 403 key_limit_exceeded |
| Expiration date | none | 401 invalid_api_key |
| Requests per minute | 600 | 429 rate_limited with Retry-After |
| Concurrent requests | 30 | 429 too_many_concurrent |
| Model allowlist | all models | 403 model_not_allowed |
The rate and concurrency defaults are a runaway-loop backstop rather than a throttle, and they apply to every endpoint, not just chat. If a bulk job needs more, ask and we will raise them on your key. Always read the limits from the key rather than hard-coding these numbers — yours may already differ.
Inspect the key you're holding:
curl -s https://api.gopura.net/v1/key \
-H "Authorization: Bearer $GOPURA_API_KEY"
{
"data": {
"key_id": "…",
"account_id": "…",
"free_tier": false,
"spend_usd": 0.42,
"rpm_limit": 600,
"concurrency_limit": 30
}
}
rpm_limit and concurrency_limit are always present, so a client can size
its own batching without guessing.
Credits
Balances are prepaid. Check yours at any time:
curl -s https://api.gopura.net/v1/credits \
-H "Authorization: Bearer $GOPURA_API_KEY"
{ "data": { "balance_usd": 24.99, "free_tier": false } }
When the balance reaches zero, new requests return 402 insufficient_credits.
A stream that is already running is never cut off mid-response for billing —
we absorb the small overrun rather than truncating your output.
The free tier
Accounts that have never topped up are on the free tier: they can use any
model marked free_tier: true in the catalog (at conservative rate limits),
which is enough to evaluate the full API surface — streaming, tools,
reasoning and cost accounting all behave identically to paid traffic.
Requesting a non-free model returns a 403 that names the models you can
use. The first top-up permanently unlocks the whole catalog.