API reference
The HTTP API serves the teacher, student, and marketing apps. The published OpenAPI document does not describe most of it.
Do not trust a missing path
Section titled “Do not trust a missing path”| Resource | Path |
|---|---|
| Health | <base-url>/health |
| Session endpoints | <base-url>/auth/* |
| OpenAPI 3.1 file | <base-url>/openapi.json |
| Scalar viewer | <base-url>/docs |
Most handlers are registered as ordinary routes and never appear in paths. A path missing from Scalar is not proof the endpoint is absent, and a path that is listed is not a promise that every field is documented. Ask ZeroExam before you build a product on an undocumented endpoint. The version string in that file is not a release id.
Authentication
Section titled “Authentication”Most product routes need a session cookie. A valid cookie is not enough: the operation also checks workspace membership or ownership. Treat workspace and resource ids as opaque strings.
Class-enrollment tokens and exam-share tokens are different values. Do not send one where the other is expected.
Routes that do not need a user session
Section titled “Routes that do not need a user session”| Method | Path | Purpose |
|---|---|---|
GET | /health | Process health |
GET | /api/public/catalog | Publicly visible plans and prices |
POST | /api/public/enterprise-leads | Enterprise contact form |
GET | /api/public/join/:token | Preview a class-enrollment link |
POST | /api/public/join/:token | Join that class with an email |
GET | /api/exams/share/:token | Exam metadata for a share link |
GET | /api/exams/share/:token/questions | Student-safe questions. Answers omitted |
POST | /api/exams/share/:token/attempts | Start an attempt. Name required. Password when the link has one |
POST | /api/exams/share/:token/submit | Submit answers and receive an initial score |
This table is not exhaustive. /auth/*, /docs, and /openapi.json are also reachable without a product session. /webhooks/stripe has no user session, but it requires a valid Stripe signature. It is not a general integration endpoint.
A share link may be closed by an open time, an expiry, a submission cap, or a password. Send the password on the attempt and question requests when the metadata says one is required. A missing password is refused. It is not counted as a guess. Repeated wrong passwords lock the token.
Conventions
Section titled “Conventions”- JSON for most bodies. Exports are file downloads. Course documents upload through a presigned storage URL, then a second call starts processing.
- Errors include an
errorstring. - Long-running work returns when it is accepted. Poll the status of that document, exam, or job. Do not assume the draft exists because the request returned.
- Send
traceparentorx-request-idwhen you have one. Support can find the request. - The student questions payload strips answer keys and correct-choice flags. Written scores may stay pending until a teacher checks them. If the link has answer reveal enabled, answers can be included after submission only.
Example
Section titled “Example”curl -s -H "x-exam-password: <password>" "<base-url>/api/exams/share/<token>/questions"Omit the header when the link has no password. Do not put the password in the query string. Older links that did this are ignored on purpose.