2xx means the request worked, 4xx means something in the request needs to change, and 5xx means something went wrong on our side.
Every error the API returns, whatever the status, has the same JSON shape.
The error envelope
string
required
A stable machine code, such as
exam_not_found or insufficient_credits. Branch on this, not on the message or the HTTP status alone. Codes never change once published.string
required
A human-readable explanation. Safe to log and show to your operators. The wording can improve over time, so do not parse it.
string
required
The id of this request, such as
req_3f2a9c41d8b04e6f9a7c2d1e5b8f0a63. The same value is returned in the X-Request-Id response header on every response, successful or not.object
Extra machine-readable context when there is some, for example the id of the existing resource on a
409, or the list of invalid fields on a 422. Left out when empty.Content-Type: application/json and Cache-Control: no-store.
Validation errors
422 validation_failed lists every field that failed in details.errors, so you can fix them all in one go:
All text you send is treated as plain text. Long text such as question text, model answers and typed answers can contain
< and > (for example x < 5); they are kept exactly as sent and never rendered as markup.Error codes
400 Bad Request
401 Unauthorized
402 Payment Required
403 Forbidden
404 Not Found
405, 413, 415
409 Conflict
A409 means the request is valid but clashes with the current state. Most carry the id of the resource involved in details.
412 Precondition Failed
422 Unprocessable Entity
feature_not_available is returned for:
- Choice groups (“attempt any N of M”): beta, enabled on request.
images[]on a submission or image files onPOST /uploads(phone photos).files[]on a submission (booklet plus supplements).question_idsonPOST /submissions/{id}/re-evaluate(re-grading single questions).format=csvonGET /exams/{id}/results.purge=trueonDELETE /exams/{id}.
429 Too Many Requests
See Rate limits and quotas.
5xx
Rarely, a gateway error (for example
502 or 504) arrives without the JSON envelope, sometimes with an HTML body. Treat any 5xx as retryable, and parse error bodies defensively.Retry or fix?
Send an
Idempotency-Key on every POST so that retries never create duplicates.
Submission error codes
Some problems only show up after a submission is accepted, while it is being graded. Those do not fail the HTTP request; instead the submission ends withstatus: "failed" and an error object:
Question errors
When a copy finishes but the AI could not grade some answers, the submission’s status ispartially_graded. In the result, each affected question has status: "failed", needs_review: true and its own error object with a code and the message “The AI could not grade this answer; review it by hand.” Mark those questions with PATCH /submissions/{id}/questions/{question_id}. Treat the question-level code as informational.
Warnings
A successful response can carrywarnings: input that was accepted but deserves attention. Each warning has a code, a message and the field it is about.
Reporting a problem
Every response carriesX-Request-Id, and every error body repeats it as error.request_id. Log it with every failed call. When you need help, email hello@evalezy.com with:
- the
request_id(or several, if the problem repeats), - the endpoint and the time of the call (with time zone),
- the
error.codeyou received and what you expected instead.