| 6 October 2026 |
First publication of the v1 contract (pre-release). |
| 6 October 2026 |
Papers take grading.feedback: how much feedback to write, from marks only to detailed. Results gain explanation. Added the 415 unsupported_media_type error. |
| 8 October 2026 |
A paper we can’t read after our automatic retries now fails with processing_failed straight away, instead of waiting for processing_timeout. |
| 8 October 2026 |
Upload URLs take one upload: upload.headers now includes If-None-Match: *, and a second PUT gets 412. |
| 10 October 2026 |
A review link carries its token after # (https://learningaide.ai/review#…), so send the link whole. A browser that opens one stays on that paper until the link expires or the reviewer leaves. |
| 10 October 2026 |
POST /v1/papers/{id}/review_links and POST /v1/api_key/revoke ignore Idempotency-Key: every call makes a new link, and revoking is safe to repeat. |
| 10 October 2026 |
A result’s questions[].feedback says why a question got 0 (no answer, or no readable answers) at every grading.feedback level, none and brief included. |
| 10 October 2026 |
POST /v1/webhook_endpoints and POST /v1/webhook_endpoints/{id}/rotate_secret ignore Idempotency-Key, as their response carries a secret. A sixth endpoint in a mode gets 409 too_many_webhook_endpoints. |
| 10 October 2026 |
Approving a paper with a question that has nothing to mark is refused with 409 paper_has_empty_question. A result’s parts is empty for a question marked as a whole whose mark can’t be split by part. Deleting a student’s last submission deletes their student.external_id. |
| 10 October 2026 |
A report’s sections lists the sections it holds. Deleting a paper or submission leaves its events in place with data.object reduced to { "id", "object", "deleted": true }. |
| 10 October 2026 |
A credit transaction’s source stays after its paper or submission is deleted. Rotating a webhook secret again within 24 hours ends the earlier secret at once. |
| 12 October 2026 |
Credits past credits_valid_until are kept, not removed: GET /v1/balance gains expired, and total is available + held + expired. 402 credits_expired names the date, and credits.balance_low is also sent when credits expire. |
| 12 October 2026 |
Requests with unrecognised keys are limited per address: 120 a minute from one IPv4 address or IPv6 /64, then 429 for every request from it until the minute ends. Changing a webhook endpoint’s url restarts its 5-day failure count. |
| 12 October 2026 |
The OpenAPI 3.1 description is served at https://api.learningaide.ai/v1/openapi.json. |
| 13 October 2026 |
v1 is live at https://api.learningaide.ai. From now on, changes follow Versioning. |