{"openapi":"3.1.0","info":{"title":"Evalmee Public API V2","version":"v2","description":"Welcome to the Evalmee Public API documentation. This API allows you to interact with our platform programmatically.\n\n## Authentication\n\nThe API uses the OAuth 2.0 **Client Credentials Flow**.\nClient credentials grant access to all resources of your organisation.\n\nTo authenticate:\n1. Obtain your client credentials: `client_id` and `client_secret`\n2. Request an access token from `/api/public/auth/token` with body:\n  ```json\n  {\n    \"client_id\": \"YOUR_CLIENT_ID\",\n    \"client_secret\": \"YOUR_CLIENT_SECRET\",\n    \"grant_type\": \"client_credentials\"\n  }\n  ```\n3. Include the access token in every request using Bearer authentication scheme with the header `Authorization: Bearer <access_token>`.\n\nTokens are valid for **24 hours**.\n\nThe API is **HTTPS-only**; HTTP requests are redirected to HTTPS.\n\n## Common Conventions\n\n- Responses are returned in **JSON** format.\n- Requests that include a JSON body (POST / PATCH) must set `Content-Type: application/json`.\n  The scan import is the one exception: it takes a `multipart/form-data` body.\n- All **timestamps** use the ISO 8601 standard (`2025-04-30T16:15:00Z`).\n- Pagination uses `page` and `per_page` query parameters; metadata comes in `\"meta\"` & `\"links\"`.\n  `per_page` defaults to **50** and is capped at **100**: a larger value is\n  silently reduced to 100 rather than rejected, so read `\"meta\"` to know whether more pages remain.\n- Responses include HATEOAS links for easy navigation.\n- This spec covers **/v2/**. Breaking changes will appear under **/v3/**.\n\n## Identifiers\n\nEvery resource is addressed by an **opaque, non-sequential** `id` —\na UUID v4, except the exam session, whose `id` is its public token.\nTreat it as a string: never parse it, never sort on it, and never\nassume it says anything about when the record was created.\n\n**Changed**: the exam attempt used to answer a numeric `id`, in\n`/exams/{exam_id}/exam_attempts` and in the `exam_attempt.*` webhook\npayloads. It now answers a UUID like every other resource, and the\nexam result's `selected_exam_attempt_id` carries that same UUID\n(`null` while no attempt is selected, where it used to be an empty\nstring). If you stored the old value, re-resolve your attempts from\nthe exam attempts list — the numeric form matches nothing the API\nreturns.\n\n## Errors\n\nErrors carry a machine slug in `\"error\"` and the human explanation in\n`\"messages\"`. Branch on the slug, never on the message text. Some\nrefusals add a `\"meta\"` object; the key is omitted entirely when empty.\n\n```json\n{ \"error\": \"invalid_schema\", \"status_code\": 422, \"messages\": [\"name is missing\"] }\n```\n\n### Account state (403)\n\nWrite endpoints are refused when your organization's account is\nread-only (trial ended, or subscription cancelled), or when a renewal\npayment failed and its grace window elapsed:\n\n| `error` | Meaning | Affected writes |\n|---|---|---|\n| `billing_read_only` | trial expired, or subscription cancelled | everything that creates: exams, subjects, assessment criteria, examinees, exam sessions |\n| `billing_past_due` | payment failed, grace window elapsed | launching and scheduling only |\n\n`meta` describes the refusal (`action`, `state`, `message`, `upsell`),\nso a client can show the reason and what to do about it.\n\n**Reads, exports and deletes are never refused for account state** —\ndata is never held hostage. A `403` with an empty body means something\nelse entirely: your API key has no access to that record.\n"},"tags":[{"name":"Set up an exam and enrol its examinees","description":"This walkthrough takes an organization from nothing to an exam ready to be\ntaken, granting one of the two examinees the extra time they are entitled to.\n\nIt assumes you already have API credentials and an access token, and that\n`teacher@example.com` is an examiner in your organization — examiners are\ncreated in the Evalmee application, not through this API.\n\nEvery request and every response below is produced by running this scenario\nagainst the API, so what you read is what the API answers.\n\n### 1. Find the time accommodation to grant\n\nAccommodations are curated in the Evalmee application and read-only here. Look\nthe one you need up once, and keep its id: it is stable for as long as the\naccommodation exists.\n\n`extra_ratio` is a fraction, not a decimal — `\"1/3\"` means a third more time\nthan the exam's own limit.\n\n```http\nGET /api/public/v2/time_accommodations\nAuthorization: Bearer YOUR_ACCESS_TOKEN\n```\n\nResponse `200` (excerpt):\n\n```json\n{\n  \"data\": [\n    {\n      \"id\": \"00000001-0000-4000-8000-000000000000\",\n      \"denominator\": 3,\n      \"extra_ratio\": \"1/3\",\n      \"links\": {\n        \"self\": \"https://app.evalmee.com/api/public/v2/time_accommodations/00000001-0000-4000-8000-000000000000\"\n      },\n      \"name\": \"Tiers-temps\",\n      \"numerator\": 1\n    }\n  ]\n}\n```\n\n### 2. Add the first examinee, with the accommodation\n\nThe email identifies a person across the whole platform. Sending one that is\nalready a member updates them instead of creating a second entry, and answers\n`200` rather than `201` — so this call is safe to replay.\n\nThe id you get back names this person's MEMBERSHIP of your organization, which\nis what the rest of the API expects.\n\n```http\nPOST /api/public/v2/users\nAuthorization: Bearer YOUR_ACCESS_TOKEN\nContent-Type: application/json\n\n{\n  \"email\": \"student1@example.com\",\n  \"first_name\": \"Alice\",\n  \"last_name\": \"Martin\",\n  \"time_accommodation_id\": \"00000001-0000-4000-8000-000000000000\"\n}\n```\n\nResponse `201`:\n\n```json\n{\n  \"id\": \"00000002-0000-4000-8000-000000000000\",\n  \"email\": \"student1@example.com\",\n  \"external_id\": null,\n  \"first_name\": \"Alice\",\n  \"last_name\": \"Martin\",\n  \"links\": {\n    \"self\": \"https://app.evalmee.com/api/public/v2/users/00000002-0000-4000-8000-000000000000\",\n    \"examinees\": \"https://app.evalmee.com/api/public/v2/users/00000002-0000-4000-8000-000000000000/examinees\"\n  },\n  \"time_accommodation\": {\n    \"id\": \"00000001-0000-4000-8000-000000000000\",\n    \"denominator\": 3,\n    \"extra_ratio\": \"1/3\",\n    \"links\": {\n      \"self\": \"https://app.evalmee.com/api/public/v2/time_accommodations/00000001-0000-4000-8000-000000000000\"\n    },\n    \"name\": \"Tiers-temps\",\n    \"numerator\": 1\n  },\n  \"type\": \"examinee\"\n}\n```\n\n### 3. Create the exam\n\nThe owner is given by email, and must already be an examiner in your\norganization. The exam is created with one session covering everyone; add more\nthrough `/exams/{id}/exam_sessions` when different groups sit it at different\ntimes.\n\n```http\nPOST /api/public/v2/exams\nAuthorization: Bearer YOUR_ACCESS_TOKEN\nContent-Type: application/json\n\n{\n  \"name\": \"Test exam\",\n  \"owner\": \"teacher@example.com\"\n}\n```\n\nResponse `201` (excerpt):\n\n```json\n{\n  \"id\": \"00000003-0000-4000-8000-000000000000\",\n  \"name\": \"Test exam\",\n  \"grading_mode\": \"global\",\n  \"time_limit\": null,\n  \"links\": {\n    \"self\": \"https://app.evalmee.com/api/public/v2/exams/00000003-0000-4000-8000-000000000000\",\n    \"exam_attempts\": \"https://app.evalmee.com/api/public/v2/exams/00000003-0000-4000-8000-000000000000/exam_attempts\",\n    \"exam_results\": \"https://app.evalmee.com/api/public/v2/exams/00000003-0000-4000-8000-000000000000/results\",\n    \"exam_sessions\": \"https://app.evalmee.com/api/public/v2/exams/00000003-0000-4000-8000-000000000000/exam_sessions\",\n    \"assessment_criteria\": \"https://app.evalmee.com/api/public/v2/exams/00000003-0000-4000-8000-000000000000/assessment_criteria\",\n    \"examinees\": \"https://app.evalmee.com/api/public/v2/exams/00000003-0000-4000-8000-000000000000/examinees\",\n    \"emails\": \"https://app.evalmee.com/api/public/v2/emails?exam_id=00000003-0000-4000-8000-000000000000\"\n  }\n}\n```\n\n### 4. Enrol both examinees in one call\n\nA batch accepts up to 50 examinees, each named by `user_id`, by `email`, or by\nthe id of an existing enrolment.\n\nUse `user_id` for someone already in your directory — here the person created\nin step 2, who keeps the accommodation granted there. Use `email` for someone\nyou have not added yet: they are created and enrolled in one go, which is why\nthe second examinee needs no prior call.\n\nNo email is sent to the examinees.\n\n```http\nPATCH /api/public/v2/exams/00000003-0000-4000-8000-000000000000/examinees\nAuthorization: Bearer YOUR_ACCESS_TOKEN\nContent-Type: application/json\n\n{\n  \"examinees\": [\n    {\n      \"user_id\": \"00000002-0000-4000-8000-000000000000\"\n    },\n    {\n      \"email\": \"student2@example.com\",\n      \"first_name\": \"Bruno\",\n      \"last_name\": \"Lopez\"\n    }\n  ]\n}\n```\n\nResponse `200`:\n\n```json\n{\n  \"data\": [\n    {\n      \"data\": {\n        \"id\": \"00000004-0000-4000-8000-000000000000\",\n        \"email\": \"student1@example.com\",\n        \"external_id\": null,\n        \"first_name\": \"Alice\",\n        \"groups\": [],\n        \"last_name\": \"Martin\",\n        \"links\": {\n          \"self\": \"https://app.evalmee.com/api/public/v2/exams/00000003-0000-4000-8000-000000000000/examinees/00000004-0000-4000-8000-000000000000\",\n          \"exam\": \"https://app.evalmee.com/api/public/v2/exams/00000003-0000-4000-8000-000000000000\",\n          \"emails\": \"https://app.evalmee.com/api/public/v2/emails?exam_id=00000003-0000-4000-8000-000000000000&examinee_id=00000004-0000-4000-8000-000000000000\",\n          \"user\": \"https://app.evalmee.com/api/public/v2/users/00000002-0000-4000-8000-000000000000\"\n        },\n        \"uids_per_identity_providers\": [\n          {\n            \"provider\": \"evalmee\",\n            \"uid\": \"student1@example.com\"\n          }\n        ]\n      },\n      \"index\": 0,\n      \"status\": \"created\"\n    },\n    {\n      \"data\": {\n        \"id\": \"00000005-0000-4000-8000-000000000000\",\n        \"email\": \"student2@example.com\",\n        \"external_id\": null,\n        \"first_name\": \"Bruno\",\n        \"groups\": [],\n        \"last_name\": \"Lopez\",\n        \"links\": {\n          \"self\": \"https://app.evalmee.com/api/public/v2/exams/00000003-0000-4000-8000-000000000000/examinees/00000005-0000-4000-8000-000000000000\",\n          \"exam\": \"https://app.evalmee.com/api/public/v2/exams/00000003-0000-4000-8000-000000000000\",\n          \"emails\": \"https://app.evalmee.com/api/public/v2/emails?exam_id=00000003-0000-4000-8000-000000000000&examinee_id=00000005-0000-4000-8000-000000000000\",\n          \"user\": \"https://app.evalmee.com/api/public/v2/users/00000006-0000-4000-8000-000000000000\"\n        },\n        \"uids_per_identity_providers\": [\n          {\n            \"provider\": \"evalmee\",\n            \"uid\": \"student2@example.com\"\n          }\n        ]\n      },\n      \"index\": 1,\n      \"status\": \"created\"\n    }\n  ],\n  \"errors_count\": 0\n}\n```\n"},{"name":"Users","description":"A user represents a person known to your organization — someone who takes exams, creates them, or both.\n\nThe id identifies a *membership* rather than a human being: the same person belonging to two organizations has a different id in each, and neither organization can see the other's.\n\nMind the two senses of `examinee`: as a user `type` it says what someone does in your organization, while an **Examinee** is one enrollment of one user in one exam.\n"},{"name":"Exams","description":"An exam represents a collection of questions assigned to examinees. \n\nIt can have one or more exam sessions. \n\nAn examinee can take an exam in one or more exam sessions.\n"},{"name":"Exam Sessions","description":"An exam session represents a time period during which examinees can take a given exam, with options for group restrictions and self-enrollment. \n\n\nAn exam session can either:\n- be restricted to one or more groups of examinees\n- have no restriction: all the examinees can take the exam in this session\n"},{"name":"Examinees","description":"An examinee represents a person enrolled in a given exam, including their identity and group membership.\n\n"},{"name":"Exam Attempts","description":"An exam attempt represents a participation of an examinee in a given exam session.\n\nIf an examinee is assigned to one or more exam sessions of the same exam, they will have one exam attempt per session.\n\nThe exam attempt is created when the examinee is invited by mail to the exam session or when they access the exam for the first time.\n"},{"name":"Exam Results","description":"An exam result represents the overall performance of an examinee in a given exam.\n\nA result is computed from one or more exam attempts and includes the final grade.\n"},{"name":"Assessment Criteria","description":"An assessment criterion defines an evaluation dimension for an exam. Each question is graded against all criteria with configurable points, yielding per-criterion grades. Criteria typically map to competencies from external frameworks (e.g. RNCP in France) but can be custom-defined.\n"},{"name":"Paper Exams","description":"A paper exam (Papeez) is printed, handed out, filled in on paper and scanned back in. Its `paper` sub-resource carries the copy configuration, the state of the copy generation, and the printable files the generation produces.\n\nOnly a paper exam has one: on any other exam the `paper` key is absent from the response and the endpoint answers 404.\n\nCopies are configured and generated in the Evalmee web application; the API reads that state and serves the files. Each file endpoint redirects to a signed storage URL that expires — follow the redirect, do not store its target.\n\nOnce the copies are filled in and scanned, the PDF is sent back through the scan import, which starts the automatic grading. Pages the analysis cannot attach to an examinee are resolved in the web application: an integration that never opens it is not a supported scenario.\n"},{"name":"Time Accommodations","description":"A time accommodation is the extra exam time granted to a user for specific needs, expressed as a fraction of the exam's own time limit.\n\nThe catalog is curated in the Evalmee application and is read-only here. Assigning one to a user is done on that user.\n"},{"name":"Receiving webhooks","description":"Webhooks push events to your own HTTPS endpoint as they happen, so you\ndo not have to poll. Subscriptions are set up by Evalmee on request:\ngive us the endpoint and the topics you want.\n\nThe `ping` event below is what we send to prove an endpoint is reachable\nand that your signature check works; it carries no data.\n\n### Verifying a delivery\n\nEvery request carries the [Standard Webhooks](https://www.standardwebhooks.com)\nheaders, signed with the `whsec_...` secret we hand you:\n\n| Header | Meaning |\n|---|---|\n| `webhook-id` | The event id — the key to deduplicate on, identical across retries |\n| `webhook-timestamp` | Unix seconds at which the attempt was signed |\n| `webhook-signature` | Space-separated list of `v1,<base64 HMAC-SHA256>` |\n\nVerify with a Standard Webhooks SDK rather than by hand: it checks the\nsignature over `id.timestamp.body` in constant time and rejects a\nreplayed timestamp. Treat an unverified request as hostile — the URL\nalone proves nothing.\n\nThree extra headers are informational and must not be trusted for\nauthentication: `X-Evalmee-Event`, `X-Evalmee-Delivery`,\n`X-Evalmee-Organization`.\n\n### Answering\n\nAnswer any `2xx` as soon as you have persisted the event, and do the\nwork afterwards. We never read the response body, never follow a\nredirect, and give up on a request after 20 seconds.\n\n### Retries and disabling\n\nA `429`, any status between `500`\nand `599`, or a transport failure is retried\n5 times, after 1 minute, 5 minutes, 30 minutes, 2 hours, and 12 hours. Any other `4xx` is\nfinal — we treat it as \"this endpoint refuses the event\", not as a temporary\nglitch.\n\nRetries mean the same event can arrive more than once: deduplicate on\n`webhook-id`. After 10 consecutive events exhaust\ntheir retries, the subscription is disabled automatically and we contact you.\n\n### What deduplication does not cover\n\n`webhook-id` identifies the event, not the fact behind it. It protects\nyou from processing one event twice; it does not merge two events that\ndescribe the same thing happening twice.\n\nAn attempt that is reopened and started again is a second real start,\nand carries its own `webhook-id`. Deduplicating alone would record two\nstarts where you expected one — reconcile on the resource in `data`\nwhen your own model allows the fact only once.\n"},{"name":"Exam attempt events","description":"Sent as an examinee's attempt moves through its lifecycle. `data` is\nalways the exam attempt, in the same shape `/exams/{exam_id}/exam_attempts`\nreturns, so one parser covers the whole section.\n\nOnly an examinee's attempt sends these events: an examiner previewing\ntheir own exam goes through the same states and publishes nothing.\n"},{"name":"Email events","description":"Sent as the delivery status of a convocation changes, as reported by our\nemail provider. `data` is always the email, in the same shape\n`/emails/{id}` returns, with `status_updated_at` carrying the provider's\nown timestamp.\n\nEach status change is one event, so repeated opens or clicks send nothing\nafter the first. Subscribe only to the statuses you act on —\n`email.bounced` and `email.failed` are the ones that mean an examinee will\nnot receive their convocation.\n"}],"x-tagGroups":[{"name":"Cookbooks","tags":["Set up an exam and enrol its examinees"]},{"name":"Reference","tags":["Users","Exams","Exam Sessions","Examinees","Exam Attempts","Exam Results","Assessment Criteria","Paper Exams","Time Accommodations","Emails","Invitations","Organization"]},{"name":"Webhooks","tags":["Receiving webhooks","Exam attempt events","Email events"]}],"paths":{"/exams/{exam_id}/assessment_criteria":{"parameters":[{"name":"exam_id","in":"path","required":true,"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","description":"The id of the exam in Evalmee","schema":{"type":"string"}}],"get":{"summary":"List all assessment criteria","tags":["Assessment Criteria"],"description":"List all assessment criteria for a given exam.\n","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/assessment_criterion"}},"meta":{"$ref":"#/components/schemas/pagination_meta"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}}}},"post":{"summary":"Create an assessment criterion","tags":["Assessment Criteria"],"description":"Create a new assessment criterion for a given exam.\n","parameters":[],"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/assessment_criterion"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"examples":{"invalid_schema":{"value":{"error":"invalid_schema","status_code":422,"messages":["name must be filled"]}}},"schema":{"$ref":"#/components/schemas/error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"description":"The name of the assessment criterion","example":"Data collection methodology","type":"string","minLength":1},"description":{"description":"Description of the criterion","example":"Use of appropriate tools and methods to gather information in a structured manner","type":["null","string"]},"code":{"description":"Short code (max 10 chars, auto-generated if omitted)","example":"CE1.1","type":"string","minLength":1,"maxLength":10}},"required":["name"]},"examples":{"Basic":{"summary":"Basic assessment criterion","value":{"name":"Data collection methodology"}},"With details":{"summary":"Assessment criterion with details","value":{"name":"Data collection methodology","description":"Use of appropriate tools and methods to gather information in a structured manner","code":"CE1.1"}}}}}}}},"/exams/{exam_id}/assessment_criteria/{id}":{"parameters":[{"name":"exam_id","in":"path","required":true,"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","description":"The id of the exam in Evalmee","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","description":"The id of the assessment criterion in Evalmee","schema":{"type":"string"}}],"get":{"summary":"Retrieve an assessment criterion","tags":["Assessment Criteria"],"description":"Retrieve a given assessment criterion, including its name, code and description.\n","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/assessment_criterion"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}}}},"patch":{"summary":"Update an assessment criterion","tags":["Assessment Criteria"],"description":"Update the properties of a given assessment criterion.\nCannot update a criterion linked to questions with frozen grading criteria.\n","parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/assessment_criterion"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}},"422":{"description":"Unprocessable Entity - frozen criteria","content":{"application/json":{"examples":{"frozen_criteria":{"value":{"error":"frozen_criteria","status_code":422,"messages":["Cannot update a criterion linked to questions with frozen grading criteria"]}}},"schema":{"$ref":"#/components/schemas/error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"description":"The name of the assessment criterion","example":"Data collection methodology","type":"string","minLength":1},"description":{"description":"Description of the criterion","example":"Use of appropriate tools and methods to gather information in a structured manner","type":["null","string"]},"code":{"description":"Short code (max 10 chars, auto-generated if omitted)","example":"CE1.1","type":"string","minLength":1,"maxLength":10}}},"examples":{"Basic":{"summary":"Basic assessment criterion","value":{"name":"Data collection methodology"}}}}}}},"delete":{"summary":"Delete an assessment criterion","tags":["Assessment Criteria"],"description":"Delete a given assessment criterion.\nCannot delete a criterion linked to questions with frozen grading criteria.\n","responses":{"204":{"description":"Success"},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}}}}},"422":{"description":"Unprocessable Entity - frozen criteria","content":{"application/json":{"examples":{"frozen_criteria":{"value":{"error":"frozen_criteria","status_code":422,"messages":["Cannot modify a criterion linked to questions with frozen grading criteria"]}}}}}}}}},"/emails":{"get":{"summary":"List the emails sent to examinees","tags":["Emails"],"description":"List the emails sent to the examinees of your school, most recent first.\n\nEvery email type is listed, including the ones no endpoint can trigger. Combine the\nfilters to answer \"what was sent for this session\" or \"what was sent to this examinee\".\n","parameters":[{"name":"exam_id","in":"query","required":false,"example":"a1b2c3d4-e5f6-7a8b-9c0d-e1f2a3b4c5d6","description":"Only return emails sent about this exam","schema":{"type":"string"}},{"name":"exam_session_id","in":"query","required":false,"example":"a1B2c3d4e5","description":"Only return emails sent about this exam session","schema":{"type":"string"}},{"name":"examinee_id","in":"query","required":false,"example":"b2c3d4e5-f6a7-8b9c-0d1e-f2a3b4c5d6e7","description":"Only return emails sent to this examinee","schema":{"type":"string"}},{"name":"type","in":"query","required":false,"example":"invitation","description":"Only return emails of this kind","schema":{"type":"string","enum":["invitation"]}}],"responses":{"200":{"description":"Including emails attached to the exam itself","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/email"}},"meta":{"$ref":"#/components/schemas/pagination_meta"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"examples":{"invalid_schema":{"value":{"error":"invalid_schema","status_code":422,"messages":["type must be one of: invitation"]}}},"schema":{"$ref":"#/components/schemas/error"}}}}}}},"/emails/{id}":{"parameters":[{"name":"id","in":"path","required":true,"example":"a1b2c3d4-e5f6-7a8b-9c0d-e1f2a3b4c5d6","description":"The id of the email in Evalmee","schema":{"type":"string"}}],"get":{"summary":"Retrieve an email","tags":["Emails"],"description":"Retrieve a single email sent to one of your examinees, with its delivery status.\n","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/email"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}}}}},"/exams/{exam_id}/exam_attempts":{"parameters":[{"name":"exam_id","in":"path","required":true,"schema":{"type":"string"}}],"get":{"summary":"List all exam attempts","tags":["Exam Attempts"],"description":"List all exam attempts for a given exam.\n","parameters":[{"name":"filter[exam_session_id]","in":"query","required":false,"example":"a1B2c3d4e5","description":"Only return attempts taken in one of these exam sessions. Separate ids with commas.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/exam_attempt"}},"meta":{"$ref":"#/components/schemas/pagination_meta"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}}}}},"/exams/{exam_id}/exam_attempts/{id}/close":{"parameters":[{"name":"exam_id","in":"path","required":true,"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","description":"The id of the exam in Evalmee","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"example":"b2c3d4e5-f6a7-4b9c-8d1e-f2a3b4c5d6e7","description":"The id of the exam attempt in Evalmee","schema":{"type":"string"}}],"post":{"summary":"Close an exam attempt","tags":["Exam Attempts"],"description":"End an examinee's attempt without waiting for them to submit it, the way\nan examiner closes a copy from the application.\n\nOnly an attempt being answered can be closed. The attempt is graded as it\nstands, and an `exam_attempt.finished` webhook is sent.\n","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/exam_attempt"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"examples":{"invalid_transition":{"value":{"error":"invalid_score_transition","status_code":422,"messages":["Cannot close an exam attempt in state finished."]}}},"schema":{"$ref":"#/components/schemas/error"}}}}}}},"/exams/{exam_id}/exam_attempts/{id}/reopen":{"parameters":[{"name":"exam_id","in":"path","required":true,"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","description":"The id of the exam in Evalmee","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"example":"b2c3d4e5-f6a7-4b9c-8d1e-f2a3b4c5d6e7","description":"The id of the exam attempt in Evalmee","schema":{"type":"string"}}],"post":{"summary":"Reopen an exam attempt","tags":["Exam Attempts"],"description":"Let an examinee resume an attempt that has ended, whether they submitted\nit, its time ran out, or an examiner closed it.\n\nAnswers already given are kept. The attempt starts again, so an\n`exam_attempt.started` webhook is sent and the submission deadline is\nrecomputed — which is why the exam must still be open.\n","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/exam_attempt"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"examples":{"exam_not_open":{"value":{"error":"exam_not_open","status_code":422,"messages":["Cannot reopen an exam attempt while the exam is closed."]}}},"schema":{"$ref":"#/components/schemas/error"}}}}}}},"/exams/{exam_id}/exam_attempts/{id}/reset":{"parameters":[{"name":"exam_id","in":"path","required":true,"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","description":"The id of the exam in Evalmee","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"example":"b2c3d4e5-f6a7-4b9c-8d1e-f2a3b4c5d6e7","description":"The id of the exam attempt in Evalmee","schema":{"type":"string"}}],"post":{"summary":"Reset an exam attempt","tags":["Exam Attempts"],"description":"Wipe an attempt and put the examinee back before their first start, so\nthey can sit the exam again from scratch.\n\n**This deletes the examinee's answers, their grade and their proctoring\nrecordings, and cannot be undone.** An attempt being answered must be\nclosed first, so a reset can never wipe an exam in progress. On a paper\nexam it also discards the answers read from the scanned copy, which then\nhas to be scanned again.\n","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/exam_attempt"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"examples":{"invalid_transition":{"value":{"error":"invalid_score_transition","status_code":422,"messages":["Cannot reset an exam attempt in state started."]}}},"schema":{"$ref":"#/components/schemas/error"}}}}}}},"/exams/{exam_id}/results":{"get":{"summary":"List all exam results","tags":["Exam Results"],"description":"List all results of examinees for a given exam.\n","parameters":[{"name":"exam_id","in":"path","required":true,"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"examples":{"Simple":{"value":{"data":[{"examinee_id":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","exam_attempts":{"data":[{"id":"b2c3d4e5-f6a7-4b8c-9d0e-f1f2f3f4f5f6","user_id":"c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7","status":"graded","grade":75,"grade_locked":false,"grade_scale":100,"started_at":"2025-05-12T07:46:28.576Z","finished_at":"2025-05-12T08:46:28.576Z","onboarding_seen_at":"2025-05-12T07:40:00.000Z","web_app_url":"https://app.evalmee.com/xxxxx","grades_by_criteria":[],"exam_session":{"id":"a1B2c3d4e5","name":"Session 1","start_at":"2025-01-01T00:00:00Z","scheduled_end_at":"2025-06-01T00:00:00Z","groups":[],"web_app_examinee_enrollment_url":"https://app.evalmee.com/join/a1B2c3d4e5-exam-name-session-1","allow_self_enrollment":"none","links":{"self":"https://app.evalmee.com/api/public/v2/xxxxxx"}}}],"meta":{"count":1,"current_page":1,"next_page":null,"prev_page":null,"total_count":1,"total_pages":1,"links":{"first":"https://app.evalmee.com/api/public/v2/xxxxxx","last":"https://app.evalmee.com/api/public/v2/xxxxxx"}}},"examinee":{"id":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","first_name":"John","last_name":"Doe","email":"john.doe@example.com","links":{"self":"https://app.evalmee.com/api/public/v2/xxxxxx"}},"grade":75,"grade_locked":false,"grade_scale":100,"status":"graded","grades_by_criteria":[],"selected_exam_attempt_id":"b2c3d4e5-f6a7-4b8c-9d0e-f1f2f3f4f5f6"}],"meta":{"count":1,"current_page":1,"next_page":null,"prev_page":null,"total_count":1,"total_pages":1,"links":{"first":"https://app.evalmee.com/api/public/v2/xxxxxx","last":"https://app.evalmee.com/api/public/v2/xxxxxx"}}}},"With a locked grade (pending subscription)":{"value":{"data":[{"examinee_id":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","grade":null,"grade_locked":true,"grade_scale":100,"status":"graded","grades_by_criteria":[{"code":"CE1","name":"Planning","description":"Develops comprehensive project plans with realistic timelines","grade":null,"grade_locked":true,"grade_scale":10,"question_ids":["d4e5f6a7-b8c9-4d0e-1f2a-3b4c5d6e7f8a"]}],"selected_exam_attempt_id":"b2c3d4e5-f6a7-4b8c-9d0e-f1f2f3f4f5f6"}],"meta":{"count":1,"current_page":1,"next_page":null,"prev_page":null,"total_count":1,"total_pages":1,"links":{"first":"https://app.evalmee.com/api/public/v2/xxxxxx","last":"https://app.evalmee.com/api/public/v2/xxxxxx"}}}},"With grades by criteria":{"value":{"data":[{"examinee_id":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","exam_attempts":{"data":[{"id":"b2c3d4e5-f6a7-4b8c-9d0e-f1f2f3f4f5f6","user_id":"c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7","status":"graded","grade":77.78,"grade_locked":false,"grade_scale":100,"started_at":"2025-05-12T07:46:28.576Z","finished_at":"2025-05-12T08:46:28.576Z","onboarding_seen_at":"2025-05-12T07:40:00.000Z","web_app_url":"https://app.evalmee.com/xxxxx","grades_by_criteria":[{"code":"CE1","name":"Planning","description":"Develops comprehensive project plans with realistic timelines","grade":8,"grade_locked":false,"grade_scale":10,"question_ids":["d4e5f6a7-b8c9-4d0e-1f2a-3b4c5d6e7f8a","77434259-a647-4593-bc7a-5676896c7e21"]},{"code":"CE2","name":"Risk Management","description":"Identifies and mitigates project risks proactively","grade":4,"grade_locked":false,"grade_scale":5,"question_ids":["e5f6a7b8-c9d0-4e1f-2a3b-4c5d6e7f8a9b"]},{"code":"_no_criterion","name":"No criterion","description":null,"grade":2,"grade_locked":false,"grade_scale":3,"question_ids":["f6a7b8c9-d0e1-4f2a-3b4c-5d6e7f8a9b0c"]}],"exam_session":{"id":"a1B2c3d4e5","name":"Session 1","start_at":"2025-01-01T00:00:00Z","scheduled_end_at":"2025-06-01T00:00:00Z","groups":[],"web_app_examinee_enrollment_url":"https://app.evalmee.com/join/a1B2c3d4e5-exam-name-session-1","allow_self_enrollment":"none","links":{"self":"https://app.evalmee.com/api/public/v2/xxxxxx"}}}],"meta":{"count":1,"current_page":1,"next_page":null,"prev_page":null,"total_count":1,"total_pages":1,"links":{"first":"https://app.evalmee.com/api/public/v2/xxxxxx","last":"https://app.evalmee.com/api/public/v2/xxxxxx"}}},"examinee":{"id":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","first_name":"John","last_name":"Doe","email":"john.doe@example.com","links":{"self":"https://app.evalmee.com/api/public/v2/xxxxxx"}},"grade":77.78,"grade_locked":false,"grade_scale":100,"status":"graded","grading_mode":"global","grades_by_criteria":[{"code":"CE1","name":"Planning","description":"Develops comprehensive project plans with realistic timelines","grading_instruction":"Check milestone definitions and resource allocation","grade":8,"grade_locked":false,"grade_scale":10,"question_ids":["d4e5f6a7-b8c9-4d0e-1f2a-3b4c5d6e7f8a"]},{"code":"CE2","name":"Risk Management","description":"Identifies and mitigates project risks proactively","grading_instruction":"Evaluate risk identification and mitigation strategies","grade":4,"grade_locked":false,"grade_scale":5,"question_ids":["e5f6a7b8-c9d0-4e1f-2a3b-4c5d6e7f8a9b"]},{"code":"_no_criterion","name":"No criterion","description":null,"grading_instruction":null,"grade":2,"grade_locked":false,"grade_scale":3,"question_ids":["f6a7b8c9-d0e1-4f2a-3b4c-5d6e7f8a9b0c"]}],"selected_exam_attempt_id":"b2c3d4e5-f6a7-4b8c-9d0e-f1f2f3f4f5f6"}],"meta":{"count":1,"current_page":1,"next_page":null,"prev_page":null,"total_count":1,"total_pages":1,"links":{"first":"https://app.evalmee.com/api/public/v2/xxxxxx","last":"https://app.evalmee.com/api/public/v2/xxxxxx"}}}}},"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/exam_result"}},"meta":{"$ref":"#/components/schemas/pagination_meta"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}}}}},"/exams/{exam_id}/exam_sessions/{exam_session_id}/invitations":{"parameters":[{"name":"exam_id","in":"path","required":true,"example":"a1b2c3d4-e5f6-7a8b-9c0d-e1f2a3b4c5d6","description":"The id of the exam in Evalmee","schema":{"type":"string"}},{"name":"exam_session_id","in":"path","required":true,"example":"a1B2c3d4e5","description":"The id of the exam session in Evalmee","schema":{"type":"string"}}],"post":{"summary":"Send invitations to a whole exam session","tags":["Invitations"],"description":"Send an invitation email to every examinee of a given exam session.\n\nAnswers with one entry per recipient and an `errors_count`, like the other\nbulk endpoints.\n\nSending again is how a reminder is issued: each send creates its own invitation,\nso the full history stays readable through the emails endpoint. Provide `content_override`\nto give the reminder a body of its own.\n","parameters":[],"responses":{"200":{"description":"Success sending a single invitation per examinee","content":{"application/json":{"schema":{"type":"object","properties":{"errors_count":{"type":"integer"},"data":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer"},"status":{"type":"string","enum":["error","created","updated","deleted","ignored"]},"error":{"$ref":"#/components/schemas/error"},"data":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/email"}]}},"required":["index","status"]}}},"required":["errors_count","data"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"examples":{"invalid_schema":{"value":{"error":"invalid_schema","status_code":422,"messages":["content_override must be filled"]}}},"schema":{"$ref":"#/components/schemas/error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"content_override":{"description":"The body of the invitation email, overriding the exam's default convocation\ntemplate for this send only. Omit the key to use the exam's default — an\nempty string is rejected rather than treated as \"no override\".\n\nAvailable placeholders:\n- `{{first_name}}` — The examinee's first name (also: `{{prenom}}`, `{{prénom}}`)\n- `{{last_name}}` — The examinee's last name (also: `{{nom}}`, `{{nom_de_famille}}`)\n- `{{full_name}}` — The examinee's first and last name (also: `{{nom_entier}}`, `{{nom_complet}}`)\n- `{{email}}` — The examinee's email address (also: `{{mail}}`, `{{e-mail}}`)\n- `{{student_id}}` — The examinee's student id in the school (also: `{{identifiant}}`, `{{id}}`)\n- `{{quiz}}` — The name of the exam (also: `{{quiz_name}}`, `{{exam}}`, `{{examen}}`)\n- `{{lien_de_connexion}}` — A link to the exam, labelled in the examinee's own language\n- `{{lien_de_connexion_fr}}` — A link to the exam, labelled in French\n- `{{lien_de_connexion_en}}` — A link to the exam, labelled in English\n- `{{note}}` — The examinee's grade, or a placeholder when it is withheld (also: `{{grade}}`)\n- `{{date}}` — The day the exam session opens (also: `{{start_date}}`)\n- `{{date_de_fin}}` — The day the exam session closes, time accommodation included (also: `{{stop_date}}`)\n- `{{debut}}` — The time the exam session opens (also: `{{début}}`, `{{heure_de_debut}}`, `{{heure_de_début}}`, `{{start}}`, `{{start_time}}`)\n- `{{fin}}` — The time the exam session closes, time accommodation included (also: `{{heure_de_fin}}`, `{{end}}`, `{{end_time}}`)\n- `{{publication}}` — The time the grades are published (also: `{{heure_de_publication}}`, `{{publish}}`, `{{publish_time}}`)\n- `{{fuseau_horaire}}` — The time zone the exam times are expressed in (also: `{{time_zone}}`)\n- `{{duree}}` — How long the examinee has to answer, time accommodation included (also: `{{durée}}`, `{{duration}}`, `{{length}}`)","example":"Hello {{first_name}}, your exam starts at {{debut}}. {{lien_de_connexion}}","type":"string","minLength":1}}},"examples":{"Basic":{"summary":"Send the exam's default convocation","value":{}},"With custom content":{"summary":"Send a reminder with its own body","value":{"content_override":"Hello {{first_name}}, your exam starts at {{debut}}. {{lien_de_connexion}}"}}}}}}}},"/exams/{exam_id}/exam_sessions":{"parameters":[{"name":"exam_id","in":"path","required":true,"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","description":"The id of the exam in Evalmee","schema":{"type":"string"}}],"get":{"summary":"List all exam sessions","tags":["Exam Sessions"],"description":"List all exam sessions for a given exam.\n","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/exam_session"}},"meta":{"$ref":"#/components/schemas/pagination_meta"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}}}},"post":{"summary":"Create an exam session","tags":["Exam Sessions"],"description":"Create a new exam session for a given exam, with scheduling, group restrictions, and self-enrollment options.\n","parameters":[],"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/exam_session"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"examples":{"invalid_schema":{"value":{"error":"invalid_schema","status_code":422,"messages":["name must be filled","scheduled_end_at must be a date time","allow_self_enrollment must be one of: none, all, in_school","groups must be an array"]}}},"schema":{"$ref":"#/components/schemas/error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"The name of the exam session","example":"Session 1"},"start_at":{"description":"The start date and time of the exam session (ISO 8601).\nLeave empty if you don't want to schedule a start date.","example":"2025-01-01T00:00:00Z","type":["null","string"],"format":"date-time"},"scheduled_end_at":{"description":"The scheduled end date and time of the exam session (ISO 8601).\nLeave empty if you don't want to schedule an end date.","example":"2025-01-01T00:00:00Z","type":["null","string"],"format":"date-time"},"allow_self_enrollment":{"description":"Whether to allow examinees to enroll themselves in the exam session.\n\n- `none` = forbid self enrollment\n\n- `all` = allow all examinees to enroll themselves\n\n- `in_school` = allow only examinees with an email matching the school domain to enroll themselves","example":"none","type":"string","minLength":1,"enum":["none","all","in_school"]},"groups":{"description":"The list of groups allowed to access the exam session.\nLeave empty if all exam's examinees are allowed to access this exam session.","example":["group1","group2"],"type":"array","items":{"type":"string"}}}},"examples":{"Basic":{"summary":"Basic ExamSession","value":{"name":"My Session"}},"With details":{"summary":"ExamSession with details","value":{"name":"My Session","groups":["Group 1","Group 2"],"allow_self_enrollment":"all","start_at":"2025-01-01T00:00:00Z","scheduled_end_at":"2025-01-01T00:00:00Z"}}}}}}}},"/exams/{exam_id}/exam_sessions/{id}":{"parameters":[{"name":"exam_id","in":"path","required":true,"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","description":"The id of the exam in Evalmee","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"example":"a1B2c3d4e5","description":"The id of the exam session in Evalmee","schema":{"type":"string"}}],"get":{"summary":"Retrieve an exam session","tags":["Exam Sessions"],"description":"Retrieve a given exam session, including scheduling, group restrictions, and self-enrollment options.\n","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/exam_session"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}}}},"patch":{"summary":"Update an exam session","tags":["Exam Sessions"],"description":"Update the properties of a given exam session, including scheduling, group restrictions, and self-enrollment options.\n","parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/exam_session"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"examples":{"invalid_schema":{"value":{"error":"invalid_schema","status_code":422,"messages":["name must be filled","scheduled_end_at must be a date time","allow_self_enrollment must be one of: none, all, in_school","groups must be an array"]}}},"schema":{"$ref":"#/components/schemas/error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"The name of the exam session","example":"Session 1"},"start_at":{"description":"The start date and time of the exam session (ISO 8601).\nLeave empty if you don't want to schedule a start date.","example":"2025-01-01T00:00:00Z","type":["null","string"],"format":"date-time"},"scheduled_end_at":{"description":"The scheduled end date and time of the exam session (ISO 8601).\nLeave empty if you don't want to schedule an end date.","example":"2025-01-01T00:00:00Z","type":["null","string"],"format":"date-time"},"allow_self_enrollment":{"description":"Whether to allow examinees to enroll themselves in the exam session.\n\n- `none` = forbid self enrollment\n\n- `all` = allow all examinees to enroll themselves\n\n- `in_school` = allow only examinees with an email matching the school domain to enroll themselves","example":"none","type":"string","minLength":1,"enum":["none","all","in_school"]},"groups":{"description":"The list of groups allowed to access the exam session.\nLeave empty if all exam's examinees are allowed to access this exam session.","example":["group1","group2"],"type":"array","items":{"type":"string"}}}},"examples":{"Basic":{"summary":"Basic ExamSession","value":{"name":"My Session"}},"With details":{"summary":"ExamSession with details","value":{"name":"My Session","groups":["Group 1","Group 2"],"allow_self_enrollment":"all","start_at":"2025-01-01T00:00:00Z","scheduled_end_at":"2025-01-01T00:00:00Z"}}}}}}}},"/exams/{exam_id}/examinees/{examinee_id}/invitations":{"parameters":[{"name":"exam_id","in":"path","required":true,"example":"a1b2c3d4-e5f6-7a8b-9c0d-e1f2a3b4c5d6","description":"The id of the exam in Evalmee","schema":{"type":"string"}},{"name":"examinee_id","in":"path","required":true,"example":"b2c3d4e5-f6a7-8b9c-0d1e-f2a3b4c5d6e7","description":"The id of the examinee in Evalmee","schema":{"type":"string"}},{"name":"exam_session_id","in":"query","required":true,"example":"a1B2c3d4e5","description":"The id of the exam session the invitation is about. Required even though the\nrecipient is fixed: an examinee can sit the same exam in several sessions.\n","schema":{"type":"string"}}],"post":{"summary":"Send an invitation to a single examinee","tags":["Invitations"],"description":"Send an invitation email to one examinee for a given exam session.\n\nSending again is how a reminder is issued: each send creates its own invitation,\nso the full history stays readable through the emails endpoint. Provide `content_override`\nto give the reminder a body of its own.\n","parameters":[],"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/email"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"examples":{"Invalid content override":{"value":{"error":"invalid_schema","status_code":422,"messages":["content_override must be filled"]}},"Missing exam session":{"value":{"error":"invalid_schema","status_code":422,"messages":["exam_session_id is missing"]}}},"schema":{"$ref":"#/components/schemas/error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"content_override":{"description":"The body of the invitation email, overriding the exam's default convocation\ntemplate for this send only. Omit the key to use the exam's default — an\nempty string is rejected rather than treated as \"no override\".\n\nAvailable placeholders:\n- `{{first_name}}` — The examinee's first name (also: `{{prenom}}`, `{{prénom}}`)\n- `{{last_name}}` — The examinee's last name (also: `{{nom}}`, `{{nom_de_famille}}`)\n- `{{full_name}}` — The examinee's first and last name (also: `{{nom_entier}}`, `{{nom_complet}}`)\n- `{{email}}` — The examinee's email address (also: `{{mail}}`, `{{e-mail}}`)\n- `{{student_id}}` — The examinee's student id in the school (also: `{{identifiant}}`, `{{id}}`)\n- `{{quiz}}` — The name of the exam (also: `{{quiz_name}}`, `{{exam}}`, `{{examen}}`)\n- `{{lien_de_connexion}}` — A link to the exam, labelled in the examinee's own language\n- `{{lien_de_connexion_fr}}` — A link to the exam, labelled in French\n- `{{lien_de_connexion_en}}` — A link to the exam, labelled in English\n- `{{note}}` — The examinee's grade, or a placeholder when it is withheld (also: `{{grade}}`)\n- `{{date}}` — The day the exam session opens (also: `{{start_date}}`)\n- `{{date_de_fin}}` — The day the exam session closes, time accommodation included (also: `{{stop_date}}`)\n- `{{debut}}` — The time the exam session opens (also: `{{début}}`, `{{heure_de_debut}}`, `{{heure_de_début}}`, `{{start}}`, `{{start_time}}`)\n- `{{fin}}` — The time the exam session closes, time accommodation included (also: `{{heure_de_fin}}`, `{{end}}`, `{{end_time}}`)\n- `{{publication}}` — The time the grades are published (also: `{{heure_de_publication}}`, `{{publish}}`, `{{publish_time}}`)\n- `{{fuseau_horaire}}` — The time zone the exam times are expressed in (also: `{{time_zone}}`)\n- `{{duree}}` — How long the examinee has to answer, time accommodation included (also: `{{durée}}`, `{{duration}}`, `{{length}}`)","example":"Hello {{first_name}}, your exam starts at {{debut}}. {{lien_de_connexion}}","type":"string","minLength":1}}},"examples":{"Basic":{"summary":"Send the exam's default convocation","value":{}},"With custom content":{"summary":"Send a reminder with its own body","value":{"content_override":"Hello {{first_name}}, your exam starts at {{debut}}. {{lien_de_connexion}}"}}}}}}}},"/exams/{exam_id}/examinees":{"parameters":[{"name":"exam_id","in":"path","required":true,"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","description":"The id of the exam in Evalmee","schema":{"type":"string"}}],"get":{"summary":"List all examinees","tags":["Examinees"],"description":"List all examinees enrolled in a given exam. \n\nExaminees can be assigned to one or more groups.\n","parameters":[{"name":"filter[email]","in":"query","required":false,"example":"john.doe@example.com","description":"Only return the examinee with this email","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/examinee"}},"meta":{"$ref":"#/components/schemas/pagination_meta"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}}}},"post":{"summary":"Enroll an examinee","tags":["Examinees"],"description":"Enroll an examinee into a given exam. The examinee account is created automatically if it does not exist.\nNo email is sent upon enrollment.\n","parameters":[],"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/examinee"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"examples":{"invalid_schema":{"value":{"error":"invalid_schema","status_code":422,"messages":["email must be a valid email address"]}}},"schema":{"$ref":"#/components/schemas/error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"first_name":{"description":"The first name of the examinee","example":"John","type":"string","minLength":1},"last_name":{"description":"The last name of the examinee","example":"Doe","type":"string","minLength":1},"groups":{"description":"The list of groups the examinee belongs to. Replace the existing groups if any. Skip to keep the existing groups.","example":["Group 1","Group 2"],"type":"array","items":{"type":"string"}},"id":{"description":"The id of the examinee","example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","type":"string","minLength":1,"pattern":"^[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}$"},"user_id":{"description":"The id of the user in your organization's directory. Unlike `id`, which names an enrollment and must already exist, this names a **user**: if they are not enrolled in this exam yet, they get enrolled.","example":"b2c3d4e5-f6a7-4b9c-8d1e-f2a3b4c5d6e7","type":"string","minLength":1,"pattern":"^[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}$"},"email":{"description":"The email of the examinee","example":"john.doe@example.com","type":"string","minLength":1,"format":"email"},"external_id":{"description":"The id of this examinee in your own system. Used to find them, ahead of `email` but behind `id` and `user_id`; when it matches nobody yet, `email` takes over and the person is created carrying it. Cannot be removed from here: send null to `PATCH /users/{id}` instead.","example":"STU-2024-0142","type":"string","minLength":1},"mark_for_destruction":{"description":"If true, the examinee will be deleted.","example":false,"type":"boolean"},"groups_to_add":{"description":"The list of groups to add to the examinee.","example":["Group 3","Group 4"],"type":"array","items":{"type":"string"}},"groups_to_remove":{"description":"The list of groups to remove from the examinee.","example":["Group 1","Group 2"],"type":"array","items":{"type":"string"}}}},"examples":{"Basic":{"summary":"Enroll an examinee","value":{"email":"john.doe@example.com","first_name":"John","last_name":"Doe"}},"With your own id":{"summary":"Enroll an examinee carrying your system's id","value":{"email":"john.doe@example.com","first_name":"John","last_name":"Doe","external_id":"STU-2024-0142"}},"With groups":{"summary":"Enroll an examinee with groups","value":{"email":"john.doe@example.com","first_name":"John","last_name":"Doe"}}}}}}},"patch":{"summary":"Batch manage examinees","tags":["Examinees"],"description":"Batch enroll, update, or unenroll examinees for a given exam in a single operation. \n \nExaminee accounts are created automatically if needed.\n\nNo email is sent upon enrollment.\n","parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"errors_count":{"type":"integer"},"data":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer"},"status":{"type":"string","enum":["error","created","updated","deleted","ignored"]},"error":{"$ref":"#/components/schemas/error"},"data":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/examinee"}]}},"required":["index","status"]}}},"required":["errors_count","data"]}}}},"207":{"description":"Multi-Status","content":{"application/json":{"schema":{"type":"object","properties":{"errors_count":{"type":"integer"},"data":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer"},"status":{"type":"string","enum":["error","created","updated","deleted","ignored"]},"error":{"$ref":"#/components/schemas/error"},"data":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/examinee"}]}},"required":["index","status"]}}},"required":["errors_count","data"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"examples":{"Partial failure":{"value":{"errors_count":3,"data":[{"index":2,"status":"error","error":{"error":"protected_field","status_code":422,"messages":["Can't update user email"]}},{"index":3,"status":"error","error":{"error":"not_found","status_code":422,"messages":["examinee not found"]}},{"index":4,"status":"error","error":{"error":"not_found","status_code":422,"messages":["examinee not found"]}}]}},"invalid_schema":{"value":{"error":"invalid_schema","status_code":422,"messages":["examinees is missing"]}}},"schema":{"oneOf":[{"type":"object","properties":{"errors_count":{"type":"integer"},"data":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer"},"status":{"type":"string","enum":["error","created","updated","deleted","ignored"]},"error":{"$ref":"#/components/schemas/error"},"data":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/examinee"}]}},"required":["index","status"]}}},"required":["errors_count","data"]},{"$ref":"#/components/schemas/error"}]}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"examinees":{"type":"array","items":{"type":"object","properties":{"first_name":{"description":"The first name of the examinee","example":"John","type":"string","minLength":1},"last_name":{"description":"The last name of the examinee","example":"Doe","type":"string","minLength":1},"groups":{"description":"The list of groups the examinee belongs to. Replace the existing groups if any. Skip to keep the existing groups.","example":["Group 1","Group 2"],"type":"array","items":{"type":"string"}},"id":{"description":"The id of the examinee","example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","type":"string","minLength":1,"pattern":"^[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}$"},"user_id":{"description":"The id of the user in your organization's directory. Unlike `id`, which names an enrollment and must already exist, this names a **user**: if they are not enrolled in this exam yet, they get enrolled.","example":"b2c3d4e5-f6a7-4b9c-8d1e-f2a3b4c5d6e7","type":"string","minLength":1,"pattern":"^[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}$"},"email":{"description":"The email of the examinee","example":"john.doe@example.com","type":"string","minLength":1,"format":"email"},"external_id":{"description":"The id of this examinee in your own system. Used to find them, ahead of `email` but behind `id` and `user_id`; when it matches nobody yet, `email` takes over and the person is created carrying it. Cannot be removed from here: send null to `PATCH /users/{id}` instead.","example":"STU-2024-0142","type":"string","minLength":1},"mark_for_destruction":{"description":"If true, the examinee will be deleted.","example":false,"type":"boolean"},"groups_to_add":{"description":"The list of groups to add to the examinee.","example":["Group 3","Group 4"],"type":"array","items":{"type":"string"}},"groups_to_remove":{"description":"The list of groups to remove from the examinee.","example":["Group 1","Group 2"],"type":"array","items":{"type":"string"}}},"minLength":1,"maxLength":50}},"allow_partial_success":{"description":"If false, no examinees will be created if one or more fail to be created.","example":false,"type":"boolean"}},"required":["examinees"]},"examples":{"Enroll examinees":{"summary":"Enroll two examinees to the exam","value":{"examinees":[{"email":"john.doe.student@example.com","first_name":"John","last_name":"Doe"},{"email":"jane.doe.student@example.com","first_name":"Jane","last_name":"Doe"}]}},"Enroll examinees with groups":{"summary":"Enroll two examinees to the exam with groups","value":{"examinees":[{"email":"john.doe.student@example.com","first_name":"John","last_name":"Doe","groups":["Group 1"]},{"email":"jane.doe.student@example.com","first_name":"Jane","last_name":"Doe","groups":["Group 2"]}]}},"Update examinees groups":{"summary":"Replace the groups of two examinees already in the exam","value":{"examinees":[{"email":"john.doe.student@example.com","groups":["Group 3"]},{"email":"jane.doe.student@example.com","groups":["Group 4"]}]}},"Update groups of examinees":{"summary":"Add and remove groups from two examinees already in the exam","value":{"examinees":[{"email":"john.doe.student@example.com","groups_to_add":["Group 3"],"groups_to_remove":["Group 1"]},{"email":"jane.doe.student@example.com","groups_to_add":["Group 4"],"groups_to_remove":["Group 2"]}]}},"Unenroll two examinees":{"summary":"Uneroll two examinees from the exam","value":{"examinees":[{"email":"john.doe.student@example.com","mark_for_destruction":true},{"email":"jane.doe.student@example.com","mark_for_destruction":true}]}}}}}}}},"/exams/{exam_id}/examinees/{id}":{"parameters":[{"name":"exam_id","in":"path","required":true,"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","description":"The id of the exam in Evalmee","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","description":"The id of the examinee in this exam in Evalmee","schema":{"type":"string"}}],"get":{"summary":"Retrieve an examinee","tags":["Examinees"],"description":"Retrieve a given examinee for a given exam, including their group assignments.\n","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/examinee"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}}}},"patch":{"summary":"Update an examinee","tags":["Examinees"],"description":"Update the information or group assignments of a given examinee for a given exam.","parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/examinee"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"examples":{"invalid_schema":{"value":{"error":"invalid_schema","status_code":422,"messages":["first_name must be filled"]}}},"schema":{"$ref":"#/components/schemas/error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"first_name":{"description":"The first name of the examinee","example":"John","type":"string","minLength":1},"last_name":{"description":"The last name of the examinee","example":"Doe","type":"string","minLength":1},"groups":{"description":"The list of groups the examinee belongs to. Replace the existing groups if any. Skip to keep the existing groups.","example":["Group 1","Group 2"],"type":"array","items":{"type":"string"}},"id":{"description":"The id of the examinee","example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","type":"string","minLength":1,"pattern":"^[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}$"},"user_id":{"description":"The id of the user in your organization's directory. Unlike `id`, which names an enrollment and must already exist, this names a **user**: if they are not enrolled in this exam yet, they get enrolled.","example":"b2c3d4e5-f6a7-4b9c-8d1e-f2a3b4c5d6e7","type":"string","minLength":1,"pattern":"^[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}$"},"email":{"description":"The email of the examinee","example":"john.doe@example.com","type":"string","minLength":1,"format":"email"},"external_id":{"description":"The id of this examinee in your own system. Used to find them, ahead of `email` but behind `id` and `user_id`; when it matches nobody yet, `email` takes over and the person is created carrying it. Cannot be removed from here: send null to `PATCH /users/{id}` instead.","example":"STU-2024-0142","type":"string","minLength":1},"mark_for_destruction":{"description":"If true, the examinee will be deleted.","example":false,"type":"boolean"},"groups_to_add":{"description":"The list of groups to add to the examinee.","example":["Group 3","Group 4"],"type":"array","items":{"type":"string"}},"groups_to_remove":{"description":"The list of groups to remove from the examinee.","example":["Group 1","Group 2"],"type":"array","items":{"type":"string"}}}},"examples":{"Name update":{"summary":"Update an examinee name","value":{"first_name":"Examinee","last_name":"Doe"}},"Replace groups":{"summary":"Replace the groups of an examinee","value":{"groups":["Group 3"]}},"Add and remove groups":{"summary":"Add and remove groups from an examinee","value":{"groups_to_add":["Group 3"],"groups_to_remove":["Group 1"]}}}}}}},"delete":{"summary":"Unenroll an examinee","tags":["Examinees"],"description":"Unenroll a given examinee from a given exam. All associated attempts and results are deleted, but the examinee account is preserved.\n","responses":{"204":{"description":"Success"},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}}}}},"/exams":{"get":{"summary":"List all exams","tags":["Exams"],"description":"List all exams in your organization.\n","parameters":[{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","default":50,"minimum":1,"maximum":100},"description":"Number of items per page. Above 100, the value is reduced, not rejected."},{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"minimum":1},"description":"Page number"}],"responses":{"200":{"description":"Success with string per_page parameter","content":{"application/json":{"examples":{"An online (Evalmee) and a paper (Papeez) exam":{"value":{"data":[{"id":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","assessment_criteria":{"data":[{"id":"b2c3d4e5-f6a7-4b8c-9d0e-f1f2f3f4f5f6","code":"CE1.1","description":"Use of appropriate tools and methods to gather information in a structured manner","links":{"self":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/assessment_criteria/b2c3d4e5-f6a7-4b8c-9d0e-f1f2f3f4f5f6","exam":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"},"name":"Data collection methodology"}],"meta":{"count":1,"current_page":1,"next_page":null,"prev_page":null,"total_count":1,"total_pages":1,"links":{"first":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/assessment_criteria?page=1","last":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/assessment_criteria?page=1"}}},"email_custom_instructions":{"content":"Hello {{first_name}}, your exam starts at {{debut}}. {{lien_de_connexion}}","subject":"Exam | Mathematics","convocation_subject":"Exam | Mathematics","grade_subject":"Your grade | Mathematics","name_sender":"A teacher via Evalmee","email_sender":"contact@evalmee.com","name_reply_to":"A teacher","email_reply_to":"teacher@example.com"},"exam_sessions":{"data":[{"id":"a1B2c3d4e5","allow_self_enrollment":"none","groups":[],"links":{"self":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/exam_sessions/a1B2c3d4e5","exam":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","emails":"https://app.evalmee.com/api/public/v2/emails?exam_id=a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6&exam_session_id=a1B2c3d4e5"},"name":"All students","scheduled_end_at":"2025-06-02T10:00:00Z","start_at":"2025-06-02T08:00:00Z","web_app_examinee_enrollment_url":"https://app.evalmee.com/join/a1B2c3d4e5-mathematics-final-exam-all-students"}],"meta":{"count":1,"current_page":1,"next_page":null,"prev_page":null,"total_count":1,"total_pages":1,"links":{"first":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/exam_sessions?page=1","last":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/exam_sessions?page=1"}}},"grade_scale":20,"grading_mode":"criteria","links":{"self":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","exam_attempts":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/exam_attempts","exam_results":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/results","exam_sessions":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/exam_sessions","assessment_criteria":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/assessment_criteria","examinees":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/examinees","emails":"https://app.evalmee.com/api/public/v2/emails?exam_id=a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"},"name":"Mathematics final exam","random_choices":false,"random_exercises":false,"random_questions":false,"random_sections":false,"time_accommodation":true,"time_limit":3600,"time_limit_mode":"global","type":"online","web_app_url":"https://app.evalmee.com/front/1234/evalmee_editor"},{"id":"c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7","assessment_criteria":{"data":[],"meta":{"count":0,"current_page":1,"next_page":null,"prev_page":null,"total_count":0,"total_pages":0,"links":{"first":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/assessment_criteria?page=1","last":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/assessment_criteria?page=1"}}},"email_custom_instructions":{"content":"Hello {{first_name}}, your exam starts at {{debut}}.","subject":"Exam | History","convocation_subject":"Exam | History","grade_subject":"Your grade | History","name_sender":"A teacher via Papeez","email_sender":"contact@papeez.com","name_reply_to":"A teacher","email_reply_to":"teacher@example.com"},"exam_sessions":{"data":[{"id":"f6E7g8h9i0","allow_self_enrollment":"none","groups":[],"links":{"self":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/exam_sessions/f6E7g8h9i0","exam":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7","emails":"https://app.evalmee.com/api/public/v2/emails?exam_id=c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7&exam_session_id=f6E7g8h9i0"},"name":"Amphitheater A","scheduled_end_at":"2025-06-03T11:00:00Z","start_at":"2025-06-03T09:00:00Z","web_app_examinee_enrollment_url":"https://app.evalmee.com/join/f6E7g8h9i0-history-mid-term-amphitheater-a"}],"meta":{"count":1,"current_page":1,"next_page":null,"prev_page":null,"total_count":1,"total_pages":1,"links":{"first":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/exam_sessions?page=1","last":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/exam_sessions?page=1"}}},"grade_scale":20,"grading_mode":"global","links":{"self":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7","exam_attempts":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/exam_attempts","exam_results":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/results","exam_sessions":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/exam_sessions","assessment_criteria":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/assessment_criteria","examinees":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/examinees","emails":"https://app.evalmee.com/api/public/v2/emails?exam_id=c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7","paper":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/paper"},"name":"History mid-term","paper":{"build":{"status":"generated","progress":{"done":120,"total":120}},"copies_count":120,"copy_type":"anonymous","links":{"self":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/paper","exam":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7","all_copies":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/paper/all_copies","answer_sheets":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/paper/answer_sheets","individual_copies":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/paper/individual_copies","question_sheets":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/paper/question_sheets"}},"random_choices":false,"random_exercises":false,"random_questions":false,"random_sections":false,"time_accommodation":false,"time_limit":null,"time_limit_mode":"global","type":"paper","web_app_url":"https://app.evalmee.com/front/5678/papeez_editor"}],"meta":{"count":2,"current_page":1,"next_page":null,"prev_page":null,"total_count":2,"total_pages":1,"links":{"first":"https://app.evalmee.com/api/public/v2/exams?page=1","last":"https://app.evalmee.com/api/public/v2/exams?page=1"}}}}},"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/exam"}},"meta":{"$ref":"#/components/schemas/pagination_meta"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}}}},"post":{"summary":"Create an exam","tags":["Exams"],"description":"Create a new exam with optional settings.\n","parameters":[],"responses":{"201":{"description":"Created keeping the defaults it was not given","content":{"application/json":{"examples":{"Without assessment criteria":{"value":{"id":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","name":"My exam","grade_scale":15,"grading_mode":"global","time_limit":7200,"time_limit_mode":"per_question","time_accommodation":true,"random_sections":true,"random_questions":true,"random_exercises":true,"random_choices":true,"type":"online","web_app_url":"https://app.evalmee.com/evalmee_editor/1/evalmee_editor","exam_sessions":{"data":[{"id":"a1B2c3d4e5","name":"My general session","start_at":"2025-01-01T08:00:00Z","scheduled_end_at":null,"allow_self_enrollment":"none","web_app_examinee_enrollment_url":"https://app.evalmee.com/join/a1B2c3d4e5-my-exam-my-general-session","groups":[],"links":{"self":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/exam_sessions/a1B2c3d4e5","exam":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"}}],"meta":{"count":1,"current_page":1,"next_page":null,"prev_page":null,"total_count":1,"total_pages":1,"links":{"first":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/exam_sessions?page=1","last":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/exam_sessions?page=1"}}},"assessment_criteria":{"data":[],"meta":{"count":0,"current_page":1,"next_page":null,"prev_page":null,"total_count":0,"total_pages":0,"links":{"first":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/assessment_criteria?page=1","last":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/assessment_criteria?page=1"}}},"links":{"self":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","exam_attempts":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/exam_attempts","exam_results":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/results","examinees":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/examinees"}}},"With assessment criteria":{"value":{"id":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","name":"Exam with criteria","grade_scale":20,"grading_mode":"criteria","time_limit":null,"time_limit_mode":"global","time_accommodation":false,"random_sections":false,"random_questions":false,"random_exercises":false,"random_choices":false,"type":"online","web_app_url":"https://app.evalmee.com/evalmee_editor/1/evalmee_editor","exam_sessions":{"data":[{"id":"a1B2c3d4e5","name":"Session 1","start_at":null,"scheduled_end_at":null,"allow_self_enrollment":"none","web_app_examinee_enrollment_url":"https://app.evalmee.com/join/a1B2c3d4e5-exam-with-criteria-session-1","groups":[],"links":{"self":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/exam_sessions/a1B2c3d4e5","exam":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"}}],"meta":{"count":1,"current_page":1,"next_page":null,"prev_page":null,"total_count":1,"total_pages":1,"links":{"first":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/exam_sessions?page=1","last":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/exam_sessions?page=1"}}},"assessment_criteria":{"data":[{"id":"b2c3d4e5-f6a7-4b8c-9d0e-f1f2f3f4f5f6","name":"Data collection methodology","code":"CE1.1","description":"Use of appropriate tools and methods to gather information in a structured manner","links":{"self":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/assessment_criteria/b2c3d4e5-f6a7-4b8c-9d0e-f1f2f3f4f5f6","exam":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"}},{"id":"c3d4e5f6-a7b8-4c9d-0e1f-f2f3f4f5f6f7","name":"Data structuring","code":"CE1.2","description":"Logical organization and relevant exploitation of collected information","links":{"self":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/assessment_criteria/c3d4e5f6-a7b8-4c9d-0e1f-f2f3f4f5f6f7","exam":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"}}],"meta":{"count":2,"current_page":1,"next_page":null,"prev_page":null,"total_count":2,"total_pages":1,"links":{"first":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/assessment_criteria?page=1","last":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/assessment_criteria?page=1"}}},"links":{"self":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","exam_attempts":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/exam_attempts","exam_results":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/results","examinees":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/examinees"}}}},"schema":{"$ref":"#/components/schemas/exam"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"422":{"description":"Unprocessable Entity when setting the sender address","content":{"application/json":{"examples":{"invalid_schema":{"value":{"error":"invalid_schema","status_code":422,"messages":["name must be filled","editors must be an array","grade_scale must be a float"]}},"Malformed reply-to":{"value":{"error":"invalid_schema","status_code":422,"messages":["email_custom_instructions.email_reply_to is in invalid format"]}},"Read-only sender":{"value":{"error":"invalid_schema","status_code":422,"messages":["email_custom_instructions.email_sender is not allowed"]}}},"schema":{"$ref":"#/components/schemas/error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"description":"The name of the exam","example":"My exam","type":"string","minLength":1},"owner":{"description":"The email of the owner of the exam. An Evalmee account should exist for this email.","example":"john.doe@example.com","type":"string","minLength":1},"editors":{"description":"ALPHA: The emails of the editors of the exam. An Evalmee account should exist for each email. This attribute may be deleted in the future.","example":["john.doe@example.com","jane.doe@example.com"],"type":"array","items":{"type":"string"}},"time_limit":{"description":"The answer time limit for the exam in seconds. Must be a multiple of 60 (leave null for no time limit)","example":3600,"type":["null","integer"]},"time_limit_mode":{"description":"How the time limit applies. 'global' for one countdown over the whole exam (default), 'per_question' to split the time limit evenly across the questions: each page of questions closes when its share is over and cannot be revisited. Requires a time_limit and is not compatible with free navigation nor with the correction between questions.","example":"per_question","type":"string","minLength":1,"enum":["global","per_question"]},"time_accommodation":{"description":"Whether to enable time accommodation. Can be enabled only if a time limit is set.","example":true,"type":"boolean"},"grade_scale":{"description":"The maximum grade for the exam (default is 20.0)","example":20,"type":"number"},"random_sections":{"description":"Whether to randomize the order of sections","example":false,"type":"boolean"},"random_questions":{"description":"Whether to randomize the order of questions in an exercise (or page of questions)","example":false,"type":"boolean"},"random_exercises":{"description":"Whether to randomize the order of exercises (pages of questions)","example":false,"type":"boolean"},"grading_mode":{"description":"The grading mode for the exam. 'global' for grading criteria per question, 'criteria' for shared quiz-level assessment criteria","example":"criteria","type":"string","minLength":1,"enum":["global","criteria"]},"random_choices":{"description":"Whether to randomize the order of choices in questions","example":false,"type":"boolean"},"email_custom_instructions":{"description":"The configuration of the emails sent to the examinees of this exam.\nOnly the keys you provide are set; the others keep their current value.\nThe sender address is fixed and cannot be set here; use `email_reply_to`\nto choose where replies go.\n\nPlaceholders available in `content`:\n- `{{first_name}}` — The examinee's first name (also: `{{prenom}}`, `{{prénom}}`)\n- `{{last_name}}` — The examinee's last name (also: `{{nom}}`, `{{nom_de_famille}}`)\n- `{{full_name}}` — The examinee's first and last name (also: `{{nom_entier}}`, `{{nom_complet}}`)\n- `{{email}}` — The examinee's email address (also: `{{mail}}`, `{{e-mail}}`)\n- `{{student_id}}` — The examinee's student id in the school (also: `{{identifiant}}`, `{{id}}`)\n- `{{quiz}}` — The name of the exam (also: `{{quiz_name}}`, `{{exam}}`, `{{examen}}`)\n- `{{lien_de_connexion}}` — A link to the exam, labelled in the examinee's own language\n- `{{lien_de_connexion_fr}}` — A link to the exam, labelled in French\n- `{{lien_de_connexion_en}}` — A link to the exam, labelled in English\n- `{{note}}` — The examinee's grade, or a placeholder when it is withheld (also: `{{grade}}`)\n- `{{date}}` — The day the exam session opens (also: `{{start_date}}`)\n- `{{date_de_fin}}` — The day the exam session closes, time accommodation included (also: `{{stop_date}}`)\n- `{{debut}}` — The time the exam session opens (also: `{{début}}`, `{{heure_de_debut}}`, `{{heure_de_début}}`, `{{start}}`, `{{start_time}}`)\n- `{{fin}}` — The time the exam session closes, time accommodation included (also: `{{heure_de_fin}}`, `{{end}}`, `{{end_time}}`)\n- `{{publication}}` — The time the grades are published (also: `{{heure_de_publication}}`, `{{publish}}`, `{{publish_time}}`)\n- `{{fuseau_horaire}}` — The time zone the exam times are expressed in (also: `{{time_zone}}`)\n- `{{duree}}` — How long the examinee has to answer, time accommodation included (also: `{{durée}}`, `{{duration}}`, `{{length}}`)","example":{"convocation_subject":"Exam | Mathematics","content":"Hello {{first_name}}, your exam starts at {{debut}}. {{lien_de_connexion}}"},"type":"object","properties":{"content":{"type":"string","minLength":1},"subject":{"type":"string","minLength":1},"convocation_subject":{"type":"string","minLength":1},"grade_subject":{"type":"string","minLength":1},"name_sender":{"type":"string","minLength":1},"name_reply_to":{"type":"string","minLength":1},"email_reply_to":{"type":"string","minLength":1}}},"exam_sessions":{"description":"The list of sessions to create for the exam. If not provided, a single session will becreated with no scheduling","example":[{"name":"My session","start_at":"2025-01-15T14:00:00Z","scheduled_end_at":"2025-01-15T16:00:00Z"},{"name":"My restricted session","groups":["Group 1"],"start_at":"2025-01-16T14:00:00Z"}],"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"The name of the exam session","example":"Session 1"},"start_at":{"description":"The start date and time of the exam session (ISO 8601).\nLeave empty if you don't want to schedule a start date.","example":"2025-01-01T00:00:00Z","type":["null","string"],"format":"date-time"},"scheduled_end_at":{"description":"The scheduled end date and time of the exam session (ISO 8601).\nLeave empty if you don't want to schedule an end date.","example":"2025-01-01T00:00:00Z","type":["null","string"],"format":"date-time"},"allow_self_enrollment":{"description":"Whether to allow examinees to enroll themselves in the exam session.\n\n- `none` = forbid self enrollment\n\n- `all` = allow all examinees to enroll themselves\n\n- `in_school` = allow only examinees with an email matching the school domain to enroll themselves","example":"none","type":"string","minLength":1,"enum":["none","all","in_school"]},"groups":{"description":"The list of groups allowed to access the exam session.\nLeave empty if all exam's examinees are allowed to access this exam session.","example":["group1","group2"],"type":"array","items":{"type":"string"}}}}},"assessment_criteria":{"description":"The list of assessment criteria to create for the exam. Only effective when grading_mode is set to 'criteria'.","example":[{"name":"Data collection methodology","code":"CE1.1","description":"Use of appropriate tools and methods to gather information in a structured manner"},{"name":"Data structuring","code":"CE1.2","description":"Logical organization and relevant exploitation of collected information"}],"type":"array","items":{"type":"object","properties":{"name":{"description":"The name of the assessment criterion","example":"Data collection methodology","type":"string","minLength":1},"description":{"description":"Description of the criterion","example":"Use of appropriate tools and methods to gather information in a structured manner","type":["null","string"]},"code":{"description":"Short code (max 10 chars, auto-generated if omitted)","example":"CE1.1","type":"string","minLength":1,"maxLength":10}},"required":["name"]}}},"required":["owner"]},"examples":{"Basic":{"summary":"Create an exam","value":{"name":"My exam","owner":"john.doe@example.com"}},"With exam sessions":{"summary":"Create an exam with exam sessions","value":{"name":"My exam","owner":"john.doe@example.com","exam_sessions":[{"name":"All students","start_at":"2025-01-01T08:00:00Z","scheduled_end_at":"2025-01-01T10:00:00Z"},{"name":"Groups 1 and 2","start_at":"2025-01-02T10:00:00Z","scheduled_end_at":"2025-01-02T12:00:00Z","groups":["Group 1","Group 2"]}]}},"With assessment criteria":{"summary":"Create an exam with assessment criteria","value":{"name":"My exam","owner":"john.doe@example.com","grading_mode":"criteria","assessment_criteria":[{"name":"Data collection methodology","code":"CE1.1","description":"Use of appropriate tools and methods to gather information in a structured manner"},{"name":"Data structuring","code":"CE1.2","description":"Logical organization and relevant exploitation of collected information"}]}},"With details":{"summary":"Create an exam with details","value":{"name":"My exam","owner":"john.doe@example.com","grade_scale":15,"time_limit":3600,"time_limit_mode":"per_question","time_accommodation":true,"random_sections":true,"random_questions":true,"random_exercises":true,"random_choices":true,"exam_sessions":[{"name":"All students","start_at":"2025-01-01T08:00:00Z","scheduled_end_at":"2025-01-01T10:00:00Z"}]}}}}}}}},"/exams/{id}":{"get":{"summary":"Retrieve an exam","tags":["Exams"],"description":"Retrieve a given exam, including settings and metadata.\n","parameters":[{"name":"id","in":"path","required":true,"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","description":"The id of the exam in Evalmee","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"examples":{"Online exam (Evalmee)":{"value":{"id":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","assessment_criteria":{"data":[{"id":"b2c3d4e5-f6a7-4b8c-9d0e-f1f2f3f4f5f6","code":"CE1.1","description":"Use of appropriate tools and methods to gather information in a structured manner","links":{"self":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/assessment_criteria/b2c3d4e5-f6a7-4b8c-9d0e-f1f2f3f4f5f6","exam":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"},"name":"Data collection methodology"}],"meta":{"count":1,"current_page":1,"next_page":null,"prev_page":null,"total_count":1,"total_pages":1,"links":{"first":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/assessment_criteria?page=1","last":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/assessment_criteria?page=1"}}},"email_custom_instructions":{"content":"Hello {{first_name}}, your exam starts at {{debut}}. {{lien_de_connexion}}","subject":"Exam | Mathematics","convocation_subject":"Exam | Mathematics","grade_subject":"Your grade | Mathematics","name_sender":"A teacher via Evalmee","email_sender":"contact@evalmee.com","name_reply_to":"A teacher","email_reply_to":"teacher@example.com"},"exam_sessions":{"data":[{"id":"a1B2c3d4e5","allow_self_enrollment":"none","groups":[],"links":{"self":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/exam_sessions/a1B2c3d4e5","exam":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","emails":"https://app.evalmee.com/api/public/v2/emails?exam_id=a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6&exam_session_id=a1B2c3d4e5"},"name":"All students","scheduled_end_at":"2025-06-02T10:00:00Z","start_at":"2025-06-02T08:00:00Z","web_app_examinee_enrollment_url":"https://app.evalmee.com/join/a1B2c3d4e5-mathematics-final-exam-all-students"}],"meta":{"count":1,"current_page":1,"next_page":null,"prev_page":null,"total_count":1,"total_pages":1,"links":{"first":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/exam_sessions?page=1","last":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/exam_sessions?page=1"}}},"grade_scale":20,"grading_mode":"criteria","links":{"self":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","exam_attempts":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/exam_attempts","exam_results":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/results","exam_sessions":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/exam_sessions","assessment_criteria":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/assessment_criteria","examinees":"https://app.evalmee.com/api/public/v2/exams/a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6/examinees","emails":"https://app.evalmee.com/api/public/v2/emails?exam_id=a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"},"name":"Mathematics final exam","random_choices":false,"random_exercises":false,"random_questions":false,"random_sections":false,"time_accommodation":true,"time_limit":3600,"time_limit_mode":"global","type":"online","web_app_url":"https://app.evalmee.com/front/1234/evalmee_editor"}},"Paper exam (Papeez)":{"value":{"id":"c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7","assessment_criteria":{"data":[],"meta":{"count":0,"current_page":1,"next_page":null,"prev_page":null,"total_count":0,"total_pages":0,"links":{"first":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/assessment_criteria?page=1","last":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/assessment_criteria?page=1"}}},"email_custom_instructions":{"content":"Hello {{first_name}}, your exam starts at {{debut}}.","subject":"Exam | History","convocation_subject":"Exam | History","grade_subject":"Your grade | History","name_sender":"A teacher via Papeez","email_sender":"contact@papeez.com","name_reply_to":"A teacher","email_reply_to":"teacher@example.com"},"exam_sessions":{"data":[{"id":"f6E7g8h9i0","allow_self_enrollment":"none","groups":[],"links":{"self":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/exam_sessions/f6E7g8h9i0","exam":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7","emails":"https://app.evalmee.com/api/public/v2/emails?exam_id=c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7&exam_session_id=f6E7g8h9i0"},"name":"Amphitheater A","scheduled_end_at":"2025-06-03T11:00:00Z","start_at":"2025-06-03T09:00:00Z","web_app_examinee_enrollment_url":"https://app.evalmee.com/join/f6E7g8h9i0-history-mid-term-amphitheater-a"}],"meta":{"count":1,"current_page":1,"next_page":null,"prev_page":null,"total_count":1,"total_pages":1,"links":{"first":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/exam_sessions?page=1","last":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/exam_sessions?page=1"}}},"grade_scale":20,"grading_mode":"global","links":{"self":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7","exam_attempts":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/exam_attempts","exam_results":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/results","exam_sessions":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/exam_sessions","assessment_criteria":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/assessment_criteria","examinees":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/examinees","emails":"https://app.evalmee.com/api/public/v2/emails?exam_id=c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7","paper":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/paper"},"name":"History mid-term","paper":{"build":{"status":"generated","progress":{"done":120,"total":120}},"copies_count":120,"copy_type":"anonymous","links":{"self":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/paper","exam":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7","all_copies":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/paper/all_copies","answer_sheets":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/paper/answer_sheets","individual_copies":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/paper/individual_copies","question_sheets":"https://app.evalmee.com/api/public/v2/exams/c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7/paper/question_sheets"}},"random_choices":false,"random_exercises":false,"random_questions":false,"random_sections":false,"time_accommodation":false,"time_limit":null,"time_limit_mode":"global","type":"paper","web_app_url":"https://app.evalmee.com/front/5678/papeez_editor"}}},"schema":{"$ref":"#/components/schemas/exam"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}}}},"patch":{"summary":"Update an exam","tags":["Exams"],"description":"Update the properties of a given exam.\n","parameters":[{"name":"id","in":"path","required":true,"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","description":"The id of the exam in Evalmee","schema":{"type":"string"}}],"responses":{"200":{"description":"Success updating only some email custom instructions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/exam"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}},"422":{"description":"Unprocessable Entity with a malformed reply-to email","content":{"application/json":{"examples":{"invalid_schema":{"value":{"error":"invalid_schema","status_code":422,"messages":["name must be filled","editors must be an array","grade_scale must be a float"]}},"Malformed reply-to":{"value":{"error":"invalid_schema","status_code":422,"messages":["email_custom_instructions.email_reply_to is in invalid format"]}}},"schema":{"$ref":"#/components/schemas/error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"description":"The name of the exam","example":"My exam","type":"string","minLength":1},"owner":{"description":"The email of the owner of the exam. An Evalmee account should exist for this email.","example":"john.doe@example.com","type":"string","minLength":1},"editors":{"description":"ALPHA: The emails of the editors of the exam. An Evalmee account should exist for each email. This attribute may be deleted in the future.","example":["john.doe@example.com","jane.doe@example.com"],"type":"array","items":{"type":"string"}},"time_limit":{"description":"The answer time limit for the exam in seconds. Must be a multiple of 60 (leave null for no time limit)","example":3600,"type":["null","integer"]},"time_limit_mode":{"description":"How the time limit applies. 'global' for one countdown over the whole exam (default), 'per_question' to split the time limit evenly across the questions: each page of questions closes when its share is over and cannot be revisited. Requires a time_limit and is not compatible with free navigation nor with the correction between questions.","example":"per_question","type":"string","minLength":1,"enum":["global","per_question"]},"time_accommodation":{"description":"Whether to enable time accommodation. Can be enabled only if a time limit is set.","example":true,"type":"boolean"},"grade_scale":{"description":"The maximum grade for the exam (default is 20.0)","example":20,"type":"number"},"random_sections":{"description":"Whether to randomize the order of sections","example":false,"type":"boolean"},"random_questions":{"description":"Whether to randomize the order of questions in an exercise (or page of questions)","example":false,"type":"boolean"},"random_exercises":{"description":"Whether to randomize the order of exercises (pages of questions)","example":false,"type":"boolean"},"grading_mode":{"description":"The grading mode for the exam. 'global' for grading criteria per question, 'criteria' for shared quiz-level assessment criteria","example":"criteria","type":"string","minLength":1,"enum":["global","criteria"]},"random_choices":{"description":"Whether to randomize the order of choices in questions","example":false,"type":"boolean"},"email_custom_instructions":{"description":"The configuration of the emails sent to the examinees of this exam.\nOnly the keys you provide are set; the others keep their current value.\nThe sender address is fixed and cannot be set here; use `email_reply_to`\nto choose where replies go.\n\nPlaceholders available in `content`:\n- `{{first_name}}` — The examinee's first name (also: `{{prenom}}`, `{{prénom}}`)\n- `{{last_name}}` — The examinee's last name (also: `{{nom}}`, `{{nom_de_famille}}`)\n- `{{full_name}}` — The examinee's first and last name (also: `{{nom_entier}}`, `{{nom_complet}}`)\n- `{{email}}` — The examinee's email address (also: `{{mail}}`, `{{e-mail}}`)\n- `{{student_id}}` — The examinee's student id in the school (also: `{{identifiant}}`, `{{id}}`)\n- `{{quiz}}` — The name of the exam (also: `{{quiz_name}}`, `{{exam}}`, `{{examen}}`)\n- `{{lien_de_connexion}}` — A link to the exam, labelled in the examinee's own language\n- `{{lien_de_connexion_fr}}` — A link to the exam, labelled in French\n- `{{lien_de_connexion_en}}` — A link to the exam, labelled in English\n- `{{note}}` — The examinee's grade, or a placeholder when it is withheld (also: `{{grade}}`)\n- `{{date}}` — The day the exam session opens (also: `{{start_date}}`)\n- `{{date_de_fin}}` — The day the exam session closes, time accommodation included (also: `{{stop_date}}`)\n- `{{debut}}` — The time the exam session opens (also: `{{début}}`, `{{heure_de_debut}}`, `{{heure_de_début}}`, `{{start}}`, `{{start_time}}`)\n- `{{fin}}` — The time the exam session closes, time accommodation included (also: `{{heure_de_fin}}`, `{{end}}`, `{{end_time}}`)\n- `{{publication}}` — The time the grades are published (also: `{{heure_de_publication}}`, `{{publish}}`, `{{publish_time}}`)\n- `{{fuseau_horaire}}` — The time zone the exam times are expressed in (also: `{{time_zone}}`)\n- `{{duree}}` — How long the examinee has to answer, time accommodation included (also: `{{durée}}`, `{{duration}}`, `{{length}}`)","example":{"convocation_subject":"Exam | Mathematics","content":"Hello {{first_name}}, your exam starts at {{debut}}. {{lien_de_connexion}}"},"type":"object","properties":{"content":{"type":"string","minLength":1},"subject":{"type":"string","minLength":1},"convocation_subject":{"type":"string","minLength":1},"grade_subject":{"type":"string","minLength":1},"name_sender":{"type":"string","minLength":1},"name_reply_to":{"type":"string","minLength":1},"email_reply_to":{"type":"string","minLength":1}}},"editors_to_add":{"description":"The emails of the editors to add to the exam. An Evalmee account should exist for each email.","example":["john.doe@example.com","jane.doe@example.com"],"type":"array","items":{"type":"string"}},"editors_to_remove":{"description":"The emails of the editors to remove from the exam.","example":["john.doe@example.com","jane.doe@example.com"],"type":"array","items":{"type":"string"}}}}}}}},"delete":{"summary":"Delete an exam","tags":["Exams"],"description":"Delete a given exam, including all related examinees, attempts, and results.\n","parameters":[{"name":"id","in":"path","required":true,"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","description":"The id of the exam in Evalmee","schema":{"type":"string"}}],"responses":{"204":{"description":"Success"},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}}}}},"/organization":{"get":{"summary":"Retrieve your organization","tags":["Organization"],"description":"Retrieve the organization (school) that owns the API key used to authenticate.\n","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/organization"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}}}}},"/exams/{exam_id}/paper/scans":{"parameters":[{"name":"exam_id","in":"path","example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","description":"The id in Evalmee of the paper exam","required":true,"schema":{"type":"string"}}],"post":{"summary":"Import scanned copies of a paper exam","tags":["Paper Exams"],"description":"Sends back a PDF of scanned copies and starts the automatic grading on it.\n\n**One PDF per request, 20 MB at most.** A larger batch is split into several\nimports: they accumulate on the exam, and no previous one is replaced. The\nanswer is a `202` — the analysis is queued, not finished — carrying the paper\nsub-resource, whose `pages_imported` and `pages_processed` follow the progress.\n\nAn anonymous exam identifies each copy by running OCR on the handwritten name,\nso it needs a list to compare against: importing before any examinee is\nenrolled is refused with `no_examinees`. A nominative exam has no such\nprecondition, and neither mode requires the copies to have been generated.\n\nPages the analysis cannot attach to an examinee are resolved in the web\napplication. The API exposes no per-page detail, and an integration that never\nopens the web application is not a supported scenario.\n","parameters":[],"responses":{"202":{"description":"Accepted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/paper_detail"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"examples":{"no_examinees":{"value":{"error":"no_examinees","status_code":422,"messages":["Add students to the exam before importing scanned copies of an anonymous paper exam"]}},"not_a_pdf":{"value":{"error":"invalid_file","status_code":422,"messages":["The file must be a PDF"]}},"file_too_large":{"value":{"error":"invalid_file","status_code":422,"messages":["The file must be 20 MB or smaller"]}}},"schema":{"$ref":"#/components/schemas/error"}}}}},"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"The PDF of scanned copies, 20 MB at most"}},"required":["file"]}}},"required":true}}},"/exams/{exam_id}/paper":{"parameters":[{"name":"exam_id","in":"path","example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","description":"The id in Evalmee of the paper exam","required":true,"schema":{"type":"string"}}],"get":{"summary":"Retrieve the paper configuration of an exam","tags":["Paper Exams"],"description":"Reads the copy configuration of a paper exam, the state of its copy generation, and\nthe links to the printable files that already exist.\n\nOnly a paper exam has this sub-resource: on any other exam this endpoint answers 404.\n","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/paper_detail"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"not_found":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}}}}},"/exams/{exam_id}/paper/all_copies":{"parameters":[{"name":"exam_id","in":"path","example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","description":"The id in Evalmee of the paper exam","required":true,"schema":{"type":"string"}}],"get":{"summary":"Download the all copies of a paper exam","tags":["Paper Exams"],"description":"Redirects to the file in storage. The target URL is signed and expires shortly, so\nfollow the redirect at download time rather than storing what it points at — this\nendpoint's own URL is the stable one.\n\nThe link is present in the `paper` resource only once the file exists. Called before\nthen, this endpoint answers 404 with the code `file_not_generated`, which is distinct\nfrom the `not_found` of an unknown exam.\n","responses":{"302":{"description":"Found","headers":{"Location":{"schema":{"type":"string","format":"uri"},"description":"A temporary, signed URL to the file. It expires; do not store it."}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"file_not_generated":{"value":{"error":"file_not_generated","status_code":404,"messages":["The all_copies file has not been generated yet"]}},"unknown_exam":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}}}}},"/exams/{exam_id}/paper/answer_sheets":{"parameters":[{"name":"exam_id","in":"path","example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","description":"The id in Evalmee of the paper exam","required":true,"schema":{"type":"string"}}],"get":{"summary":"Download the answer sheets of a paper exam","tags":["Paper Exams"],"description":"Redirects to the file in storage. The target URL is signed and expires shortly, so\nfollow the redirect at download time rather than storing what it points at — this\nendpoint's own URL is the stable one.\n\nThe link is present in the `paper` resource only once the file exists. Called before\nthen, this endpoint answers 404 with the code `file_not_generated`, which is distinct\nfrom the `not_found` of an unknown exam.\n","responses":{"302":{"description":"Found","headers":{"Location":{"schema":{"type":"string","format":"uri"},"description":"A temporary, signed URL to the file. It expires; do not store it."}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"file_not_generated":{"value":{"error":"file_not_generated","status_code":404,"messages":["The answer_sheets file has not been generated yet"]}},"unknown_exam":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}}}}},"/exams/{exam_id}/paper/individual_copies":{"parameters":[{"name":"exam_id","in":"path","example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","description":"The id in Evalmee of the paper exam","required":true,"schema":{"type":"string"}}],"get":{"summary":"Download the individual copies of a paper exam","tags":["Paper Exams"],"description":"Redirects to the file in storage. The target URL is signed and expires shortly, so\nfollow the redirect at download time rather than storing what it points at — this\nendpoint's own URL is the stable one.\n\nThe link is present in the `paper` resource only once the file exists. Called before\nthen, this endpoint answers 404 with the code `file_not_generated`, which is distinct\nfrom the `not_found` of an unknown exam.\n","responses":{"302":{"description":"Found","headers":{"Location":{"schema":{"type":"string","format":"uri"},"description":"A temporary, signed URL to the file. It expires; do not store it."}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"file_not_generated":{"value":{"error":"file_not_generated","status_code":404,"messages":["The individual_copies file has not been generated yet"]}},"unknown_exam":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}}}}},"/exams/{exam_id}/paper/question_sheets":{"parameters":[{"name":"exam_id","in":"path","example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","description":"The id in Evalmee of the paper exam","required":true,"schema":{"type":"string"}}],"get":{"summary":"Download the question sheets of a paper exam","tags":["Paper Exams"],"description":"Redirects to the file in storage. The target URL is signed and expires shortly, so\nfollow the redirect at download time rather than storing what it points at — this\nendpoint's own URL is the stable one.\n\nThe link is present in the `paper` resource only once the file exists. Called before\nthen, this endpoint answers 404 with the code `file_not_generated`, which is distinct\nfrom the `not_found` of an unknown exam.\n","responses":{"302":{"description":"Found","headers":{"Location":{"schema":{"type":"string","format":"uri"},"description":"A temporary, signed URL to the file. It expires; do not store it."}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"examples":{"file_not_generated":{"value":{"error":"file_not_generated","status_code":404,"messages":["The question_sheets file has not been generated yet"]}},"unknown_exam":{"value":{"error":"not_found","status_code":404}}},"schema":{"$ref":"#/components/schemas/error"}}}}}}},"/exams/{exam_id}/subject/import":{"parameters":[{"name":"exam_id","in":"path","example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6","description":"The id in Evalmee of the exam to import the subject to","required":true,"schema":{"type":"string"}}],"post":{"summary":"Import an exam subject","tags":["Exams"],"parameters":[],"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/exam"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"examples":{"invalid_schema":{"value":{"error":"invalid_schema","status_code":422,"messages":["import_format must be one of: evalmee, amc_text"]}},"subject_not_editable_anymore":{"value":{"error":"subject_not_editable_anymore","status_code":422,"messages":[]}}}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"import_format":{"description":"The format of the subject to import","example":"evalmee","type":"string","minLength":1,"enum":["evalmee","amc_text"]},"content":{"description":"The content of the subject to import in the format of the import_format","example":"# Title\n1. Question\n- Choice1\n+ Choice2","type":["null","string"]}},"required":["import_format"]},"examples":{"Format Evalmee":{"summary":"Import an exam subject from Evalmee","value":{"import_format":"evalmee","content":"#Exam title\n1.Question\n-Choice 1\n+Choice 2"}},"Format AMC text":{"summary":"Import an exam subject from AMC text","value":{"import_format":"amc_text","content":"Title: Exam title\n** Question 1\n-Choice 1\n+Choice 2"}}}}}}}},"/time_accommodations":{"get":{"summary":"List the time accommodations","tags":["Time Accommodations"],"description":"List the time accommodations your organization has defined.\n\nRead-only: the catalog is curated in the Evalmee application. Assigning one\nto a user is done on that user, with `time_accommodation_id`.\n","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/time_accommodation"}},"meta":{"$ref":"#/components/schemas/pagination_meta"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}}}}},"/time_accommodations/{id}":{"parameters":[{"name":"id","in":"path","required":true,"example":"b2c3d4e5-f6a7-4b9c-8d1e-f2a3b4c5d6e7","description":"The id of the time accommodation in Evalmee","schema":{"type":"string"}}],"get":{"summary":"Retrieve a time accommodation","tags":["Time Accommodations"],"description":"Retrieve one time accommodation, with the exact fraction of extra time it grants.\n","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/time_accommodation"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}}}}},"/users/{user_id}/examinees":{"parameters":[{"name":"user_id","in":"path","required":true,"example":"c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7","description":"The id of the user in Evalmee","schema":{"type":"string"}}],"get":{"summary":"List a user's examinees","tags":["Users"],"description":"List the examinees of one user: one per exam they are enrolled in, across\nall your exams. Same resource as `/exams/{exam_id}/examinees`, taken from\nthe user's side.\n\nRead-only: enrolling someone is done on the exam, with\n`POST /exams/{exam_id}/examinees`.\n","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/examinee"}},"meta":{"$ref":"#/components/schemas/pagination_meta"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}}}}},"/users":{"get":{"summary":"List the users in your organization","tags":["Users"],"description":"List everyone your organization knows — examinees and examiners alike.\n\nThe id identifies a membership, not a human being: the same person belonging to\ntwo organizations has a different id in each.\n","parameters":[{"name":"filter[email]","in":"query","required":false,"example":"john.doe@example.com","description":"Only return the user with this email","schema":{"type":"string"}},{"name":"filter[external_id]","in":"query","required":false,"example":"STU-2024-0142,STU-2024-0999","description":"Only return users carrying one of these IDs in your own system. Separate IDs with commas.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/user"}},"meta":{"$ref":"#/components/schemas/pagination_meta"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}}}},"post":{"summary":"Add a user to your organization","tags":["Users"],"description":"Add a user to your organization's directory.\n\nThe email identifies them across the whole platform. Sending one that is already\na member updates that user instead of creating a second entry, and answers\n`200` rather than `201`.\n\nUsers are always added as examinees through the API. Creating an examiner is done via the Evalmee web application.\n","parameters":[],"responses":{"200":{"description":"The user was already a member, and was updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/user"}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/user"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"first_name":{"description":"The first name of the user","example":"John","type":"string","minLength":1},"last_name":{"description":"The last name of the user","example":"Doe","type":"string","minLength":1},"time_accommodation_id":{"description":"The id of the time accommodation granted to this user for every exam. Send null to remove it, omit the key to leave it unchanged. Not to be confused with the exam's own `time_accommodation`, a boolean saying whether that exam honors accommodations at all.","example":"b2c3d4e5-f6a7-4b9c-8d1e-f2a3b4c5d6e7","type":["null","string"],"pattern":"^[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}$"},"external_id":{"description":"The id of this person in your own system. Specific to your organization, unlike the email above. Send null to remove it, omit the key to leave it unchanged.","example":"STU-2024-0142","type":["null","string"]},"email":{"description":"The email of the user. Identifies them across the whole platform, and cannot be changed afterwards.","example":"john.doe@example.com","type":"string","minLength":1,"format":"email"}},"required":["email"]},"examples":{"Basic":{"summary":"Add an examinee","value":{"email":"jane.doe@example.com","first_name":"Jane","last_name":"Doe"}},"With your own id":{"summary":"Add an examinee carrying your system's id","value":{"email":"jane.doe@example.com","first_name":"Jane","last_name":"Doe","external_id":"STU-2024-0143"}},"With a time accommodation":{"summary":"Add an examinee granted extra time","value":{"email":"jane.doe@example.com","first_name":"Jane","last_name":"Doe","time_accommodation_id":"b2c3d4e5-f6a7-4b9c-8d1e-f2a3b4c5d6e7"}}}}}}}},"/users/{id}":{"parameters":[{"name":"id","in":"path","required":true,"example":"c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7","description":"The id of the user in Evalmee","schema":{"type":"string"}}],"get":{"summary":"Retrieve a user","tags":["Users"],"description":"Retrieve one user, with the time accommodation they are granted, if any.\n","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/user"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}}}},"patch":{"summary":"Update a user","tags":["Users"],"description":"Update a user's name, or the time accommodation they are granted.\n\nThe email cannot be changed: it identifies them across the whole platform,\nand a rename is reversible where an address change is not.\n\nNames live on the person, not on the membership, so renaming them here also\nrenames them for every other organization they belong to. The time accommodation\nis yours alone.\n\nSend `time_accommodation_id: null` to remove the accommodation; omit the key to\nleave it as it is. `external_id` follows the same rule.\n","parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/user"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"examples":{"unauthorized":{"value":{"error":"unauthorized","status_code":401}}},"schema":{"$ref":"#/components/schemas/error"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"first_name":{"description":"The first name of the user","example":"John","type":"string","minLength":1},"last_name":{"description":"The last name of the user","example":"Doe","type":"string","minLength":1},"time_accommodation_id":{"description":"The id of the time accommodation granted to this user for every exam. Send null to remove it, omit the key to leave it unchanged. Not to be confused with the exam's own `time_accommodation`, a boolean saying whether that exam honors accommodations at all.","example":"b2c3d4e5-f6a7-4b9c-8d1e-f2a3b4c5d6e7","type":["null","string"],"pattern":"^[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}$"},"external_id":{"description":"The id of this person in your own system. Specific to your organization, unlike the email above. Send null to remove it, omit the key to leave it unchanged.","example":"STU-2024-0142","type":["null","string"]}}},"examples":{"Rename":{"summary":"Correct a name","value":{"first_name":"Jonathan"}},"Grant extra time":{"summary":"Assign a time accommodation","value":{"time_accommodation_id":"b2c3d4e5-f6a7-4b9c-8d1e-f2a3b4c5d6e7"}},"Set your own id":{"summary":"Attach the id this person carries in your system","value":{"external_id":"STU-2024-0143"}},"Remove extra time":{"summary":"Take the time accommodation back","value":{"time_accommodation_id":null}}}}}}}}},"webhooks":{"ping":{"post":{"tags":["Receiving webhooks"],"summary":"Ping","operationId":"webhookPing","security":[],"description":"Sent on demand, to prove your endpoint is reachable and that your\nsignature verification works. Carries no business data, and is\ndelivered through the exact same pipeline as any other event.\n","parameters":[{"name":"webhook-id","in":"header","required":true,"description":"The event id, identical across retries of the same event","schema":{"type":"string","format":"uuid"},"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"},{"name":"webhook-timestamp","in":"header","required":true,"description":"Unix seconds at which the attempt was signed","schema":{"type":"string"},"example":"1788166500"},{"name":"webhook-signature","in":"header","required":true,"description":"Space-separated list of `v1,<base64 HMAC-SHA256>` signatures","schema":{"type":"string"},"example":"v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE="},{"name":"X-Evalmee-Event","in":"header","required":true,"description":"The event type. Informational — never authenticate on it.","schema":{"type":"string"},"example":"ping"},{"name":"X-Evalmee-Delivery","in":"header","required":true,"description":"The id of this individual attempt. Differs between retries of one event.","schema":{"type":"string","format":"uuid"},"example":"b2c3d4e5-f6a7-4b8c-9d0e-f1a2b3c4d5e6"},{"name":"X-Evalmee-Organization","in":"header","required":true,"description":"The id of the organization the event belongs to","schema":{"type":"string","format":"uuid"},"example":"c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/webhook_ping_event"},"examples":{"ping":{"value":{"id":"00000001-0000-4000-8000-000000000000","type":"ping","timestamp":"2026-08-31T11:15:00+02:00","organization_id":"00000002-0000-4000-8000-000000000000","data":{}}}}}}},"responses":{"2XX":{"description":"Acknowledged. Any 2xx counts, and the body is never read."},"4XX":{"description":"Refused. Final, except for `429` which is retried.\n"},"5XX":{"description":"Failed. Retried up to 5 times."}}}},"exam_attempt.started":{"post":{"tags":["Exam attempt events"],"summary":"Exam attempt started","operationId":"webhookExamAttemptStarted","security":[],"description":"Sent when an examinee starts an exam. `data` is the exam attempt,\nin the same shape `/exams/{exam_id}/exam_attempts` returns.\n\nReopening a finished attempt starts it again and sends a second\nevent, with a different `id`. Previewing an exam does not send\none: only an examinee's attempt does.\n","parameters":[{"name":"webhook-id","in":"header","required":true,"description":"The event id, identical across retries of the same event","schema":{"type":"string","format":"uuid"},"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"},{"name":"webhook-timestamp","in":"header","required":true,"description":"Unix seconds at which the attempt was signed","schema":{"type":"string"},"example":"1788166500"},{"name":"webhook-signature","in":"header","required":true,"description":"Space-separated list of `v1,<base64 HMAC-SHA256>` signatures","schema":{"type":"string"},"example":"v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE="},{"name":"X-Evalmee-Event","in":"header","required":true,"description":"The event type. Informational — never authenticate on it.","schema":{"type":"string"},"example":"exam_attempt.started"},{"name":"X-Evalmee-Delivery","in":"header","required":true,"description":"The id of this individual attempt. Differs between retries of one event.","schema":{"type":"string","format":"uuid"},"example":"b2c3d4e5-f6a7-4b8c-9d0e-f1a2b3c4d5e6"},{"name":"X-Evalmee-Organization","in":"header","required":true,"description":"The id of the organization the event belongs to","schema":{"type":"string","format":"uuid"},"example":"c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/webhook_exam_attempt_started_event"},"examples":{"exam_attempt.started":{"value":{"id":"00000001-0000-4000-8000-000000000000","type":"exam_attempt.started","timestamp":"2026-08-31T11:15:00+02:00","organization_id":"00000002-0000-4000-8000-000000000000","data":{"id":"00000003-0000-4000-8000-000000000000","grade":0,"links":{"exam":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000","examinee":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/examinees/00000005-0000-4000-8000-000000000000","exam_session":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/exam_sessions/ID00000003"},"status":"answering","user_id":"00000006-0000-4000-8000-000000000000","examinee":{"id":"00000005-0000-4000-8000-000000000000","email":"alice.martin@example.com","links":{"exam":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000","self":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/examinees/00000005-0000-4000-8000-000000000000","user":"https://app.evalmee.com/api/public/v2/users/00000006-0000-4000-8000-000000000000","emails":"https://app.evalmee.com/api/public/v2/emails?exam_id=00000004-0000-4000-8000-000000000000&examinee_id=00000005-0000-4000-8000-000000000000"},"groups":[],"last_name":"Martin","first_name":"Alice","external_id":"STU-2024-0142","uids_per_identity_providers":[{"uid":"alice.martin@example.com","provider":"evalmee"}]},"started_at":"2026-08-31T11:15:00+02:00","finished_at":null,"grade_scale":20,"web_app_url":"https://app.evalmee.com/front/1001/exam_attempt/1002","exam_session":{"id":"ID00000003","name":"Morning session","links":{"exam":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000","self":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/exam_sessions/ID00000003","emails":"https://app.evalmee.com/api/public/v2/emails?exam_id=00000004-0000-4000-8000-000000000000&exam_session_id=ID00000003"},"groups":[],"start_at":"2026-08-30T11:15:00+02:00","scheduled_end_at":"2026-09-01T11:15:00+02:00","allow_self_enrollment":"none","web_app_examinee_enrollment_url":"https://app.evalmee.com/join/ID00000003-algorithms-final-exam-morning-session"},"grade_locked":false,"grades_by_criteria":[],"onboarding_seen_at":null}}}}}}},"responses":{"2XX":{"description":"Acknowledged. Any 2xx counts, and the body is never read."},"4XX":{"description":"Refused. Final, except for `429` which is retried.\n"},"5XX":{"description":"Failed. Retried up to 5 times."}}}},"exam_attempt.finished":{"post":{"tags":["Exam attempt events"],"summary":"Exam attempt finished","operationId":"webhookExamAttemptFinished","security":[],"description":"Sent when an examinee's attempt ends, whether the examinee\nsubmitted it, its time ran out, or an examiner closed it. `data`\nis the exam attempt, in the same shape\n`/exams/{exam_id}/exam_attempts` returns.\n\nThe grade may still be computing when the event is sent: read it\nfrom the API when it matters. A finished attempt that is reopened\nsends `exam_attempt.started` again, then a second\n`exam_attempt.finished` when it ends again. Paper exams do not\nsend it, and previewing an exam does not send one: only an\nexaminee's attempt does.\n","parameters":[{"name":"webhook-id","in":"header","required":true,"description":"The event id, identical across retries of the same event","schema":{"type":"string","format":"uuid"},"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"},{"name":"webhook-timestamp","in":"header","required":true,"description":"Unix seconds at which the attempt was signed","schema":{"type":"string"},"example":"1788166500"},{"name":"webhook-signature","in":"header","required":true,"description":"Space-separated list of `v1,<base64 HMAC-SHA256>` signatures","schema":{"type":"string"},"example":"v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE="},{"name":"X-Evalmee-Event","in":"header","required":true,"description":"The event type. Informational — never authenticate on it.","schema":{"type":"string"},"example":"exam_attempt.finished"},{"name":"X-Evalmee-Delivery","in":"header","required":true,"description":"The id of this individual attempt. Differs between retries of one event.","schema":{"type":"string","format":"uuid"},"example":"b2c3d4e5-f6a7-4b8c-9d0e-f1a2b3c4d5e6"},{"name":"X-Evalmee-Organization","in":"header","required":true,"description":"The id of the organization the event belongs to","schema":{"type":"string","format":"uuid"},"example":"c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/webhook_exam_attempt_finished_event"},"examples":{"exam_attempt.finished":{"value":{"id":"00000001-0000-4000-8000-000000000000","type":"exam_attempt.finished","timestamp":"2026-08-31T11:15:00+02:00","organization_id":"00000002-0000-4000-8000-000000000000","data":{"id":"00000003-0000-4000-8000-000000000000","grade":0,"links":{"exam":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000","examinee":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/examinees/00000005-0000-4000-8000-000000000000","exam_session":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/exam_sessions/ID00000003"},"status":"graded","user_id":"00000006-0000-4000-8000-000000000000","examinee":{"id":"00000005-0000-4000-8000-000000000000","email":"alice.martin@example.com","links":{"exam":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000","self":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/examinees/00000005-0000-4000-8000-000000000000","user":"https://app.evalmee.com/api/public/v2/users/00000006-0000-4000-8000-000000000000","emails":"https://app.evalmee.com/api/public/v2/emails?exam_id=00000004-0000-4000-8000-000000000000&examinee_id=00000005-0000-4000-8000-000000000000"},"groups":[],"last_name":"Martin","first_name":"Alice","external_id":"STU-2024-0142","uids_per_identity_providers":[{"uid":"alice.martin@example.com","provider":"evalmee"}]},"started_at":"2026-08-31T11:15:00+02:00","finished_at":"2026-08-31T11:15:00+02:00","grade_scale":20,"web_app_url":"https://app.evalmee.com/front/1001/exam_attempt/1002","exam_session":{"id":"ID00000003","name":"Morning session","links":{"exam":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000","self":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/exam_sessions/ID00000003","emails":"https://app.evalmee.com/api/public/v2/emails?exam_id=00000004-0000-4000-8000-000000000000&exam_session_id=ID00000003"},"groups":[],"start_at":"2026-08-30T11:15:00+02:00","scheduled_end_at":"2026-09-01T11:15:00+02:00","allow_self_enrollment":"none","web_app_examinee_enrollment_url":"https://app.evalmee.com/join/ID00000003-algorithms-final-exam-morning-session"},"grade_locked":false,"grades_by_criteria":[],"onboarding_seen_at":null}}}}}}},"responses":{"2XX":{"description":"Acknowledged. Any 2xx counts, and the body is never read."},"4XX":{"description":"Refused. Final, except for `429` which is retried.\n"},"5XX":{"description":"Failed. Retried up to 5 times."}}}},"exam_attempt.onboarding_seen":{"post":{"tags":["Exam attempt events"],"summary":"Exam attempt onboarding seen","operationId":"webhookExamAttemptOnboardingSeen","security":[],"description":"Sent the first time an examinee opens an exam's onboarding page.\n`data` is the exam attempt, in the same shape\n`/exams/{exam_id}/exam_attempts` returns.\n\nFires once per attempt: a later visit to the same page does not\nsend a second event. Previewing an exam does not send one: only\nan examinee's attempt does.\n","parameters":[{"name":"webhook-id","in":"header","required":true,"description":"The event id, identical across retries of the same event","schema":{"type":"string","format":"uuid"},"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"},{"name":"webhook-timestamp","in":"header","required":true,"description":"Unix seconds at which the attempt was signed","schema":{"type":"string"},"example":"1788166500"},{"name":"webhook-signature","in":"header","required":true,"description":"Space-separated list of `v1,<base64 HMAC-SHA256>` signatures","schema":{"type":"string"},"example":"v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE="},{"name":"X-Evalmee-Event","in":"header","required":true,"description":"The event type. Informational — never authenticate on it.","schema":{"type":"string"},"example":"exam_attempt.onboarding_seen"},{"name":"X-Evalmee-Delivery","in":"header","required":true,"description":"The id of this individual attempt. Differs between retries of one event.","schema":{"type":"string","format":"uuid"},"example":"b2c3d4e5-f6a7-4b8c-9d0e-f1a2b3c4d5e6"},{"name":"X-Evalmee-Organization","in":"header","required":true,"description":"The id of the organization the event belongs to","schema":{"type":"string","format":"uuid"},"example":"c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/webhook_exam_attempt_onboarding_seen_event"},"examples":{"exam_attempt.onboarding_seen":{"value":{"id":"00000001-0000-4000-8000-000000000000","type":"exam_attempt.onboarding_seen","timestamp":"2026-08-31T11:15:00+02:00","organization_id":"00000002-0000-4000-8000-000000000000","data":{"id":"00000003-0000-4000-8000-000000000000","grade":0,"links":{"exam":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000","examinee":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/examinees/00000005-0000-4000-8000-000000000000","exam_session":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/exam_sessions/ID00000003"},"status":"not_answered","user_id":"00000006-0000-4000-8000-000000000000","examinee":{"id":"00000005-0000-4000-8000-000000000000","email":"alice.martin@example.com","links":{"exam":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000","self":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/examinees/00000005-0000-4000-8000-000000000000","user":"https://app.evalmee.com/api/public/v2/users/00000006-0000-4000-8000-000000000000","emails":"https://app.evalmee.com/api/public/v2/emails?exam_id=00000004-0000-4000-8000-000000000000&examinee_id=00000005-0000-4000-8000-000000000000"},"groups":[],"last_name":"Martin","first_name":"Alice","external_id":"STU-2024-0142","uids_per_identity_providers":[{"uid":"alice.martin@example.com","provider":"evalmee"}]},"started_at":null,"finished_at":null,"grade_scale":20,"web_app_url":"https://app.evalmee.com/front/1001/exam_attempt/1002","exam_session":{"id":"ID00000003","name":"Morning session","links":{"exam":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000","self":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/exam_sessions/ID00000003","emails":"https://app.evalmee.com/api/public/v2/emails?exam_id=00000004-0000-4000-8000-000000000000&exam_session_id=ID00000003"},"groups":[],"start_at":"2026-08-30T11:15:00+02:00","scheduled_end_at":"2026-09-01T11:15:00+02:00","allow_self_enrollment":"none","web_app_examinee_enrollment_url":"https://app.evalmee.com/join/ID00000003-algorithms-final-exam-morning-session"},"grade_locked":false,"grades_by_criteria":[],"onboarding_seen_at":"2026-08-31T11:15:00+02:00"}}}}}}},"responses":{"2XX":{"description":"Acknowledged. Any 2xx counts, and the body is never read."},"4XX":{"description":"Refused. Final, except for `429` which is retried.\n"},"5XX":{"description":"Failed. Retried up to 5 times."}}}},"email.sent":{"post":{"tags":["Email events"],"summary":"Email sent","operationId":"webhookEmailSent","security":[],"description":"Sent when the provider accepted the convocation and handed it to the\ntransport. `data` is the email, in the same shape `/emails/{id}`\nreturns.\n\nIt does not mean the convocation reached the mailbox: `email.delivered`\nreports that. Sent once per convocation.\n","parameters":[{"name":"webhook-id","in":"header","required":true,"description":"The event id, identical across retries of the same event","schema":{"type":"string","format":"uuid"},"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"},{"name":"webhook-timestamp","in":"header","required":true,"description":"Unix seconds at which the attempt was signed","schema":{"type":"string"},"example":"1788166500"},{"name":"webhook-signature","in":"header","required":true,"description":"Space-separated list of `v1,<base64 HMAC-SHA256>` signatures","schema":{"type":"string"},"example":"v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE="},{"name":"X-Evalmee-Event","in":"header","required":true,"description":"The event type. Informational — never authenticate on it.","schema":{"type":"string"},"example":"email.sent"},{"name":"X-Evalmee-Delivery","in":"header","required":true,"description":"The id of this individual attempt. Differs between retries of one event.","schema":{"type":"string","format":"uuid"},"example":"b2c3d4e5-f6a7-4b8c-9d0e-f1a2b3c4d5e6"},{"name":"X-Evalmee-Organization","in":"header","required":true,"description":"The id of the organization the event belongs to","schema":{"type":"string","format":"uuid"},"example":"c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/webhook_email_sent_event"},"examples":{"email.sent":{"value":{"id":"00000001-0000-4000-8000-000000000000","type":"email.sent","timestamp":"2026-08-31T11:15:00+02:00","organization_id":"00000002-0000-4000-8000-000000000000","data":{"id":"00000003-0000-4000-8000-000000000000","type":"invitation","links":{"exam":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000","self":"https://app.evalmee.com/api/public/v2/emails/00000003-0000-4000-8000-000000000000","examinee":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/examinees/00000005-0000-4000-8000-000000000000","exam_session":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/exam_sessions/MorningS01"},"status":"processed","recipient":"alice.martin@example.com","created_at":"2026-08-31T11:15:00+02:00","status_updated_at":"2026-08-31T11:15:00+02:00"}}}}}}},"responses":{"2XX":{"description":"Acknowledged. Any 2xx counts, and the body is never read."},"4XX":{"description":"Refused. Final, except for `429` which is retried.\n"},"5XX":{"description":"Failed. Retried up to 5 times."}}}},"email.delivered":{"post":{"tags":["Email events"],"summary":"Email delivered","operationId":"webhookEmailDelivered","security":[],"description":"Sent when the recipient's mail server accepted the convocation. `data`\nis the email, in the same shape `/emails/{id}` returns.\n\nDelivery is not proof the convocation was read: `email.opened` reports\nthat. `status_updated_at` carries the provider's own timestamp for the\ndelivery, distinct from the envelope's `timestamp`.\n","parameters":[{"name":"webhook-id","in":"header","required":true,"description":"The event id, identical across retries of the same event","schema":{"type":"string","format":"uuid"},"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"},{"name":"webhook-timestamp","in":"header","required":true,"description":"Unix seconds at which the attempt was signed","schema":{"type":"string"},"example":"1788166500"},{"name":"webhook-signature","in":"header","required":true,"description":"Space-separated list of `v1,<base64 HMAC-SHA256>` signatures","schema":{"type":"string"},"example":"v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE="},{"name":"X-Evalmee-Event","in":"header","required":true,"description":"The event type. Informational — never authenticate on it.","schema":{"type":"string"},"example":"email.delivered"},{"name":"X-Evalmee-Delivery","in":"header","required":true,"description":"The id of this individual attempt. Differs between retries of one event.","schema":{"type":"string","format":"uuid"},"example":"b2c3d4e5-f6a7-4b8c-9d0e-f1a2b3c4d5e6"},{"name":"X-Evalmee-Organization","in":"header","required":true,"description":"The id of the organization the event belongs to","schema":{"type":"string","format":"uuid"},"example":"c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/webhook_email_delivered_event"},"examples":{"email.delivered":{"value":{"id":"00000001-0000-4000-8000-000000000000","type":"email.delivered","timestamp":"2026-08-31T11:15:00+02:00","organization_id":"00000002-0000-4000-8000-000000000000","data":{"id":"00000003-0000-4000-8000-000000000000","type":"invitation","links":{"exam":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000","self":"https://app.evalmee.com/api/public/v2/emails/00000003-0000-4000-8000-000000000000","examinee":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/examinees/00000005-0000-4000-8000-000000000000","exam_session":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/exam_sessions/MorningS01"},"status":"delivered","recipient":"alice.martin@example.com","created_at":"2026-08-31T11:15:00+02:00","status_updated_at":"2026-08-31T11:15:00+02:00"}}}}}}},"responses":{"2XX":{"description":"Acknowledged. Any 2xx counts, and the body is never read."},"4XX":{"description":"Refused. Final, except for `429` which is retried.\n"},"5XX":{"description":"Failed. Retried up to 5 times."}}}},"email.delivery_delayed":{"post":{"tags":["Email events"],"summary":"Email delivery delayed","operationId":"webhookEmailDeliveryDelayed","security":[],"description":"Sent when the recipient's mail server temporarily refused the\nconvocation and the provider will retry. `data` is the email, in the\nsame shape `/emails/{id}` returns.\n\nSent once, on the first deferral, however many times the provider\nretries afterwards. Usually followed by `email.delivered` or\n`email.bounced`.\n","parameters":[{"name":"webhook-id","in":"header","required":true,"description":"The event id, identical across retries of the same event","schema":{"type":"string","format":"uuid"},"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"},{"name":"webhook-timestamp","in":"header","required":true,"description":"Unix seconds at which the attempt was signed","schema":{"type":"string"},"example":"1788166500"},{"name":"webhook-signature","in":"header","required":true,"description":"Space-separated list of `v1,<base64 HMAC-SHA256>` signatures","schema":{"type":"string"},"example":"v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE="},{"name":"X-Evalmee-Event","in":"header","required":true,"description":"The event type. Informational — never authenticate on it.","schema":{"type":"string"},"example":"email.delivery_delayed"},{"name":"X-Evalmee-Delivery","in":"header","required":true,"description":"The id of this individual attempt. Differs between retries of one event.","schema":{"type":"string","format":"uuid"},"example":"b2c3d4e5-f6a7-4b8c-9d0e-f1a2b3c4d5e6"},{"name":"X-Evalmee-Organization","in":"header","required":true,"description":"The id of the organization the event belongs to","schema":{"type":"string","format":"uuid"},"example":"c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/webhook_email_delivery_delayed_event"},"examples":{"email.delivery_delayed":{"value":{"id":"00000001-0000-4000-8000-000000000000","type":"email.delivery_delayed","timestamp":"2026-08-31T11:15:00+02:00","organization_id":"00000002-0000-4000-8000-000000000000","data":{"id":"00000003-0000-4000-8000-000000000000","type":"invitation","links":{"exam":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000","self":"https://app.evalmee.com/api/public/v2/emails/00000003-0000-4000-8000-000000000000","examinee":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/examinees/00000005-0000-4000-8000-000000000000","exam_session":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/exam_sessions/MorningS01"},"status":"deferred","recipient":"alice.martin@example.com","created_at":"2026-08-31T11:15:00+02:00","status_updated_at":"2026-08-31T11:15:00+02:00"}}}}}}},"responses":{"2XX":{"description":"Acknowledged. Any 2xx counts, and the body is never read."},"4XX":{"description":"Refused. Final, except for `429` which is retried.\n"},"5XX":{"description":"Failed. Retried up to 5 times."}}}},"email.bounced":{"post":{"tags":["Email events"],"summary":"Email bounced","operationId":"webhookEmailBounced","security":[],"description":"Sent when the recipient's mail server permanently rejected the\nconvocation — an unknown address, a full mailbox, a blocked sender.\n`data` is the email, in the same shape `/emails/{id}` returns.\n\nThis is the event to act on: the examinee will not receive the\nconvocation. Fix the address, then invite them again.\n","parameters":[{"name":"webhook-id","in":"header","required":true,"description":"The event id, identical across retries of the same event","schema":{"type":"string","format":"uuid"},"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"},{"name":"webhook-timestamp","in":"header","required":true,"description":"Unix seconds at which the attempt was signed","schema":{"type":"string"},"example":"1788166500"},{"name":"webhook-signature","in":"header","required":true,"description":"Space-separated list of `v1,<base64 HMAC-SHA256>` signatures","schema":{"type":"string"},"example":"v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE="},{"name":"X-Evalmee-Event","in":"header","required":true,"description":"The event type. Informational — never authenticate on it.","schema":{"type":"string"},"example":"email.bounced"},{"name":"X-Evalmee-Delivery","in":"header","required":true,"description":"The id of this individual attempt. Differs between retries of one event.","schema":{"type":"string","format":"uuid"},"example":"b2c3d4e5-f6a7-4b8c-9d0e-f1a2b3c4d5e6"},{"name":"X-Evalmee-Organization","in":"header","required":true,"description":"The id of the organization the event belongs to","schema":{"type":"string","format":"uuid"},"example":"c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/webhook_email_bounced_event"},"examples":{"email.bounced":{"value":{"id":"00000001-0000-4000-8000-000000000000","type":"email.bounced","timestamp":"2026-08-31T11:15:00+02:00","organization_id":"00000002-0000-4000-8000-000000000000","data":{"id":"00000003-0000-4000-8000-000000000000","type":"invitation","links":{"exam":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000","self":"https://app.evalmee.com/api/public/v2/emails/00000003-0000-4000-8000-000000000000","examinee":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/examinees/00000005-0000-4000-8000-000000000000","exam_session":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/exam_sessions/MorningS01"},"status":"bounce","recipient":"alice.martin@example.com","created_at":"2026-08-31T11:15:00+02:00","status_updated_at":"2026-08-31T11:15:00+02:00"}}}}}}},"responses":{"2XX":{"description":"Acknowledged. Any 2xx counts, and the body is never read."},"4XX":{"description":"Refused. Final, except for `429` which is retried.\n"},"5XX":{"description":"Failed. Retried up to 5 times."}}}},"email.failed":{"post":{"tags":["Email events"],"summary":"Email failed","operationId":"webhookEmailFailed","security":[],"description":"Sent when the convocation could not be sent at all — a suppressed\naddress, a rendering failure at the provider. `data` is the email, in\nthe same shape `/emails/{id}` returns.\n\nNothing ever left the provider, so the examinee received nothing. Same\nremediation as a bounce: fix the address, then invite them again.\n","parameters":[{"name":"webhook-id","in":"header","required":true,"description":"The event id, identical across retries of the same event","schema":{"type":"string","format":"uuid"},"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"},{"name":"webhook-timestamp","in":"header","required":true,"description":"Unix seconds at which the attempt was signed","schema":{"type":"string"},"example":"1788166500"},{"name":"webhook-signature","in":"header","required":true,"description":"Space-separated list of `v1,<base64 HMAC-SHA256>` signatures","schema":{"type":"string"},"example":"v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE="},{"name":"X-Evalmee-Event","in":"header","required":true,"description":"The event type. Informational — never authenticate on it.","schema":{"type":"string"},"example":"email.failed"},{"name":"X-Evalmee-Delivery","in":"header","required":true,"description":"The id of this individual attempt. Differs between retries of one event.","schema":{"type":"string","format":"uuid"},"example":"b2c3d4e5-f6a7-4b8c-9d0e-f1a2b3c4d5e6"},{"name":"X-Evalmee-Organization","in":"header","required":true,"description":"The id of the organization the event belongs to","schema":{"type":"string","format":"uuid"},"example":"c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/webhook_email_failed_event"},"examples":{"email.failed":{"value":{"id":"00000001-0000-4000-8000-000000000000","type":"email.failed","timestamp":"2026-08-31T11:15:00+02:00","organization_id":"00000002-0000-4000-8000-000000000000","data":{"id":"00000003-0000-4000-8000-000000000000","type":"invitation","links":{"exam":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000","self":"https://app.evalmee.com/api/public/v2/emails/00000003-0000-4000-8000-000000000000","examinee":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/examinees/00000005-0000-4000-8000-000000000000","exam_session":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/exam_sessions/MorningS01"},"status":"dropped","recipient":"alice.martin@example.com","created_at":"2026-08-31T11:15:00+02:00","status_updated_at":"2026-08-31T11:15:00+02:00"}}}}}}},"responses":{"2XX":{"description":"Acknowledged. Any 2xx counts, and the body is never read."},"4XX":{"description":"Refused. Final, except for `429` which is retried.\n"},"5XX":{"description":"Failed. Retried up to 5 times."}}}},"email.complained":{"post":{"tags":["Email events"],"summary":"Email reported as spam","operationId":"webhookEmailComplained","security":[],"description":"Sent when the recipient reported the convocation as spam to their mail\nprovider. `data` is the email, in the same shape `/emails/{id}`\nreturns.\n\n`status_updated_at` carries the provider's own timestamp for the\nreport, distinct from the envelope's `timestamp`.\n","parameters":[{"name":"webhook-id","in":"header","required":true,"description":"The event id, identical across retries of the same event","schema":{"type":"string","format":"uuid"},"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"},{"name":"webhook-timestamp","in":"header","required":true,"description":"Unix seconds at which the attempt was signed","schema":{"type":"string"},"example":"1788166500"},{"name":"webhook-signature","in":"header","required":true,"description":"Space-separated list of `v1,<base64 HMAC-SHA256>` signatures","schema":{"type":"string"},"example":"v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE="},{"name":"X-Evalmee-Event","in":"header","required":true,"description":"The event type. Informational — never authenticate on it.","schema":{"type":"string"},"example":"email.complained"},{"name":"X-Evalmee-Delivery","in":"header","required":true,"description":"The id of this individual attempt. Differs between retries of one event.","schema":{"type":"string","format":"uuid"},"example":"b2c3d4e5-f6a7-4b8c-9d0e-f1a2b3c4d5e6"},{"name":"X-Evalmee-Organization","in":"header","required":true,"description":"The id of the organization the event belongs to","schema":{"type":"string","format":"uuid"},"example":"c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/webhook_email_complained_event"},"examples":{"email.complained":{"value":{"id":"00000001-0000-4000-8000-000000000000","type":"email.complained","timestamp":"2026-08-31T11:15:00+02:00","organization_id":"00000002-0000-4000-8000-000000000000","data":{"id":"00000003-0000-4000-8000-000000000000","type":"invitation","links":{"exam":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000","self":"https://app.evalmee.com/api/public/v2/emails/00000003-0000-4000-8000-000000000000","examinee":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/examinees/00000005-0000-4000-8000-000000000000","exam_session":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/exam_sessions/MorningS01"},"status":"spamreport","recipient":"alice.martin@example.com","created_at":"2026-08-31T11:15:00+02:00","status_updated_at":"2026-08-31T11:15:00+02:00"}}}}}}},"responses":{"2XX":{"description":"Acknowledged. Any 2xx counts, and the body is never read."},"4XX":{"description":"Refused. Final, except for `429` which is retried.\n"},"5XX":{"description":"Failed. Retried up to 5 times."}}}},"email.opened":{"post":{"tags":["Email events"],"summary":"Email opened","operationId":"webhookEmailOpened","security":[],"description":"Sent the first time the recipient opened the convocation, as reported\nby its tracking pixel. `data` is the email, in the same shape\n`/emails/{id}` returns.\n\nAn absent event does not mean the convocation went unread: a mail\nclient that blocks images never loads the pixel. Sent once, on the\nfirst open.\n","parameters":[{"name":"webhook-id","in":"header","required":true,"description":"The event id, identical across retries of the same event","schema":{"type":"string","format":"uuid"},"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"},{"name":"webhook-timestamp","in":"header","required":true,"description":"Unix seconds at which the attempt was signed","schema":{"type":"string"},"example":"1788166500"},{"name":"webhook-signature","in":"header","required":true,"description":"Space-separated list of `v1,<base64 HMAC-SHA256>` signatures","schema":{"type":"string"},"example":"v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE="},{"name":"X-Evalmee-Event","in":"header","required":true,"description":"The event type. Informational — never authenticate on it.","schema":{"type":"string"},"example":"email.opened"},{"name":"X-Evalmee-Delivery","in":"header","required":true,"description":"The id of this individual attempt. Differs between retries of one event.","schema":{"type":"string","format":"uuid"},"example":"b2c3d4e5-f6a7-4b8c-9d0e-f1a2b3c4d5e6"},{"name":"X-Evalmee-Organization","in":"header","required":true,"description":"The id of the organization the event belongs to","schema":{"type":"string","format":"uuid"},"example":"c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/webhook_email_opened_event"},"examples":{"email.opened":{"value":{"id":"00000001-0000-4000-8000-000000000000","type":"email.opened","timestamp":"2026-08-31T11:15:00+02:00","organization_id":"00000002-0000-4000-8000-000000000000","data":{"id":"00000003-0000-4000-8000-000000000000","type":"invitation","links":{"exam":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000","self":"https://app.evalmee.com/api/public/v2/emails/00000003-0000-4000-8000-000000000000","examinee":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/examinees/00000005-0000-4000-8000-000000000000","exam_session":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/exam_sessions/MorningS01"},"status":"open","recipient":"alice.martin@example.com","created_at":"2026-08-31T11:15:00+02:00","status_updated_at":"2026-08-31T11:15:00+02:00"}}}}}}},"responses":{"2XX":{"description":"Acknowledged. Any 2xx counts, and the body is never read."},"4XX":{"description":"Refused. Final, except for `429` which is retried.\n"},"5XX":{"description":"Failed. Retried up to 5 times."}}}},"email.clicked":{"post":{"tags":["Email events"],"summary":"Email link clicked","operationId":"webhookEmailClicked","security":[],"description":"Sent the first time the recipient clicked the exam link in the\nconvocation. `data` is the email, in the same shape `/emails/{id}`\nreturns.\n\nSent once, on the first click, however many links the recipient\nfollows afterwards.\n","parameters":[{"name":"webhook-id","in":"header","required":true,"description":"The event id, identical across retries of the same event","schema":{"type":"string","format":"uuid"},"example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"},{"name":"webhook-timestamp","in":"header","required":true,"description":"Unix seconds at which the attempt was signed","schema":{"type":"string"},"example":"1788166500"},{"name":"webhook-signature","in":"header","required":true,"description":"Space-separated list of `v1,<base64 HMAC-SHA256>` signatures","schema":{"type":"string"},"example":"v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE="},{"name":"X-Evalmee-Event","in":"header","required":true,"description":"The event type. Informational — never authenticate on it.","schema":{"type":"string"},"example":"email.clicked"},{"name":"X-Evalmee-Delivery","in":"header","required":true,"description":"The id of this individual attempt. Differs between retries of one event.","schema":{"type":"string","format":"uuid"},"example":"b2c3d4e5-f6a7-4b8c-9d0e-f1a2b3c4d5e6"},{"name":"X-Evalmee-Organization","in":"header","required":true,"description":"The id of the organization the event belongs to","schema":{"type":"string","format":"uuid"},"example":"c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/webhook_email_clicked_event"},"examples":{"email.clicked":{"value":{"id":"00000001-0000-4000-8000-000000000000","type":"email.clicked","timestamp":"2026-08-31T11:15:00+02:00","organization_id":"00000002-0000-4000-8000-000000000000","data":{"id":"00000003-0000-4000-8000-000000000000","type":"invitation","links":{"exam":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000","self":"https://app.evalmee.com/api/public/v2/emails/00000003-0000-4000-8000-000000000000","examinee":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/examinees/00000005-0000-4000-8000-000000000000","exam_session":"https://app.evalmee.com/api/public/v2/exams/00000004-0000-4000-8000-000000000000/exam_sessions/MorningS01"},"status":"click","recipient":"alice.martin@example.com","created_at":"2026-08-31T11:15:00+02:00","status_updated_at":"2026-08-31T11:15:00+02:00"}}}}}}},"responses":{"2XX":{"description":"Acknowledged. Any 2xx counts, and the body is never read."},"4XX":{"description":"Refused. Final, except for `429` which is retried.\n"},"5XX":{"description":"Failed. Retried up to 5 times."}}}}},"servers":[{"url":"https://app.evalmee.com/api/public/v2","description":"Production API server"},{"url":"{scheme}://{host}/api/public/v2","variables":{"scheme":{"enum":["http","https"],"default":"https"},"host":{"default":"app.evalmee.com"}},"description":"Custom"}],"security":[{"oauth":[]}],"components":{"securitySchemes":{"oauth":{"type":"oauth2","description":"OAuth2 authentication with Client Credentials Flow","flows":{"clientCredentials":{"tokenUrl":"/api/public/auth/token","scopes":{},"x-scalar-credentials-location":"body"}}}},"schemas":{"assessment_criterion":{"type":"object","title":"Assessment Criterion","properties":{"id":{"type":"string","format":"uuid","description":"The id of the assessment criterion in Evalmee","example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"},"name":{"type":"string","description":"The name of the assessment criterion","example":"Data collection methodology"},"code":{"type":"string","description":"Short code for the criterion (max 10 chars, auto-generated if omitted)","example":"CE1.1"},"description":{"type":["string","null"],"description":"Description of the assessment criterion","example":"Use of appropriate tools and methods to gather information in a structured manner"},"links":{"$ref":"#/components/schemas/links"}},"required":["id","name","code","links"]},"criterion_grade":{"type":"object","title":"Criterion Grade","description":"Beta feature - format may change. A grade for a specific grading criterion.","x-beta":true,"properties":{"code":{"type":"string","description":"Unique identifier for the criterion","example":"CE1"},"name":{"type":"string","description":"Display name of the criterion","example":"Planning"},"description":{"type":["string","null"],"description":"Description of the criterion","example":"Develops comprehensive project plans with realistic timelines"},"grade":{"type":["number","null"],"description":"Points earned for this criterion.\n`null` when not yet graded **or** when the grade is locked — check\n`grade_locked` to tell the two apart.\n","example":8},"grade_locked":{"type":"boolean","description":"Whether this criterion's points are withheld pending a subscription.\nMirrors the parent exam result / exam attempt `grade_locked`: the\nper-criterion breakdown is masked together with the overall grade, since\nsumming it would rebuild the withheld value.\n","example":false},"grade_scale":{"type":"number","description":"Maximum points for this criterion","example":10},"question_ids":{"type":"array","items":{"type":"string"},"description":"Question UUIDs related to this criterion (single in global mode, multiple in criteria mode)","example":["d4e5f6a7-b8c9-4d0e-1f2a-3b4c5d6e7f8a"]}},"required":["code","name","grade_locked","grade_scale"]},"email":{"type":"object","title":"Email","properties":{"id":{"type":"string","description":"The id of the email in Evalmee","example":"a1b2c3d4-e5f6-7a8b-9c0d-e1f2a3b4c5d6"},"type":{"type":"string","description":"The kind of email that was sent\n- `invitation` = the convocation inviting an examinee to sit the exam\n","example":"invitation","enum":["invitation"]},"status":{"type":"string","description":"The delivery status reported by the email provider.\n`unknown` means no delivery event has been received yet.\n","example":"delivered","enum":["unknown","processed","dropped","deferred","bounce","delivered","open","click","spamreport","unsubscribe","group_unsubscribe","group_resubscribe"]},"recipient":{"type":"string","nullable":true,"description":"The address the email was sent to. `null` when the examinee it was sent\nto has since been deleted.\n","example":"john.doe@example.com"},"created_at":{"type":"string","format":"date-time","description":"When the email was sent (ISO 8601)","example":"2025-01-01T00:00:00Z"},"status_updated_at":{"type":"string","format":"date-time","nullable":true,"description":"When `status` was last updated (ISO 8601). `null` while `status` is\nstill `unknown`.\n","example":"2025-01-01T00:00:00Z"},"links":{"$ref":"#/components/schemas/links"}},"required":["id","type","status","created_at","links"]},"error":{"type":"object","title":"Error","properties":{"error":{"type":"string","description":"Internal error code","example":"unauthorized"},"status_code":{"type":"integer","description":"Associated HTTP status code","example":401},"messages":{"type":"array","description":"Optional messages detailing the error","items":{"type":"string"}},"meta":{"description":"Optional additional data, mainly used for debugging","additionalProperties":{"type":"object"}}},"required":["error","status_code"]},"exam":{"type":"object","title":"Exam","properties":{"id":{"type":"string","description":"The id of the exam in Evalmee","example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"},"name":{"type":"string","description":"The name of the exam","example":"My new exam"},"type":{"type":"string","description":"Which product the exam belongs to, and so how it is taken.\n- `online` = an **Evalmee** exam, answered in the web application\n- `paper` = a **Papeez** exam, printed, answered on paper, then scanned\n\nRead-only: this API creates online (Evalmee) exams, and a paper exam is\ncreated in the Papeez application. `paper` is present if and only if this\nis `paper`.\n","enum":["online","paper"],"example":"online"},"grade_scale":{"type":"number","description":"The maximum grade for the exam (default is 20.0)","example":20},"time_limit":{"type":["integer","null"],"description":"The answer time limit for the exam in seconds. Must be a multiple of 60.\nOnly applies to an online exam (`type: online`): a paper exam is timed in the\nroom rather than by the platform, so the value is never enforced on one.\n","example":3600},"time_limit_mode":{"type":"string","description":"How the time limit applies. `global` is one countdown over the whole exam.\n`per_question` splits the time limit evenly across the questions: each page of\nquestions closes when its share is over and cannot be revisited.\n\nOnly applies to an online exam (`type: online`); on a paper exam it keeps its\ndefault `global` and means nothing.\n","enum":["global","per_question"],"example":"global"},"time_accommodation":{"type":"boolean","description":"Whether time accommodation is enabled. Only applies to an online exam\n(`type: online`); on a paper exam it means nothing.\n","example":false},"random_sections":{"type":"boolean","description":"Whether to randomize the order of sections","example":false},"random_exercises":{"type":"boolean","description":"Whether to randomize the order of exercises (pages of questions)","example":false},"random_questions":{"type":"boolean","description":"Whether to randomize the order of questions in an exercise (or page of questions)","example":false},"random_choices":{"type":"boolean","description":"Whether to randomize the order of choices in questions","example":false},"grading_mode":{"type":"string","description":"The grading mode for the exam","enum":["global","criteria"],"example":"global"},"web_app_url":{"type":"string","description":"The URL to access the exam in the Evalmee or Papeez web application as an owner or editor.","example":"https://app.evalmee.com/evalmee_editor/a1b2c3d4-e5f6-7a8b-9c0d-e1f2g3h4i5j6/evalmee_editor"},"email_custom_instructions":{"type":"object","description":"The configuration of the emails sent to the examinees of this exam.\n`content` supports {{token}} placeholders (for example {{first_name}} or {{lien_de_connexion}}).\n","properties":{"content":{"type":"string","description":"The default body of the convocation email","example":"Hello {{first_name}}, your exam starts at {{debut}}. {{lien_de_connexion}}"},"subject":{"type":"string","description":"The default subject of the emails sent for this exam","example":"Exam | Mathematics"},"convocation_subject":{"type":"string","description":"The subject of the convocation email","example":"Exam | Mathematics"},"grade_subject":{"type":"string","description":"The subject of the email sent when grades are published","example":"Your grade | Mathematics"},"name_sender":{"type":"string","description":"The display name the emails are sent from","example":"A teacher via Evalmee"},"email_sender":{"type":"string","readOnly":true,"description":"The address the emails are sent from. Fixed per brand, cannot be set.","example":"contact@evalmee.com"},"name_reply_to":{"type":"string","description":"The display name replies are addressed to","example":"A teacher"},"email_reply_to":{"type":"string","description":"The address replies are addressed to","example":"teacher@example.com"}}},"exam_sessions":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/exam_session"}},"meta":{"$ref":"#/components/schemas/pagination_meta"}}},"assessment_criteria":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/assessment_criterion"}},"meta":{"$ref":"#/components/schemas/pagination_meta"}}},"paper":{"allOf":[{"$ref":"#/components/schemas/paper"}],"description":"The paper configuration. Present only when `type` is `paper` (a Papeez exam):\non an online (Evalmee) exam the key is absent from the response, never `null`.\n"},"links":{"$ref":"#/components/schemas/links"}},"required":["id","name","type"]},"exam_attempt":{"type":"object","title":"Exam Attempt","properties":{"id":{"type":"string","format":"uuid","description":"The id of the exam attempt","example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"},"user_id":{"type":["string","null"],"format":"uuid","description":"The id of the user who took this attempt — the same id `/users` and\n`examinee.links.user` address, so an attempt maps to a person without\nfetching the examinee first.\n","example":"c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7"},"status":{"type":"string","description":"The state of the exam attempt\n- `not_answered`: The examinee has not answered the exam in this session\n- `answering`: The examinee is answering the exam in this session\n- `answered_pending_grading`: The examinee has answered and answers are not yet graded\n- `graded_pending_approval`: The examinee has answered and answers are graded but waiting for approval [This state is not yet used]\n- `graded`: The examinee has answered and answers are graded\n","example":"answered_pending_grading","enum":["not_answered","answering","answered_pending_grading","graded_pending_approval","graded"]},"grade":{"type":["number","null"],"description":"The grade for the exam attempt.\n`null` when the attempt has no grade yet **or** when the grade is locked —\ncheck `grade_locked` to tell the two apart before writing to a gradebook.\n","example":95},"grade_locked":{"type":"boolean","description":"Whether the grade is withheld pending a subscription.\nWhen `true`, `grade` and every `grades_by_criteria[].grade` are `null`\nalthough the attempt has been graded: the grade exists but is not released\nyet. Do **not** record it as a zero and do **not** overwrite a previously\nsynced grade — skip the attempt and poll again once the school has\nsubscribed, at which point the same request returns the real values.\n","example":false},"grade_scale":{"type":"number","description":"The maximum grade for the exam","example":100},"started_at":{"type":["string","null"],"format":"date-time","description":"The start date and time of the exam attempt"},"finished_at":{"type":["string","null"],"format":"date-time","description":"The end date and time of the exam attempt"},"onboarding_seen_at":{"type":["string","null"],"format":"date-time","description":"The date and time the examinee first opened the exam's onboarding page.\n`null` until then, and set once — a later visit does not move it.\n"},"web_app_url":{"type":"string","description":"The URL to access the exam attempt copy in the Evalmee or Papeez web application as an exam owner or editor.","example":"https://app.evalmee.com/xxxxx"},"grades_by_criteria":{"type":"array","description":"Beta feature - format may change. Grades broken down by criterion for this exam attempt","x-beta":true,"items":{"$ref":"#/components/schemas/criterion_grade"}},"examinee":{"$ref":"#/components/schemas/examinee"},"exam_session":{"$ref":"#/components/schemas/exam_session"},"links":{"$ref":"#/components/schemas/links"}},"required":["id","user_id","status","started_at","finished_at","onboarding_seen_at","grade","grade_locked","grade_scale","exam_session"]},"exam_result":{"type":"object","title":"Exam Result","properties":{"examinee_id":{"type":"string","description":"The id of the examinee","example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"},"grade":{"type":["number","null"],"description":"The final grade of the examinee.\n`null` when the examinee has no grade yet **or** when the grade is locked —\ncheck `grade_locked` to tell the two apart before writing to a gradebook.\n","example":95},"grade_locked":{"type":"boolean","description":"Whether the grade is withheld pending a subscription.\nWhen `true`, `grade` and every `grades_by_criteria[].grade` are `null`\nalthough the exam has been graded: the grade exists but is not released\nyet. Do **not** record it as a zero and do **not** overwrite a previously\nsynced grade — skip the examinee and poll again once the school has\nsubscribed, at which point the same request returns the real values.\n","example":false},"grade_scale":{"type":"number","description":"The maximum grade for the exam","example":100},"selected_exam_attempt_id":{"type":["string","null"],"format":"uuid","description":"The id of the exam attempt selected as the final result — the same id\n`exam_attempts[].id` carries. `null` while no attempt is selected.\n","example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"},"status":{"type":"string","description":"The status of the examinee grade\n- `not_answered_yet`: The examinee has not answered the exam\n- `answering`: The examinee is answering the exam\n- `answered_pending_grading`: The examinee has answered and answers are not yet graded\n- `graded_pending_approval`: The examinee has answered and answers are graded but waiting for approval [This status is not yet used]\n- `graded`: The examinee has answered the exam all answers are graded\n- `absent`: The examinee was absent\n","example":"answered_pending_grading","enum":["not_answered_yet","answering","answered_pending_grading","graded_pending_approval","graded","absent"]},"grading_mode":{"type":"string","description":"Beta feature. The grading mode of the exam: 'global' (per-question criteria) or 'criteria' (aggregated quiz-level criteria)","x-beta":true,"example":"global","enum":["global","criteria"]},"grades_by_criteria":{"type":"array","description":"Beta feature - format may change. Grades broken down by criterion for the selected exam attempt","x-beta":true,"items":{"$ref":"#/components/schemas/criterion_grade"}},"exam_attempts":{"type":"object","description":"The exam attempts for the examinee","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/exam_attempt"}},"meta":{"$ref":"#/components/schemas/pagination_meta"}}},"examinee":{"$ref":"#/components/schemas/examinee"},"uids_per_identity_providers":{"$ref":"#/components/schemas/uids_per_identity_providers"},"links":{"$ref":"#/components/schemas/links"}},"required":["examinee_id","grade","grade_locked","grade_scale","status"]},"exam_session":{"type":"object","title":"Exam Session","properties":{"id":{"type":"string","description":"The id of the exam session in Evalmee","example":"a1B2c3d4e5"},"name":{"type":"string","description":"The name of the exam session","example":"Session 1"},"start_at":{"type":["string","null"],"format":"date-time","description":"The start date and time of the exam session (ISO 8601)","example":"2025-01-01T00:00:00Z"},"scheduled_end_at":{"type":["string","null"],"format":"date-time","description":"The scheduled end date and time of the exam session (ISO 8601)","example":"2025-01-01T00:00:00Z"},"groups":{"type":"array","description":"The list of groups allowed to access the exam session. Empty if all exam's examinees are allowed to access this exam session.","items":{"type":"string"}},"web_app_examinee_enrollment_url":{"type":"string","description":"The web app url an examinee can use to self-enroll in the exam session","example":"https://app.evalmee.com/join/a1B2c3d4e5-exam-name-session-name"},"allow_self_enrollment":{"type":"string","description":"Whether to allow examinees to self-enroll in the exam session\n- `none` = no self enrollment\n- `all` = all examinees can self-enroll\n- `in_school` = only examinees with an email matching the school domain can self-enroll\n","example":"none","enum":["none","all","in_school"]},"links":{"$ref":"#/components/schemas/links"}},"required":["id","name","start_at","scheduled_end_at","web_app_examinee_enrollment_url","allow_self_enrollment","links"]},"examinee":{"type":"object","title":"Examinee","properties":{"id":{"type":"string","description":"The id of the examinee in Evalmee","example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"},"first_name":{"type":["string","null"],"description":"The first name of the examinee","example":"John"},"last_name":{"type":["string","null"],"description":"The last name of the examinee","example":"Doe"},"email":{"type":"string","description":"The email of the examinee","example":"john.doe@example.com"},"external_id":{"type":["string","null"],"description":"The id of this examinee in your own system","example":"STU-2024-0142"},"groups":{"type":"array","description":"The groups of the examinee","example":["Group 1","Group 2"],"items":{"type":"string"}},"uids_per_identity_providers":{"$ref":"#/components/schemas/uids_per_identity_providers"},"links":{"$ref":"#/components/schemas/links"}},"required":["id"]},"links":{"type":"object","title":"Links","additionalProperties":{"type":"string","format":"uri"},"description":"A list of API urls related to the resource","example":{"self":"https://app.evalmee.com/api/public/v2/xxxxxx"}},"organization":{"type":"object","title":"Organization","properties":{"id":{"type":"string","description":"The id of the organization (school) in Evalmee","example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"},"name":{"type":"string","description":"The name of the organization","example":"Springfield University"},"links":{"$ref":"#/components/schemas/links"}},"required":["id","name"]},"pagination_meta":{"type":"object","properties":{"count":{"type":"integer"},"current_page":{"type":"integer"},"next_page":{"type":["integer","null"]},"prev_page":{"type":["integer","null"]},"total_count":{"type":"integer"},"total_pages":{"type":"integer"},"links":{"type":"object","properties":{"first":{"type":"string","format":"uri"},"last":{"type":"string","format":"uri"},"prev":{"type":["string","null"],"format":"uri"},"next":{"type":["string","null"],"format":"uri"}},"required":["first","last"]}},"required":["count","total_count","total_pages","links"]},"paper":{"type":"object","title":"Paper","description":"The paper configuration of an exam, and the printable files its generation produces.\n\nThis sub-resource exists **only** for a paper (Papeez) exam. The `paper` key is absent\nfrom the representation of any other exam — it is never sent as `null` — and the\ndedicated endpoint answers 404 for one.\n\nGeneration itself is triggered from the web application. This resource is read-only\napart from the scan import hanging off it.\n","properties":{"copy_type":{"type":"string","description":"Whether each copy is printed for a named examinee (`nominative`) or is interchangeable\nand matched back to a student after the scan (`anonymous`).\n","enum":["nominative","anonymous"],"example":"anonymous"},"copies_count":{"type":"integer","description":"The number of copies a generation produces: the number of enrolled examinees when\n`copy_type` is `nominative`, the configured number when it is `anonymous`.\n\nA `copies_count` greater than `build.progress.done` means the enrollments changed\nafter the copies were generated, and some examinees have no copy.\n","example":120},"build":{"type":"object","description":"The state of the copy generation.","properties":{"status":{"type":"string","description":"`not_generated` — nothing produced yet.\n`queued` — generation requested, not started.\n`generating` — in progress, follow `progress`.\n`generated` — the printable files are available.\n","enum":["not_generated","queued","generating","generated"],"example":"generated"},"progress":{"type":"object","description":"How many copies have been produced out of those expected.","properties":{"done":{"type":"integer","example":120},"total":{"type":"integer","example":120}},"required":["done","total"]}},"required":["status","progress"]},"links":{"$ref":"#/components/schemas/links"}},"required":["copy_type","copies_count","build"]},"paper_detail":{"title":"Paper Detail","description":"The paper sub-resource as served by its own endpoint, and by the answer to a scan\nimport. It carries everything the representation nested in an exam carries, plus the\ntwo page counters — which cost an aggregate query each and are therefore never\ncomputed for a whole page of exams.\n","allOf":[{"$ref":"#/components/schemas/paper"},{"type":"object","properties":{"pages_imported":{"type":"integer","description":"How many scanned pages have been split out of the imported PDFs so far. It\nrises as an import is processed and stops at the total number of pages sent.\n","example":240},"pages_processed":{"type":"integer","description":"How many of those pages the automatic grading has finished analysing. Equal\nto `pages_imported` once every page has been handled.\n\nPages the analysis could not attach to an examinee are resolved in the web\napplication: the API exposes no per-page detail.\n","example":118}},"required":["pages_imported","pages_processed"]}]},"time_accommodation":{"type":"object","title":"TimeAccommodation","description":"Extra exam time granted for specific needs. Curated in the Evalmee\napplication; this API exposes the catalog read-only and lets you assign an\nentry to a user.\n","properties":{"id":{"type":"string","format":"uuid","description":"The id of the time accommodation in Evalmee","example":"b2c3d4e5-f6a7-4b9c-8d1e-f2a3b4c5d6e7"},"name":{"type":"string","nullable":true,"description":"The label given to this accommodation in the Evalmee application","example":"One third extra time"},"numerator":{"type":"integer","description":"Numerator of the extra-time fraction","example":1},"denominator":{"type":"integer","description":"Denominator of the extra-time fraction","example":3},"extra_ratio":{"type":"string","description":"The extra time as an exact fraction of the exam's own time limit — `\"1/3\"`\ngrants a 60-minute exam another 20 minutes. A string rather than a number\nso that thirds stay exact.\n","example":"1/3"},"links":{"$ref":"#/components/schemas/links"}},"required":["id"]},"uids_per_identity_providers":{"type":"array","description":"The uids per identity providers of the examinee","items":{"type":"object","properties":{"provider":{"type":"string","description":"The identity provider name","example":"evalmee"},"uid":{"type":"string","description":"The user identifier for this provider","example":"john.doe@example.com"}},"required":["provider","uid"]},"example":[{"provider":"evalmee","uid":"john.doe@example.com"},{"provider":"azure_active_directory","uid":"1234567890"}]},"user":{"type":"object","title":"User","description":"A user represents a person known to your organization.\n\nThe id identifies a *membership*, not a human being: the same person belonging\nto two organizations has a different id in each, and neither can see the\nother's.\n","properties":{"id":{"type":"string","format":"uuid","description":"The id of the user in Evalmee","example":"c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7"},"first_name":{"type":"string","nullable":true,"description":"The first name of the user","example":"John"},"last_name":{"type":"string","nullable":true,"description":"The last name of the user","example":"Doe"},"email":{"type":"string","description":"The email of the user. Identifies them across the whole platform, and\ncannot be changed through this API.\n","example":"john.doe@example.com"},"type":{"type":"string","description":"What the user can do in your organization.\n- `examinee` = takes exams\n- `examiner` = creates and grades exams\n\nRead-only: creating an examiner is a billable act and goes through the\nEvalmee application. An examiner can still be enrolled as an examinee.\n","example":"examinee","enum":["examinee","examiner"]},"external_id":{"type":"string","nullable":true,"description":"The id of this person in your own system. Specific to your organization:\nthe same person in another organization can carry a different one, or\nnone.\n","example":"STU-2024-0142"},"time_accommodation":{"nullable":true,"description":"The extra time this user is granted, on every exam that honors\naccommodations. `null` when they have none.\n\nNot to be confused with the exam's own `time_accommodation`, which is a\nboolean saying whether that exam honors accommodations at all.\n","allOf":[{"$ref":"#/components/schemas/time_accommodation"}]},"links":{"$ref":"#/components/schemas/links"}},"required":["id"]},"webhook_email_bounced_event":{"title":"Email bounced event","description":"Sent when the recipient's mail server permanently rejected the\nconvocation — an unknown address, a full mailbox, a blocked sender.\n`data` is the email, in the same shape `/emails/{id}` returns.\n\nThis is the event to act on: the examinee will not receive the\nconvocation. Fix the address, then invite them again.\n","allOf":[{"$ref":"#/components/schemas/webhook_envelope"},{"type":"object","properties":{"type":{"type":"string","enum":["email.bounced"]},"data":{"$ref":"#/components/schemas/email"}}}]},"webhook_email_clicked_event":{"title":"Email link clicked event","description":"Sent the first time the recipient clicked the exam link in the\nconvocation. `data` is the email, in the same shape `/emails/{id}`\nreturns.\n\nSent once, on the first click, however many links the recipient\nfollows afterwards.\n","allOf":[{"$ref":"#/components/schemas/webhook_envelope"},{"type":"object","properties":{"type":{"type":"string","enum":["email.clicked"]},"data":{"$ref":"#/components/schemas/email"}}}]},"webhook_email_complained_event":{"title":"Email reported as spam event","description":"Sent when the recipient reported the convocation as spam to their mail\nprovider. `data` is the email, in the same shape `/emails/{id}`\nreturns.\n\n`status_updated_at` carries the provider's own timestamp for the\nreport, distinct from the envelope's `timestamp`.\n","allOf":[{"$ref":"#/components/schemas/webhook_envelope"},{"type":"object","properties":{"type":{"type":"string","enum":["email.complained"]},"data":{"$ref":"#/components/schemas/email"}}}]},"webhook_email_delivered_event":{"title":"Email delivered event","description":"Sent when the recipient's mail server accepted the convocation. `data`\nis the email, in the same shape `/emails/{id}` returns.\n\nDelivery is not proof the convocation was read: `email.opened` reports\nthat. `status_updated_at` carries the provider's own timestamp for the\ndelivery, distinct from the envelope's `timestamp`.\n","allOf":[{"$ref":"#/components/schemas/webhook_envelope"},{"type":"object","properties":{"type":{"type":"string","enum":["email.delivered"]},"data":{"$ref":"#/components/schemas/email"}}}]},"webhook_email_delivery_delayed_event":{"title":"Email delivery delayed event","description":"Sent when the recipient's mail server temporarily refused the\nconvocation and the provider will retry. `data` is the email, in the\nsame shape `/emails/{id}` returns.\n\nSent once, on the first deferral, however many times the provider\nretries afterwards. Usually followed by `email.delivered` or\n`email.bounced`.\n","allOf":[{"$ref":"#/components/schemas/webhook_envelope"},{"type":"object","properties":{"type":{"type":"string","enum":["email.delivery_delayed"]},"data":{"$ref":"#/components/schemas/email"}}}]},"webhook_email_failed_event":{"title":"Email failed event","description":"Sent when the convocation could not be sent at all — a suppressed\naddress, a rendering failure at the provider. `data` is the email, in\nthe same shape `/emails/{id}` returns.\n\nNothing ever left the provider, so the examinee received nothing. Same\nremediation as a bounce: fix the address, then invite them again.\n","allOf":[{"$ref":"#/components/schemas/webhook_envelope"},{"type":"object","properties":{"type":{"type":"string","enum":["email.failed"]},"data":{"$ref":"#/components/schemas/email"}}}]},"webhook_email_opened_event":{"title":"Email opened event","description":"Sent the first time the recipient opened the convocation, as reported\nby its tracking pixel. `data` is the email, in the same shape\n`/emails/{id}` returns.\n\nAn absent event does not mean the convocation went unread: a mail\nclient that blocks images never loads the pixel. Sent once, on the\nfirst open.\n","allOf":[{"$ref":"#/components/schemas/webhook_envelope"},{"type":"object","properties":{"type":{"type":"string","enum":["email.opened"]},"data":{"$ref":"#/components/schemas/email"}}}]},"webhook_email_sent_event":{"title":"Email sent event","description":"Sent when the provider accepted the convocation and handed it to the\ntransport. `data` is the email, in the same shape `/emails/{id}`\nreturns.\n\nIt does not mean the convocation reached the mailbox: `email.delivered`\nreports that. Sent once per convocation.\n","allOf":[{"$ref":"#/components/schemas/webhook_envelope"},{"type":"object","properties":{"type":{"type":"string","enum":["email.sent"]},"data":{"$ref":"#/components/schemas/email"}}}]},"webhook_envelope":{"type":"object","title":"Webhook envelope","description":"The body of every webhook we POST to your endpoint. `data` carries the\npayload specific to `type`; every other field is present on all events.\n","properties":{"id":{"type":"string","format":"uuid","description":"The id of the event. Stable across retries of the same event, so it is\nthe key to deduplicate on. Also sent as the `webhook-id` header.\n","example":"a1b2c3d4-e5f6-4a8b-9c0d-e1f2a3b4c5d6"},"type":{"type":"string","description":"The kind of event, matching one of the topics you subscribed to","example":"ping"},"timestamp":{"type":"string","format":"date-time","description":"When the event happened, not when this delivery attempt was made","example":"2026-08-31T09:15:00Z"},"organization_id":{"type":"string","format":"uuid","description":"The id of the organization (school) the event belongs to","example":"c3d4e5f6-a7b8-4c9d-8e1f-a2b3c4d5e6f7"},"data":{"type":"object","description":"The payload of the event, whose shape depends on `type`"}},"required":["id","type","timestamp","organization_id","data"]},"webhook_exam_attempt_finished_event":{"title":"Exam attempt finished event","description":"Sent when an examinee's attempt ends, whether the examinee\nsubmitted it, its time ran out, or an examiner closed it. `data`\nis the exam attempt, in the same shape\n`/exams/{exam_id}/exam_attempts` returns.\n\nThe grade may still be computing when the event is sent: read it\nfrom the API when it matters. A finished attempt that is reopened\nsends `exam_attempt.started` again, then a second\n`exam_attempt.finished` when it ends again. Paper exams do not\nsend it, and previewing an exam does not send one: only an\nexaminee's attempt does.\n","allOf":[{"$ref":"#/components/schemas/webhook_envelope"},{"type":"object","properties":{"type":{"type":"string","enum":["exam_attempt.finished"]},"data":{"$ref":"#/components/schemas/exam_attempt"}}}]},"webhook_exam_attempt_onboarding_seen_event":{"title":"Exam attempt onboarding seen event","description":"Sent the first time an examinee opens an exam's onboarding page.\n`data` is the exam attempt, in the same shape\n`/exams/{exam_id}/exam_attempts` returns.\n\nFires once per attempt: a later visit to the same page does not\nsend a second event. Previewing an exam does not send one: only\nan examinee's attempt does.\n","allOf":[{"$ref":"#/components/schemas/webhook_envelope"},{"type":"object","properties":{"type":{"type":"string","enum":["exam_attempt.onboarding_seen"]},"data":{"$ref":"#/components/schemas/exam_attempt"}}}]},"webhook_exam_attempt_started_event":{"title":"Exam attempt started event","description":"Sent when an examinee starts an exam. `data` is the exam attempt,\nin the same shape `/exams/{exam_id}/exam_attempts` returns.\n\nReopening a finished attempt starts it again and sends a second\nevent, with a different `id`. Previewing an exam does not send\none: only an examinee's attempt does.\n","allOf":[{"$ref":"#/components/schemas/webhook_envelope"},{"type":"object","properties":{"type":{"type":"string","enum":["exam_attempt.started"]},"data":{"$ref":"#/components/schemas/exam_attempt"}}}]},"webhook_ping_event":{"title":"Ping event","description":"Sent on demand, to prove your endpoint is reachable and that your\nsignature verification works. Carries no business data, and is\ndelivered through the exact same pipeline as any other event.\n","allOf":[{"$ref":"#/components/schemas/webhook_envelope"},{"type":"object","properties":{"type":{"type":"string","enum":["ping"]},"data":{"type":"object","description":"Always empty","example":{}}}}]}}}}