Requests and responses
Format
Section titled “Format”- Base URL:
https://api.learningaide.ai. Every path in this document is relative to it, soPOST /v1/papersmeansPOST https://api.learningaide.ai/v1/papers. - HTTPS only, with TLS 1.2 or later.
- JSON request and response bodies in UTF-8. Send
Content-Type: application/jsonon requests with a body, uncompressed. A request body may be up to 1 MB; documents go through Files. - Field names are
snake_case. - Timestamps are ISO 8601 strings in UTC, for example
2026-10-06T09:15:30Z. - Numbers: marks are numbers with up to 2 decimal places, such as
1.5. Credits and page counts are whole numbers. Apercentagehas 1 decimal place. - IDs are opaque strings of up to 64 characters with a type prefix, such as
sub_7Hk2Pz9QaN. Store them as given and don’t parse them. - Every object has an
objectfield naming its type. Objects that belong to a mode also have alivemodefield. - Every documented field is always present in a response; it is
nullwhen it doesn’t apply. - Unknown request fields are rejected with
400 parameter_unknown, so typos surface at once. - Responses can gain new fields at any time. Ignore fields you don’t recognise.
- A machine-readable OpenAPI 3.1 description of every request, response and webhook is at
https://api.learningaide.ai/v1/openapi.json. It needs no key.
Your own IDs and metadata
Section titled “Your own IDs and metadata”external_idon a paper is your own ID for it. It must be unique per mode, and you can look papers up by it.student.external_idon a submission is your ID for the student. Use a stable ID that is not personal data (see Data protection).metadatais an object of up to 20 string key–value pairs, available on papers and submissions. Keys can be up to 40 characters and values up to 500 characters. We store it, return it and include it in webhooks, but never act on it. Don’t put personal data in it. APATCHthat includesmetadatareplaces the whole object.
Text formatting
Section titled “Text formatting”Question text, answer keys, students’ answers and feedback are Markdown, including tables and bold, with two additions:
- Maths is LaTeX between
$…$inside a line, or$$…$$on a line of its own. - Chemistry is mhchem
\ce{…}, with no dollar signs around it, for example\ce{CaCO3(s) -> CaO(s) + CO2(g)}.
We never use $ for money in these fields, so every $ starts or ends maths. KaTeX with its mhchem extension renders all of it. Feedback is written in English.
Lists and pagination
Section titled “Lists and pagination”List endpoints return objects in pages:
{ "object": "list", "data": [ { "id": "sub_7Hk2Pz9QaN", "object": "submission" } ], "has_more": true, "next_cursor": "c_8f2kQ1x9LmZt"}| Parameter | Meaning |
|---|---|
limit |
Items per page, from 1 to 100. Default 20. |
cursor |
The next_cursor from the previous page. Omit it for the first page. |
created_after, created_before |
Only objects created after or before this time (ISO 8601, exclusive). |
updated_after |
Only objects changed after this time (exclusive). |
- Results are newest first.
- With
updated_afterthey are oldest change first instead, ordered byupdated_at, so you can sync by saving theupdated_atof the last item you processed and passing it next time. - Keep requesting with
cursoruntilhas_moreisfalse. A cursor stays valid while you page through, even if objects change.
Request IDs
Section titled “Request IDs”Every response carries an X-Request-Id header, such as 3f2b8c1e-9d4a-4e7b-a6c5-1f0e2d3c4b5a. Log it, and include it when you contact support about a request.
Status codes
Section titled “Status codes”| Code | Meaning |
|---|---|
200 OK |
The request succeeded. |
201 Created |
A new object was created. Its processing may continue in the background. |
202 Accepted |
Not ready yet. Retry after the number of seconds in Retry-After. |
204 No Content |
The object was deleted. |
4xx |
The request has a problem you need to fix. See Errors. |
5xx |
Something went wrong on our side. Retry with backoff. |