Errors
The response envelope, every status code the API returns, and what to do about each.
Successful responses
Every successful response uses the same envelope:
{
"status": 200,
"message": "Success",
"data": {}
}data holds the payload — an object for a single resource, an array for a list. Paginated
endpoints add a pagination object:
{
"status": 200,
"message": "Success",
"data": [],
"pagination": { "total": 42, "nextPage": 2, "limit": 20, "currentPage": 1, "totalPage": 3 }
}nextPage is absent on the last page. Use its presence, not arithmetic on total, to decide
whether to keep going.
Failed responses
Errors use a different shape. Check the HTTP status first; do not parse data out of an error.
{
"error": {
"statusCode": 422,
"timestamp": "2026-07-03T06:00:00.000Z",
"message": "input.prompt is required",
"details": {
"errorName": "UnprocessableEntityException"
}
}
}message is the human-readable reason. details.errorName is stable enough to branch on when you
need to distinguish cases programmatically.
Status codes
| Code | Meaning | What to do |
|---|---|---|
400 | Malformed request | Fix the request. Retrying will not help |
401 | Missing, unknown, or revoked key | Check the x-mager-api-key header. See Authentication |
403 | Not allowed | Account not approved, scope missing, or IP not allowlisted |
404 | Not found | Unknown model slug, template, or task — or a task belonging to another account |
422 | Validation failed | Compare your input against the model's input_schema |
429 | Rate limit exceeded | Back off. See Rate limits |
500 | Something broke on our side | Retry with backoff. If it persists, report it |
Which errors are worth retrying
Retry 429 and 500, with exponential backoff and jitter.
Do not retry 400, 401, 403, 404, or 422. Nothing about the next attempt will differ,
and on 429 a tight loop makes it worse.
Task failures are not HTTP errors
A task that fails still returns 200. The failure is in the body:
{
"status": 200,
"data": {
"task_id": "cmagr01hxyz123",
"status": "failed",
"error": "Model returned no output",
"result": []
}
}Check data.status as well as the HTTP status. A 200 means Mager answered your question; it does
not mean the generation worked.