Error codes
Every answer that is not a success carries a code. The sentence beside it is written
to be read and may be rewritten at any time; the code will not change. Branch on the code.
The shape
HTTP/1.1 402
Content-Type: application/problem+json
{
"type": "/errors#limit_reached",
"title": "The plan is used up",
"status": 402,
"code": "limit_reached",
"detail": "You have made 250 documents this month and Start stops at 250.",
"error": "You have made 250 documents this month and Start stops at 250."
}
detail is the sentence, and error is the same sentence again: every
integration written before this page existed reads error, and breaking those to be tidy would be a
poor trade. Some answers carry more: hint, retryAfter, reference.
Every code
| Code | Status | What it means |
|---|---|---|
invalid_request |
400 | The request could not be used. Something in the body or the query is missing or the wrong shape. The sentence says which part. |
data_does_not_fit |
422 | The data does not fit the template. None of the fields in the template found anything in the data, so the document would be blank. Usually a field name that does not match the template. With ?strict=1 any empty field is refused this way. |
invalid_template |
400 | The template cannot be rendered. The template uses something Morfee does not have. Only text, format, rows, condition, calc, math, tree and descend exist, plus if, unless and each. |
not_found |
404 | Not here. No such template, folder, key or document **in your organization**. An id belonging to somebody else answers exactly the same way, on purpose: a 403 would confirm it exists. |
no_route |
404 | No such endpoint. Nothing answers that method and path. Fetch /openapi.json for the list. |
unauthorized |
401 | No key, or not a key we know. Send `X-Api-Key: mrf_...` or `Authorization: Bearer mrf_...`. Keys are made under Keys in the app. |
forbidden_scope |
403 | That key may not do this. The key is good but its scope is too narrow. The scopes are read, render, write and full, and a key can never make a key wider than itself. |
limit_reached |
402 | The plan is used up. The monthly ceiling for documents or templates has been reached, or the plan has ended. Nothing is deleted and everything can still be read; only making new things stops. See /billing. |
would_drop_logic |
409 | That save would throw the template away. The stored template was written by hand and has logic in it. What was sent has none, which means it is the design without the loops rather than a new version of it. Send `replaceLogic: true` if replacing it is what you mean. |
idempotency_key_reused |
422 | That key was used for a different request. An Idempotency-Key belongs to one request. Sending the same key with a different body would make "did this happen?" unanswerable, so it is refused rather than guessed at. |
idempotency_in_progress |
409 | That key is still being worked on. The first request with this key has not finished. Wait for Retry-After and ask again with the same key. |
too_many_requests |
429 | Too many attempts. Wait for the number of seconds in Retry-After. The RateLimit fields say how much room is left. |
busy |
503 | The render queue is full. Refused at once rather than queued behind a wait that would not fit, so a flow can come back instead of hanging. Retry-After says when. |
render_failed |
502 | The document could not be made. The browser that draws the PDF refused this document. Usually the document itself; occasionally us. |
server_error |
500 | Something went wrong at our end. Not your request. The answer carries a reference; quote it and it can be found in the log. |