Errors
Every failure is a problem detail (RFC 9457) with a stable code.
{
"type": "https://api.reflowpdf.com/docs/errors#template_not_found",
"title": "Template not found",
"status": 404,
"detail": "No template `invoice-modern`. GET /v1/templates lists them.",
"code": "template_not_found",
"request_id": "req_x7Kq2mVb9TcA3pLw"
}Branch on code: it never changes; title and detail are for people. Every response, failed or not, carries Request-Id: give it to support.
| code | Status | What happened | What to do |
|---|---|---|---|
invalid_request | 400 | A field is missing, unknown or of the wrong type. detail names it. | Fix the request; repeating it unchanged gives the same answer. |
invalid_json | 400 | The body is not valid JSON. | Send JSON with Content-Type: application/json. |
template_not_fillable | 400 | A template of yours designed on the page was sent data. | Print it without data, or make it a template in the editor's Code view. |
invalid_html | 400 | The engine could not read the HTML. | Send a whole HTML document. |
template_error | 400 | The template does not read: an expression, a tag or a filter it cannot parse. detail names each, with its line. | Fix the template — see the template language. Nothing is printed half-read. |
unauthorized | 401 | No Authorization header. | Send Authorization: Bearer rpdf_…. |
invalid_api_key | 401 | The key is not valid, or was revoked. | Make a new key in your account. |
license_required | 401 | A print condition's profile was asked for without an API key or an engine license's token. | Send one (Authorization: Bearer …); @reflowpdf/engine sends its license's token itself. |
license_inactive | 402 | The engine license is not paid for, or its subscription has ended. | Renew it at app.reflowpdf.com → account menu → Engine licenses. The engine prints as the trial meanwhile. |
plan_required | 403 | A claim of the Pro and Max plans (pdf_a, pdf_x, pdf_ua: 2) on another plan. | Choose Pro or Max (account menu → Billing), or leave the option out. |
insufficient_scope | 403 | The key may not make this request: it lacks the scope the route asks for — print, templates, account, or assistant for the MCP server. detail names it. | Give the key the scope (account menu → API keys → Access), or use another key. |
ip_not_allowed | 403 | The key is kept to its allowed addresses, and the request came from another. detail says from where. | Add the address to the key (account menu → API keys → Access), or send from an allowed one. |
not_found | 404 | No such path. | See the reference. |
template_not_found | 404 | No such template in the gallery or in your library. | GET /v1/templates lists them. |
job_not_found | 404 | No such job in this account, or it is over 24 hours old. | |
file_not_found | 404 | No such file, or it expired (files are kept 24 hours). | Print again. |
license_not_found | 404 | No engine license has this key. | Check the key (rpdfl_…) you were given with the license. |
font_not_found | 404 | No such family in ReflowPDF's font catalogue (GET /v1/fonts/{family}). | Give the family yourself: @font-face, or engine.registerFont() in the engine package. |
method_not_allowed | 405 | The path does not take this method. | Allow names the one it takes. |
idempotency_in_progress | 409 | A request with this Idempotency-Key is still being done. | Wait, then repeat to read its response. |
job_not_finished | 409 | A job's webhook was asked again before the job finished. | Ask again once it is done. |
no_webhook | 409 | A job's webhook was asked again, and the job has no webhook_url. | Read the job instead: GET /v1/jobs/{id}. |
delivery_in_progress | 409 | A job's webhook was asked again while an attempt to deliver it is under way. | Wait (Retry-After), then read the job: its webhook says how the delivery went. |
file_expired | 410 | The answer of an Idempotency-Key is no longer kept: the file of a PDF or of images is kept one hour, a link 24 hours; or it was deleted, or could not be kept (the first answer delivered it). | Repeat with a new Idempotency-Key. |
payload_too_large | 413 | The body is over 15 MB. | Put large images on https URLs instead of data: URIs. |
document_too_large | 413 | The document is over the size a print lays out. | Split it into parts. |
result_too_large | 413 | The result is over the 1 GB a file stored for a link may be. | Ask for the file in the response (Accept: application/pdf, no Idempotency-Key). |
unsupported_media_type | 415 | The body is not JSON. | Send Content-Type: application/json. |
document_unreachable | 422 | The page of url could not be fetched: not a public http(s) address on ports 80/443, it answered an error or redirected more than 5 times, it is not HTML, or it is over 15 MB or 20 s. detail says which. | Fetch it yourself and send it as html, with options.base_url for its relative addresses. |
engine_unavailable | 422 | The engine named prints here no more (a previous version prints until three newer ones have shipped, 30 days at most). detail names the versions that do. | Pin a version GET /v1/engines lists, or leave engine out for the current one. |
invalid_pdf | 422 | A PDF to merge, split or compress is not a PDF, or one that cannot be read. detail names the part. | Send the PDF itself; a damaged file may open after it is saved again by its maker. |
pdf_encrypted | 422 | A PDF to merge, split or compress is encrypted, and its password was not given or is wrong. | Give the part its password. |
unfulfillable | 422 | Not possible for this document: a claim it cannot keep (detail says why — a colour that cannot be converted to the press's inks, transparency PDF/X-1a cannot flatten…), an unknown print condition, a page it does not have, or images over the budget of a request (250 megapixels, 256 MB). | Change the document or the option detail names; nothing was counted. |
render_failed | 422 | The document could not be laid out. | Check the document; tell support its request_id if it persists. |
idempotency_key_reused | 422 | The Idempotency-Key was used with another request in the last 24 hours. | Use a new key for a new request. |
rate_limited | 429 | Too many requests of this account at once, or in the last minutes. | Wait Retry-After seconds; the SDKs do. RateLimit-* on every answer say where you stand. |
storage_quota | 429 | The files your account stores for links fill its space: Free 256 MB, Pro and Max 2 GB (each file is stored 24 hours). | Delete some (DELETE /v1/files/{id}), wait for them to expire, or ask for the file in the response instead of a link. |
interrupted | 500 | A job (its error.code): it was interrupted on our side and could not be run again. | Create the job again. |
internal_error | 500 | Something failed on our side; nothing was printed. | Repeat (with the same Idempotency-Key); give support the request_id if it persists. |
render_failed | 502 | The engine failed to print. | Repeat; give support the request_id if it persists. |
engine_busy | 503 | The engine is busy. | Wait Retry-After seconds. |
storage_full | 503 | Files cannot be stored for links right now. | Ask for the file in the response, or try again in a few minutes. |
render_timeout | 503 | The print took over its time limit: 90 seconds for a request, 3 minutes for a job. | Print a long document as a job; make it lighter, or split it. |