Errors
Every FynePDF API error as RFC 9457 problem details, with a code to branch on and what to do about each.
Errors come as problem details (application/problem+json), the same shape every time:
{
"type": "https://fynepdf.com/developers/docs/errors#insufficient_credits",
"title": "Not enough credits",
"status": 402,
"detail": "Step 1 needs 3 credits and the account has 1. Nothing was charged.",
"code": "insufficient_credits",
"request_id": "req_5mzvj9Wwj0nXyCXI"
}
Branch on code; show detail to people (it says what to do). Invalid requests add errors, one per field: { "path": "steps.0.params.pages", "message": "..." }.
Codes
| Code | Status | What to do |
|---|---|---|
unauthorized | 401 | Send your key: Authorization: Bearer fyne_…. |
invalid_api_key | 401 | Check the key; it may have a typo or belong to another environment. |
api_key_revoked | 401 | Make a new key in the dashboard. |
api_key_expired | 401 | Make a new key, or one without an expiry date. |
insufficient_credits | 402 | Buy credits, or wait for next month's free ones. Nothing was charged. |
forbidden | 403 | This key isn't allowed to do this; detail says why. |
plan_limit_reached | 403 | An assistant signed in with your account hit the plan's limit; detail names it. |
not_found | 404 | The file or job doesn't exist on this account, or has been deleted. |
method_not_allowed | 405 | Check the method in this reference. |
conflict | 409 | The resource changed; get it again and retry. |
idempotency_in_progress | 409 | The first request with this Idempotency-Key is still running; retry shortly. |
payload_too_large | 413 | Use an upload URL for files over 25 MB. |
unsupported_media_type | 415 | Send JSON, or multipart/form-data to /v1/files. |
idempotency_key_reused | 422 | That Idempotency-Key went with a different request; use a new one. |
validation_failed | 422 | Fix the fields listed in errors. |
rate_limited | 429 | Wait for Retry-After seconds. See Limits. |
too_many_active_jobs | 429 | Wait for a running job to finish, or buy credits for more at once. The limit is per key and per account. |
test_limit_reached | 429 | Test keys run 100 jobs a day per account; use a live key, or wait for 00:00 UTC. |
internal_error | 500 | Retry with the same Idempotency-Key; tell us the request_id if it lasts. |
ai_unavailable | 502 | The AI model didn't answer; retry in a moment. Nothing was charged. |
busy | 503 | Retry after Retry-After seconds. |
ai_paused | 503 | Free AI steps are paused for now; buy credits to keep going, or retry later. |
A job that failed
A job can be accepted and still fail at a step: the job comes back with status: "failed" and an error saying which step and why ("Step 2 (redact) failed: none of the text was found"). Failed steps are never charged, and a failed job gives back everything it spent.
Rate limit headers
Every response says where you stand: RateLimit-Policy and RateLimit (IETF draft headers), plus Retry-After on a 429.