> ## Documentation Index
> Fetch the complete documentation index at: https://docs.examino.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Copies API - Create, List, Read, and Delete Copies

> Attach uploaded files to student copies, list and inspect copy status, and permanently delete copies along with their corrections and storage files.

A copy represents one student's submission for an exam. You create copies by linking previously uploaded file IDs to an exam, Examino then processes the files, recognizes student names, and makes the copies available for correction. This page covers listing, creating, reading, and deleting copies.

***

## List copies

Returns all copies belonging to an exam, sorted by `index` then by creation date.

**Required scope:** `copies:read`

<Note>
  Provisional copies created during batch splitting in the web app are never included in this response.
</Note>

```bash title="Request" theme={null}
curl "https://app.examino.ai/api/v1/exams/aa11bb22-cc33-44dd-88ee-ff0011223344/copies" \
  -H "Authorization: Bearer $EXAMINO_API_KEY"
```

```json title="Response 200" theme={null}
{
  "items": [
    {
      "id": "11112222-3333-4444-8555-666677778888",
      "examId": "aa11bb22-cc33-44dd-88ee-ff0011223344",
      "studentName": "Camille Dupont",
      "studentNameRecognized": "Camille Dupont",
      "idProvidedByUser": "ETU-2026-0417",
      "index": 1,
      "triageStatus": "success",
      "reviewedAt": null,
      "mainCorrectionId": "99990000-aaaa-4bbb-8ccc-ddddeeeeffff",
      "createdAt": "2026-09-15T10:02:11.775Z"
    }
  ],
  "total": 1
}
```

### Response fields

<ResponseField name="id" type="string">
  UUID of the copy.
</ResponseField>

<ResponseField name="examId" type="string">
  UUID of the exam this copy belongs to.
</ResponseField>

<ResponseField name="studentName" type="string | null">
  The name you provided at creation time via `studentName`.
</ResponseField>

<ResponseField name="studentNameRecognized" type="string | null">
  The name Examino read directly from the copy document. Useful for matching an anonymous import back to your student roster when no `studentName` was supplied.
</ResponseField>

<ResponseField name="idProvidedByUser" type="string | null">
  Your own student identifier, returned exactly as you provided it. This is the recommended key for matching copies back to your Student Information System.
</ResponseField>

<ResponseField name="index" type="integer | null">
  Position of this copy within the exam. Used for stable ordering.
</ResponseField>

<ResponseField name="triageStatus" type="string | null">
  Processing status of the copy files: `success`, `processing`, `error`, or `null`.
</ResponseField>

<ResponseField name="reviewedAt" type="string | null">
  ISO 8601 timestamp of when an instructor validated the correction. `null` means the copy has not yet been reviewed.
</ResponseField>

<ResponseField name="mainCorrectionId" type="string | null">
  UUID of the active correction for this copy. This is set as soon as a correction is launched, its presence does **not** mean a result is available yet.
</ResponseField>

<ResponseField name="createdAt" type="string">
  ISO 8601 creation timestamp.
</ResponseField>

***

## Create copies

Links already-uploaded files to new copies and kicks off background processing. You can create up to 50 copies in a single call.

**Required scope:** `copies:write`

<ParamField body="copies" type="array" required>
  Array of copy objects to create. Must contain between 1 and 50 items.

  <Expandable title="Copy object fields">
    <ParamField body="fileIds" type="string[]" required>
      One or more `fileId` values returned by `POST /uploads`, in page order. Between 1 and 50 file IDs per copy. Use multiple IDs when a single student's submission spans several files.
    </ParamField>

    <ParamField body="studentName" type="string">
      Student's display name. Maximum 300 characters. If omitted, Examino attempts to recognize it from the document.
    </ParamField>

    <ParamField body="idProvidedByUser" type="string">
      Your own identifier for this student, e.g. an SIS student ID. Maximum 200 characters. Returned as-is on every response, useful for matching results back to your system.
    </ParamField>
  </Expandable>
</ParamField>

<Note>
  Creation is **atomic**: either every copy in the request is created, or none of them are. A single invalid `fileId` rolls back the entire batch. Created copies are attributed to the API key, not to the user who originally created it.
</Note>

<Warning>
  A file is only usable by the API key that registered it. If you upload a file with one key and try to attach it with another key, the API returns `404 not_found`.
</Warning>

```bash title="Request" theme={null}
curl -X POST https://app.examino.ai/api/v1/exams/aa11bb22-cc33-44dd-88ee-ff0011223344/copies \
  -H "Authorization: Bearer $EXAMINO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "copies": [
      {
        "studentName": "Camille Dupont",
        "idProvidedByUser": "ETU-2026-0417",
        "fileIds": ["5c6d7e8f-9a0b-41c2-83d4-e5f6a7b8c9d0"]
      },
      {
        "studentName": "Alex Martin",
        "idProvidedByUser": "ETU-2026-0418",
        "fileIds": [
          "1a2b3c4d-5e6f-4071-8293-a4b5c6d7e8f9",
          "2b3c4d5e-6f70-4182-93a4-b5c6d7e8f9a0"
        ]
      }
    ]
  }'
```

```json title="Response 201" theme={null}
{
  "items": [
    {
      "id": "11112222-3333-4444-8555-666677778888",
      "examId": "aa11bb22-cc33-44dd-88ee-ff0011223344",
      "studentName": "Camille Dupont",
      "idProvidedByUser": "ETU-2026-0417"
    },
    {
      "id": "22223333-4444-5555-8666-777788889999",
      "examId": "aa11bb22-cc33-44dd-88ee-ff0011223344",
      "studentName": "Alex Martin",
      "idProvidedByUser": "ETU-2026-0418"
    }
  ],
  "total": 2
}
```

### Error reference

<AccordionGroup>
  <Accordion title="Creation errors">
    | Case                                                     | Response              |
    | -------------------------------------------------------- | --------------------- |
    | Same `fileId` appears on two copies in the same request  | `400 invalid_request` |
    | Unknown `fileId` or file uploaded by a different API key | `404 not_found`       |
    | `fileId` is already attached to an existing copy         | `409 conflict`        |
  </Accordion>
</AccordionGroup>

***

## Get a copy

Returns the full detail object for a single copy, including its `teamId`.

**Required scope:** `copies:read`

```bash title="Request" theme={null}
curl "https://app.examino.ai/api/v1/copies/11112222-3333-4444-8555-666677778888" \
  -H "Authorization: Bearer $EXAMINO_API_KEY"
```

```json title="Response 200" theme={null}
{
  "id": "11112222-3333-4444-8555-666677778888",
  "examId": "aa11bb22-cc33-44dd-88ee-ff0011223344",
  "teamId": "d4e5f6a7-b8c9-40d1-a2b3-c4d5e6f7a8b9",
  "studentName": "Camille Dupont",
  "studentNameRecognized": "Camille Dupont",
  "idProvidedByUser": "ETU-2026-0417",
  "index": 1,
  "triageStatus": "success",
  "reviewedAt": null,
  "mainCorrectionId": "99990000-aaaa-4bbb-8ccc-ddddeeeeffff",
  "createdAt": "2026-09-15T10:02:11.775Z"
}
```

The response includes all fields from the list endpoint, plus `teamId`, the UUID of the team that owns the exam.

***

## Delete a copy

Permanently removes a copy, its uploaded files, and its correction from Examino.

**Required scope:** `copies:write`

<Warning>
  Deletion is **permanent**, this is not an archive. The copy, its files, and any associated correction are permanently deleted and cannot be recovered. Do not use this endpoint unless you are certain the data is no longer needed.
</Warning>

<Note>
  The following cleanup happens automatically on deletion:

  * Any credits reserved for this copy are returned to your balance.
  * In-progress background processing is cancelled.
  * Storage files are deleted, unless a file is shared with another copy or with the exam subject.
</Note>

```bash title="Request" theme={null}
curl -X DELETE "https://app.examino.ai/api/v1/copies/11112222-3333-4444-8555-666677778888" \
  -H "Authorization: Bearer $EXAMINO_API_KEY"
```

```json title="Response 200" theme={null}
{
  "id": "11112222-3333-4444-8555-666677778888",
  "deleted": true
}
```
