Errors
Mandatum's REST API reports an error with an HTTP status and a JSON body. The status tells you what kind of failure it is. The body tells you what to change.
The error body #
json
{
"error": "The key lacks the `searchStatutes` scope (`code`: tool_not_enabled_for_key).",
"code": "tool_not_enabled_for_key",
"request_id": "9d1f0c2e-6b7a-4f3e-8a51-2b0f7c1e4d10"
}erroris always present. It is a human-readable message. Do not parse it; it can change wording.codeis present only when the route sets one. Branch on it when it is there, and branch on the status when it is not.request_idis the correlation id for the request. Every error body carries it, and the same value is returned in thex-request-idheader, so you can read it without parsing the body. Quote it when you report a problem.
HTTP status #
| Status | Meaning | code |
|---|---|---|
400 |
The body or query failed validation, or a parameter has an unknown value. | bad_request on most routes. |
401 |
The credential is missing, malformed, revoked or expired. | None. |
402 |
The workspace has reached its monthly agent budget, so a workflow run was not started. | BUDGET_EXCEEDED |
403 |
The credential lacks the scope the operation needs, or the caller's role does not allow it. | tool_not_enabled_for_key, or forbidden for a role check. |
404 |
The resource does not exist, or belongs to another workspace. The two cases look the same on purpose. | not_found on most routes. |
410 |
The endpoint was removed. See the changelog for the replacement. | gone on the removed gazette and drafts routes. |
422 |
The request is well formed, but the analysis cannot be issued. | no_resolved_citations |
411 |
POST /api/v1/documents was sent without a finite Content-Length. |
length_required |
413 |
An evidence bundle is over 4 MB. Narrow the period and export again. | EVIDENCE_TOO_LARGE |
429 |
You sent more requests than the limit allows. Wait, then retry. See rate limits. Workflow-run refusals send Retry-After. |
too_many_requests on workflow runs; none elsewhere. |
500 |
The handler failed. The message is scrubbed of internals. | internal_error on most routes. |
502 |
The document conversion service returned no document. | conversion_failed |
503 |
The corpus client, or the gap-report tables, is not available on this deployment. | corpus_unavailable, or gap_issuance_unavailable |
401 and 429 never carry a code. Use the status.
Codes #
These are the code values the REST facade defines. Each is listed with the statuses it is returned with.
| Code | Status | Meaning |
|---|---|---|
tool_not_enabled_for_key |
403 |
The key's scopes do not include the operation. Every scope denial returns this code. |
forbidden |
403 |
The credential is valid, but the caller's role does not permit the operation. For example, usage is for owners and admins. |
not_found |
404 |
The resource does not exist in the caller's workspace. |
bad_request |
400 |
Validation failed. For citation verification, error carries the list of issues. |
internal_error |
500 |
Unexpected failure. |
unauthorized |
401 |
Defined for a refused credential. Today a 401 carries no code, so branch on the status. |
too_many_requests |
429 |
Defined for the rate limit. Today a 429 carries no code, so branch on the status. |
Some routes define a code of their own. These appear only on the routes named.
| Code | Status | Route | Meaning |
|---|---|---|---|
length_required |
411 |
POST /api/v1/documents |
No finite Content-Length header. |
archive_too_large |
400 |
POST /api/v1/documents |
The archive exceeds the parser limit. |
conversion_failed |
502 |
POST /api/v1/documents |
The conversion service returned no document. |
corpus_unavailable |
503 |
POST /api/v1/citations/verify |
The corpus client is not configured on this deployment. |
gap_issuance_unavailable |
503 |
POST /api/v1/gaps/{analysisId}/issue |
The gap-report tables are not yet present on this deployment. |
no_resolved_citations |
422 |
POST /api/v1/gaps/{analysisId}/issue |
The analysis has no resolved citation, so it cannot be issued. |
BUDGET_EXCEEDED |
402 |
POST /api/v1/skills/run |
The monthly agent budget is spent. The body names the ceiling and the spend. |
invalid_range |
400 |
GET /api/v1/evidence/export |
The period is longer than 397 days. |
EVIDENCE_TOO_LARGE |
413 |
GET /api/v1/evidence/export |
The bundle is larger than 4 MB. |
gone |
410 |
Removed gazette and drafts routes | The endpoint was removed. The see field points to the changelog. |
Authentication errors #
A 401 tells you the credential was refused and nothing more, so the message varies: a missing bearer token, an unrecognised token, an expired token and a revoked token each get their own text. Check the header first, then create a new key if the old one was revoked or expired.
Changes that are not errors #
- A statute lookup for a CAP number that does not exist returns
200with anerrorfield, not404. Check the body. - A citation that does not resolve is a
200withverdict: not_found. It is a valid answer, not a failure. See the quickstart.