Submission checks
Check uploaded work before you accept it: right brief, every question answered, word count, name and your own questions.
- Price1 credit (10p) per request
- Typical time5 s to 2 min
- Scope
marking:write - Runs asA background job
Run submission checks in the sandbox
No key and nothing to pay. The sandbox returns a realistic example in a couple of seconds; no AI runs and no data is kept.
- Queued202 and a job id, straight away
- ProcessingPoll, stream or wait for a webhook
- SucceededResult and files on the job
Send the files a learner is about to hand in, the brief and the checks to run. Each check comes back pass, fail or unavailable with a plain explanation you can show the learner. Scans, photos and handwriting are read as images. Checks are evidence for a person, never a mark, and nothing is stored in your LMS. All checks in one request cost one charge.
Requires marking:write. Costs 1 credit per request. Send a unique Idempotency-Key; reuse it with the identical body when retrying. Returns 202 with a job: poll GET /jobs/{job_id}, stream GET /jobs/{job_id}/events, or use a signed webhook.
Submission checks
POST/v1/checks/submissions
Scope marking:write
Headers
| Field | Details |
|---|---|
Idempotency-Key | stringRequiredA unique key per new operation; reuse it with the identical body when retrying. |
EduMark-Version | enumAPI version. Defaults to the latest.One of 2026-10-21 |
Request body
| Field | Details |
|---|---|
files | array of FileReference or DocumentInputRequiredThe uploaded work: PDF, DOCX or TXT (inline or uploaded), or PNG, JPEG or WEBP photos via file_id.1 to 5 items |
file_idfiles[].file_id | stringRequiredThe id returned by POST /v1/files, after POST /v1/files/{id}/complete reported ready.When sending FileReferencePattern ^file_[a-f0-9]{32}$ |
filenamefiles[].filename | stringRequiredWhen sending DocumentInputUp to 200 characters |
base64files[].base64 | stringRequiredWhen sending DocumentInputUp to 27,962,028 characters |
mime_typefiles[].mime_type | string, optionalWhen sending DocumentInputUp to 150 characters |
checks | array of BriefMatchCheck or WordCountCheck or IdentityCheck or LanguageCheck or CustomCheckRequired1 to 10 items |
namechecks[].name | string, optionalWhen sending BriefMatchCheckUp to 80 characters |
kindchecks[].kind | "brief_match"RequiredWhen sending BriefMatchCheck |
matchchecks[].match | enumsame_work: the file is an attempt at this brief. every_question: it also answers every question in the brief.When sending BriefMatchCheckOne of same_work, every_questionDefault "same_work" |
namechecks[].name | string, optionalWhen sending WordCountCheckUp to 80 characters |
kindchecks[].kind | "word_count"RequiredWhen sending WordCountCheck |
min_wordschecks[].min_words | integer, optionalDefaults to the brief's word_count.When sending WordCountCheck1 to 100,000 |
max_wordschecks[].max_words | integer, optionalDefaults to the brief's word_count.When sending WordCountCheck1 to 100,000 |
tolerance_percentchecks[].tolerance_percent | integerWhen sending WordCountCheck0 to 50Default 0 |
exclude_referenceschecks[].exclude_references | booleanWhen sending WordCountCheckDefault true |
namechecks[].name | string, optionalWhen sending IdentityCheckUp to 80 characters |
kindchecks[].kind | "learner_identity"RequiredWhen sending IdentityCheck |
namechecks[].name | string, optionalWhen sending LanguageCheckUp to 80 characters |
kindchecks[].kind | "language"RequiredWhen sending LanguageCheck |
languagechecks[].language | stringWhen sending LanguageCheckUp to 40 charactersDefault "English" |
namechecks[].name | string, optionalWhen sending CustomCheckUp to 80 characters |
kindchecks[].kind | "custom"RequiredWhen sending CustomCheck |
idchecks[].id | stringRequiredWhen sending CustomCheckPattern ^[A-Za-z0-9_-]{1,64}$ |
promptchecks[].prompt | stringRequiredA question about the work, for example “Is there a signed declaration?”When sending CustomCheckUp to 2,000 characters |
outputchecks[].output | enumRequiredWhen sending CustomCheckOne of yes_no, number, choice, text |
pass_whenchecks[].pass_when | enumWhen sending CustomCheckOne of yes, noDefault "yes" |
pass_minchecks[].pass_min | number, optionalWhen sending CustomCheck-1,000,000 to 1,000,000 |
pass_maxchecks[].pass_max | number, optionalWhen sending CustomCheck-1,000,000 to 1,000,000 |
choiceschecks[].choices | array of stringWhen sending CustomCheckUp to 10 items |
pass_choiceschecks[].pass_choices | array of stringWhen sending CustomCheckUp to 10 items |
brief | Brief, optionalThe assignment the work should answer. Needed for brief_match. |
titlebrief.title | stringRequiredUp to 200 characters |
instructionsbrief.instructions | string, optionalUp to 3,000 characters |
questionsbrief.questions | array of BriefQuestionUp to 60 items |
refbrief.questions[].ref | stringRequiredHow the brief labels it, for example 1a or Task 2.Up to 80 characters |
promptbrief.questions[].prompt | stringRequiredUp to 1,500 characters |
word_countbrief.word_count | WordLimits, optional |
minimumbrief.word_count.minimum | integer, optional1 to 100,000 |
maximumbrief.word_count.maximum | integer, optional1 to 100,000 |
learner_name | string, optionalNeeded for learner_identity.Up to 200 characters |
Responses
| Status | Meaning |
|---|---|
| 202 | Successful Response |
| 400 | Request rejected. Inspect error.code and request_id; failed work is not billed. |
| 401 | Request rejected. Inspect error.code and request_id; failed work is not billed. |
| 402 | Request rejected. Inspect error.code and request_id; failed work is not billed. |
| 403 | Request rejected. Inspect error.code and request_id; failed work is not billed. |
| 404 | Request rejected. Inspect error.code and request_id; failed work is not billed. |
| 409 | Request rejected. Inspect error.code and request_id; failed work is not billed. |
| 410 | Request rejected. Inspect error.code and request_id; failed work is not billed. |
| 413 | Request rejected. Inspect error.code and request_id; failed work is not billed. |
| 415 | Request rejected. Inspect error.code and request_id; failed work is not billed. |
| 422 | Validation Error |
| 429 | Request rejected. Inspect error.code and request_id; failed work is not billed. |
| 503 | Request rejected. Inspect error.code and request_id; failed work is not billed. |