---
title: "Mark a submission"
description: "Records the mark and feedback the way the marking page does, so the gradebook, the marking workflow and the audit trail behave the same. Only the current attempt that has been handed in can be marked.\n\n### Quire permissions\n\nRequired capability: `assignment/grade`.\n\nCredential scopes: `submissions:write`.\n\nThe acting subject must also be allowed to perform this action in the organisation."
image: "https://docs.quirelms.com/og.png"
---

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

Path: Quire API › submissions

`POST /submissions/{id}/actions/mark`

Records the mark and feedback the way the marking page does, so the gradebook, the marking workflow and the audit trail behave the same. Only the current attempt that has been handed in can be marked.

\### Quire permissions

Required capability: `assignment/grade`.

Credential scopes: `submissions:write`.

The acting subject must also be allowed to perform this action in the organisation.

## Authentication

Requires one of the following:

- `apiKey`, http, header `Authorization`, scopes: `submissions:write`
- `oauth2`, oauth2, scopes: `submissions:write`

## Path parameters

- `markSubmission.path.id` (string, required)

## Header parameters

- `markSubmission.header.Quire-Version` (string, optional) — The dated API revision to serve this request at. Omitted, the request is served at the revision the credential was issued against. The response echoes the revision actually applied.
  - format `date`
- `markSubmission.header.Idempotency-Key` (string, optional) — A caller-chosen key making this request safe to retry. A replay of a completed request returns the recorded response with `Idempotency-Replayed: true`. Reusing a key for a different request is refused.
  - maxLength 255

## Request body

_Required._

- `markSubmission.raw` (any of, required) — The mark out of 100, or null to clear it.
  - any of: `number`, `null`
- `markSubmission.feedback` (any of, optional)
  - any of: `string`, `null`
- `markSubmission.workflow_state` (string, optional) — Move the marking workflow on, when the assignment uses it.
  - one of `"not_marked"`, `"in_marking"`, `"marking_completed"`, `"in_review"`, `"ready_for_release"`, `"released"`

## Example request

```json
{
  "raw": 100,
  "feedback": "string",
  "workflow_state": "not_marked"
}
```

## Code samples

### cURL

```curl
curl --request POST \
  --url https://your-organisation.quirelms.com/api/v1/submissions/string/actions/mark \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "raw": 100,
  "feedback": "string",
  "workflow_state": "not_marked"
}
'
```

### TypeScript

```typescript
const url = 'https://your-organisation.quirelms.com/api/v1/submissions/string/actions/mark';
const options = {
  method: 'POST',
  headers: {'Content-Type': 'application/json', Authorization: 'Bearer <token>'},
  body: JSON.stringify({raw: 100, feedback: 'string', workflow_state: 'not_marked'})
};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error(err));
```

### Python

```python
import requests

url = "https://your-organisation.quirelms.com/api/v1/submissions/string/actions/mark"

payload = {
    "raw": 100,
    "feedback": "string",
    "workflow_state": "not_marked"
}
headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer <token>"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
```

## Responses

### 200

Success.

#### Example

```json
{
  "id": "string",
  "external_id": "string",
  "assignment_id": "string",
  "activity_id": "string",
  "course_id": "string",
  "user_id": "string",
  "group_id": "string",
  "attempt": -9007199254740991,
  "state": "new",
  "submitted_at": "string",
  "is_late": true,
  "word_count": -9007199254740991,
  "latest": true,
  "created_at": "string",
  "updated_at": "string"
}
```

- `markSubmission.response.200.id` (string, required)
- `markSubmission.response.200.external_id` (string | null, required)
- `markSubmission.response.200.assignment_id` (string, required)
- `markSubmission.response.200.activity_id` (string, required)
- `markSubmission.response.200.course_id` (string, required)
- `markSubmission.response.200.user_id` (string | null, required)
- `markSubmission.response.200.group_id` (string | null, required)
- `markSubmission.response.200.attempt` (integer, required)
  - min -9007199254740991; max 9007199254740991
- `markSubmission.response.200.state` (string, required)
  - one of `"new"`, `"draft"`, `"submitted"`, `"reopened"`
- `markSubmission.response.200.submitted_at` (any of, required)
  - any of: `string`, `null`
- `markSubmission.response.200.is_late` (boolean, required)
- `markSubmission.response.200.word_count` (any of, required)
  - any of: `integer`, `null`
- `markSubmission.response.200.latest` (boolean, required)
- `markSubmission.response.200.created_at` (string, required) — RFC 3339 timestamp in UTC.
- `markSubmission.response.200.updated_at` (string, required) — RFC 3339 timestamp in UTC.

### 401

The credential is missing, malformed, expired or revoked.

#### Example

```json
{
  "type": "http://example.com",
  "title": "string",
  "status": 0,
  "code": "string",
  "category": "validation",
  "detail": "string",
  "request_id": "string",
  "errors": [
    {
      "path": "string",
      "code": "string",
      "detail": "string"
    }
  ],
  "retry_after": 0,
  "docs_url": "http://example.com"
}
```

- `markSubmission.response.401.type` (string, required)
  - format `uri`
- `markSubmission.response.401.title` (string, required)
- `markSubmission.response.401.status` (integer, required)
- `markSubmission.response.401.code` (string, required)
- `markSubmission.response.401.category` (string, required)
  - one of `"validation"`, `"authentication"`, `"authorization"`, `"not_found"`, `"conflict"`, `"precondition"`, `"quota"`, `"rate_limit"`, `"upstream"`, `"internal"`
- `markSubmission.response.401.detail` (string, required)
- `markSubmission.response.401.request_id` (string, required)
- `markSubmission.response.401.docs_url` (string, required)
  - format `uri`
- `markSubmission.response.401.errors` (array<object>, optional)
  - `markSubmission.response.401.errors.path` (string, required) — RFC 6901 JSON Pointer into the request body.
  - `markSubmission.response.401.errors.code` (string, required)
  - `markSubmission.response.401.errors.detail` (string, required)
- `markSubmission.response.401.retry_after` (integer | null, optional)

### 403

The credential lacks the scope this operation requires, or the acting subject lacks the capability.

#### Example

```json
{
  "type": "http://example.com",
  "title": "string",
  "status": 0,
  "code": "string",
  "category": "validation",
  "detail": "string",
  "request_id": "string",
  "errors": [
    {
      "path": "string",
      "code": "string",
      "detail": "string"
    }
  ],
  "retry_after": 0,
  "docs_url": "http://example.com"
}
```

- `markSubmission.response.403.type` (string, required)
  - format `uri`
- `markSubmission.response.403.title` (string, required)
- `markSubmission.response.403.status` (integer, required)
- `markSubmission.response.403.code` (string, required)
- `markSubmission.response.403.category` (string, required)
  - one of `"validation"`, `"authentication"`, `"authorization"`, `"not_found"`, `"conflict"`, `"precondition"`, `"quota"`, `"rate_limit"`, `"upstream"`, `"internal"`
- `markSubmission.response.403.detail` (string, required)
- `markSubmission.response.403.request_id` (string, required)
- `markSubmission.response.403.docs_url` (string, required)
  - format `uri`
- `markSubmission.response.403.errors` (array<object>, optional)
  - `markSubmission.response.403.errors.path` (string, required) — RFC 6901 JSON Pointer into the request body.
  - `markSubmission.response.403.errors.code` (string, required)
  - `markSubmission.response.403.errors.detail` (string, required)
- `markSubmission.response.403.retry_after` (integer | null, optional)

### 404

No such resource, or none this credential is permitted to know about.

#### Example

```json
{
  "type": "http://example.com",
  "title": "string",
  "status": 0,
  "code": "string",
  "category": "validation",
  "detail": "string",
  "request_id": "string",
  "errors": [
    {
      "path": "string",
      "code": "string",
      "detail": "string"
    }
  ],
  "retry_after": 0,
  "docs_url": "http://example.com"
}
```

- `markSubmission.response.404.type` (string, required)
  - format `uri`
- `markSubmission.response.404.title` (string, required)
- `markSubmission.response.404.status` (integer, required)
- `markSubmission.response.404.code` (string, required)
- `markSubmission.response.404.category` (string, required)
  - one of `"validation"`, `"authentication"`, `"authorization"`, `"not_found"`, `"conflict"`, `"precondition"`, `"quota"`, `"rate_limit"`, `"upstream"`, `"internal"`
- `markSubmission.response.404.detail` (string, required)
- `markSubmission.response.404.request_id` (string, required)
- `markSubmission.response.404.docs_url` (string, required)
  - format `uri`
- `markSubmission.response.404.errors` (array<object>, optional)
  - `markSubmission.response.404.errors.path` (string, required) — RFC 6901 JSON Pointer into the request body.
  - `markSubmission.response.404.errors.code` (string, required)
  - `markSubmission.response.404.errors.detail` (string, required)
- `markSubmission.response.404.retry_after` (integer | null, optional)

### 409

The request conflicts with the current state, with a previous use of the same idempotency key, or with a concurrent write.

#### Example

```json
{
  "type": "http://example.com",
  "title": "string",
  "status": 0,
  "code": "string",
  "category": "validation",
  "detail": "string",
  "request_id": "string",
  "errors": [
    {
      "path": "string",
      "code": "string",
      "detail": "string"
    }
  ],
  "retry_after": 0,
  "docs_url": "http://example.com"
}
```

- `markSubmission.response.409.type` (string, required)
  - format `uri`
- `markSubmission.response.409.title` (string, required)
- `markSubmission.response.409.status` (integer, required)
- `markSubmission.response.409.code` (string, required)
- `markSubmission.response.409.category` (string, required)
  - one of `"validation"`, `"authentication"`, `"authorization"`, `"not_found"`, `"conflict"`, `"precondition"`, `"quota"`, `"rate_limit"`, `"upstream"`, `"internal"`
- `markSubmission.response.409.detail` (string, required)
- `markSubmission.response.409.request_id` (string, required)
- `markSubmission.response.409.docs_url` (string, required)
  - format `uri`
- `markSubmission.response.409.errors` (array<object>, optional)
  - `markSubmission.response.409.errors.path` (string, required) — RFC 6901 JSON Pointer into the request body.
  - `markSubmission.response.409.errors.code` (string, required)
  - `markSubmission.response.409.errors.detail` (string, required)
- `markSubmission.response.409.retry_after` (integer | null, optional)

### 422

The request was understood and its content is not valid. `errors` names each field.

#### Example

```json
{
  "type": "http://example.com",
  "title": "string",
  "status": 0,
  "code": "string",
  "category": "validation",
  "detail": "string",
  "request_id": "string",
  "errors": [
    {
      "path": "string",
      "code": "string",
      "detail": "string"
    }
  ],
  "retry_after": 0,
  "docs_url": "http://example.com"
}
```

- `markSubmission.response.422.type` (string, required)
  - format `uri`
- `markSubmission.response.422.title` (string, required)
- `markSubmission.response.422.status` (integer, required)
- `markSubmission.response.422.code` (string, required)
- `markSubmission.response.422.category` (string, required)
  - one of `"validation"`, `"authentication"`, `"authorization"`, `"not_found"`, `"conflict"`, `"precondition"`, `"quota"`, `"rate_limit"`, `"upstream"`, `"internal"`
- `markSubmission.response.422.detail` (string, required)
- `markSubmission.response.422.request_id` (string, required)
- `markSubmission.response.422.docs_url` (string, required)
  - format `uri`
- `markSubmission.response.422.errors` (array<object>, optional)
  - `markSubmission.response.422.errors.path` (string, required) — RFC 6901 JSON Pointer into the request body.
  - `markSubmission.response.422.errors.code` (string, required)
  - `markSubmission.response.422.errors.detail` (string, required)
- `markSubmission.response.422.retry_after` (integer | null, optional)

### 429

A rate limit or a concurrency cap was reached. `Retry-After` says when to try again.

#### Example

```json
{
  "type": "http://example.com",
  "title": "string",
  "status": 0,
  "code": "string",
  "category": "validation",
  "detail": "string",
  "request_id": "string",
  "errors": [
    {
      "path": "string",
      "code": "string",
      "detail": "string"
    }
  ],
  "retry_after": 0,
  "docs_url": "http://example.com"
}
```

- `markSubmission.response.429.type` (string, required)
  - format `uri`
- `markSubmission.response.429.title` (string, required)
- `markSubmission.response.429.status` (integer, required)
- `markSubmission.response.429.code` (string, required)
- `markSubmission.response.429.category` (string, required)
  - one of `"validation"`, `"authentication"`, `"authorization"`, `"not_found"`, `"conflict"`, `"precondition"`, `"quota"`, `"rate_limit"`, `"upstream"`, `"internal"`
- `markSubmission.response.429.detail` (string, required)
- `markSubmission.response.429.request_id` (string, required)
- `markSubmission.response.429.docs_url` (string, required)
  - format `uri`
- `markSubmission.response.429.errors` (array<object>, optional)
  - `markSubmission.response.429.errors.path` (string, required) — RFC 6901 JSON Pointer into the request body.
  - `markSubmission.response.429.errors.code` (string, required)
  - `markSubmission.response.429.errors.detail` (string, required)
- `markSubmission.response.429.retry_after` (integer | null, optional)

### 500

Something failed at our end. Quote `request_id` when reporting it.

#### Example

```json
{
  "type": "http://example.com",
  "title": "string",
  "status": 0,
  "code": "string",
  "category": "validation",
  "detail": "string",
  "request_id": "string",
  "errors": [
    {
      "path": "string",
      "code": "string",
      "detail": "string"
    }
  ],
  "retry_after": 0,
  "docs_url": "http://example.com"
}
```

- `markSubmission.response.500.type` (string, required)
  - format `uri`
- `markSubmission.response.500.title` (string, required)
- `markSubmission.response.500.status` (integer, required)
- `markSubmission.response.500.code` (string, required)
- `markSubmission.response.500.category` (string, required)
  - one of `"validation"`, `"authentication"`, `"authorization"`, `"not_found"`, `"conflict"`, `"precondition"`, `"quota"`, `"rate_limit"`, `"upstream"`, `"internal"`
- `markSubmission.response.500.detail` (string, required)
- `markSubmission.response.500.request_id` (string, required)
- `markSubmission.response.500.docs_url` (string, required)
  - format `uri`
- `markSubmission.response.500.errors` (array<object>, optional)
  - `markSubmission.response.500.errors.path` (string, required) — RFC 6901 JSON Pointer into the request body.
  - `markSubmission.response.500.errors.code` (string, required)
  - `markSubmission.response.500.errors.detail` (string, required)
- `markSubmission.response.500.retry_after` (integer | null, optional)


Source: https://docs.quirelms.com/api/submissions/markSubmission/index.md
