OverSkill API errors and how to handle them
What 401s, rate limits, credit exhaustion, and other API errors look like — and the right way for your code (or your agent) to respond.
Every OverSkill API error is machine-readable JSON and includes a next_steps field telling you (or your AI agent) what to do about it. This reference covers the errors you'll actually hit.
401 Unauthorized
Missing key:
{
"error": "Unauthorized",
"message": "Missing authentication. Provide an X-API-Key header…",
"next_steps": ["Create an API key at overskill.com → Team Settings → API Keys", "…"]
}
Invalid or malformed key: same shape with "Invalid API key format" — keys must start with os_.
Revoked key: revocation is immediate. If a previously working key starts returning 401, it was revoked or expired — mint a new one; don't retry.
403 Forbidden
Your key is valid but its scope doesn't include the permission for this endpoint (for example, a read_only key calling POST /generation_queue). Create a key with the right scope — scopes are fixed at creation time.
404 Not Found
Besides genuinely wrong IDs, you'll get 404 for resources that belong to another team — the API never reveals whether an ID exists outside your team. Double-check you're using the job_id from the generation response (not the app_id) when polling /generation_queue/{id}.
402 / credit exhaustion
Generations cost credits. When a team runs out:
- API responses include an
unlock_url— a signed, one-click link to buy credits or upgrade. Surface it to a human; don't retry the request in a loop. - If you use webhooks, you'll receive
app.generation.blockedwithblock_type,balance, andrequired_creditsinstead ofapp.generation.failed. Blocked ≠ failed: never auto-retry a blocked generation — fix the block first. - Monitor proactively with
GET /api/v1/usage(credits.balance).
429 Too Many Requests
Rate limits are per key and tiered:
| Tier | Generations | Reads | Writes | Deploys |
|---|---|---|---|---|
| standard | 20/hour | 300/min | 60/min | 10/hour |
| partner | 100/hour | 1,000/min | 200/min | 50/hour |
| enterprise | 500/hour | 5,000/min | 1,000/min | 200/hour |
On 429, back off and retry after the indicated delay (the response's next_steps includes a retry_after hint). For sustained higher volume, ask about partner-tier keys rather than spreading load across keys.
400 Bad Request
Validation errors name the offending field, e.g. {"error": "Prompt is required"}. Fix the request; don't retry unchanged.
Retired hosts — 410 Gone
api.overskill.app is permanently retired and returns 410 Gone. If a tutorial, cached doc, or old SDK points there, update it to https://www.overskill.com/api/v1. Likewise, ignore any links to docs.overskill.com — the docs home is overskill.com/developers.
General handling rules
- Trust
next_steps. Success and error responses both include it — it's designed so autonomous integrations can self-correct. - Retry only what's retryable: network errors and 5xx (with backoff), and 429 after the delay. Never blind-retry 4xx.
- Escalate with
unlock_urlwhen a human decision (billing, plan) is needed. - Timestamps are ISO 8601 UTC; IDs for apps are obfuscated strings — treat them as opaque.