curl --request GET \
--url https://app.dotportion.com/api/v1/submissions \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.dotportion.com/api/v1/submissions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://app.dotportion.com/api/v1/submissions"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text){
"data": [
{
"id": "00000000-0000-4000-8000-000000000031",
"assessment_id": "00000000-0000-4000-8000-000000000011",
"challenge": {
"name": "LRU Cache",
"slug": "lru-cache"
},
"candidate": {
"email": "katherine@example.com",
"name": "Katherine Johnson"
},
"status": "evaluated",
"started_at": "2026-01-15T12:00:00.000Z",
"submitted_at": "2026-01-15T12:00:00.000Z",
"evaluated_at": "2026-01-15T12:00:00.000Z",
"paused_total_seconds": 120,
"budget": {
"dollars_used": 1.25,
"dollars_cap": 3
},
"created_at": "2026-01-15T12:00:00.000Z"
},
{
"id": "00000000-0000-4000-8000-000000000032",
"assessment_id": "00000000-0000-4000-8000-000000000011",
"challenge": {
"name": "LRU Cache",
"slug": "lru-cache"
},
"candidate": {
"email": "alan@example.com",
"name": "Alan Turing"
},
"status": "in_progress",
"started_at": "2026-01-15T12:00:00.000Z",
"submitted_at": null,
"evaluated_at": null,
"paused_total_seconds": 0,
"budget": {
"dollars_used": 0.4,
"dollars_cap": 3
},
"created_at": "2026-01-15T12:00:00.000Z"
},
{
"id": "00000000-0000-4000-8000-000000000033",
"assessment_id": "00000000-0000-4000-8000-000000000011",
"challenge": {
"name": "LRU Cache",
"slug": "lru-cache"
},
"candidate": {
"email": "grace@example.com",
"name": "Grace Hopper"
},
"status": "submitted",
"started_at": "2026-01-15T12:00:00.000Z",
"submitted_at": "2026-01-15T12:00:00.000Z",
"evaluated_at": null,
"paused_total_seconds": 0,
"budget": {
"dollars_used": 2.1,
"dollars_cap": 3
},
"created_at": "2026-01-15T12:00:00.000Z"
}
],
"meta": {
"request_id": "req_4f2a9c1e8b7d4a5f9e3c2b1a8d7f6e5c",
"next_cursor": null,
"has_more": false
}
}{
"error": {
"code": "INVALID_INPUT",
"message": "Invalid request",
"details": {
"formErrors": [],
"fieldErrors": {
"name": [
"String must contain at least 1 character(s)"
]
}
},
"request_id": "req_4f2a9c1e8b7d4a5f9e3c2b1a8d7f6e5c"
}
}{
"error": {
"code": "INVALID_TOKEN",
"message": "Invalid or revoked API key",
"request_id": "req_4f2a9c1e8b7d4a5f9e3c2b1a8d7f6e5c"
}
}{
"error": {
"code": "INSUFFICIENT_SCOPE",
"message": "This API key lacks the required scope: write.",
"request_id": "req_4f2a9c1e8b7d4a5f9e3c2b1a8d7f6e5c"
}
}{
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded for write requests (200/hour). Retry after 2026-01-15T13:00:00.000Z.",
"details": {
"limit": 200,
"remaining": 0,
"reset": 1768482000
},
"request_id": "req_4f2a9c1e8b7d4a5f9e3c2b1a8d7f6e5c"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "Internal server error",
"request_id": "req_4f2a9c1e8b7d4a5f9e3c2b1a8d7f6e5c"
}
}List submissions
Candidate submissions across your assessments, newest first. CURSOR-paginated, because this collection grows without bound.
Walk the collection by following meta.next_cursor until it comes back null. Never build a cursor yourself — the encoding is ours to change.
Note the status vocabulary: there is no completed. A graded submission is evaluated.
curl --request GET \
--url https://app.dotportion.com/api/v1/submissions \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.dotportion.com/api/v1/submissions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://app.dotportion.com/api/v1/submissions"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text){
"data": [
{
"id": "00000000-0000-4000-8000-000000000031",
"assessment_id": "00000000-0000-4000-8000-000000000011",
"challenge": {
"name": "LRU Cache",
"slug": "lru-cache"
},
"candidate": {
"email": "katherine@example.com",
"name": "Katherine Johnson"
},
"status": "evaluated",
"started_at": "2026-01-15T12:00:00.000Z",
"submitted_at": "2026-01-15T12:00:00.000Z",
"evaluated_at": "2026-01-15T12:00:00.000Z",
"paused_total_seconds": 120,
"budget": {
"dollars_used": 1.25,
"dollars_cap": 3
},
"created_at": "2026-01-15T12:00:00.000Z"
},
{
"id": "00000000-0000-4000-8000-000000000032",
"assessment_id": "00000000-0000-4000-8000-000000000011",
"challenge": {
"name": "LRU Cache",
"slug": "lru-cache"
},
"candidate": {
"email": "alan@example.com",
"name": "Alan Turing"
},
"status": "in_progress",
"started_at": "2026-01-15T12:00:00.000Z",
"submitted_at": null,
"evaluated_at": null,
"paused_total_seconds": 0,
"budget": {
"dollars_used": 0.4,
"dollars_cap": 3
},
"created_at": "2026-01-15T12:00:00.000Z"
},
{
"id": "00000000-0000-4000-8000-000000000033",
"assessment_id": "00000000-0000-4000-8000-000000000011",
"challenge": {
"name": "LRU Cache",
"slug": "lru-cache"
},
"candidate": {
"email": "grace@example.com",
"name": "Grace Hopper"
},
"status": "submitted",
"started_at": "2026-01-15T12:00:00.000Z",
"submitted_at": "2026-01-15T12:00:00.000Z",
"evaluated_at": null,
"paused_total_seconds": 0,
"budget": {
"dollars_used": 2.1,
"dollars_cap": 3
},
"created_at": "2026-01-15T12:00:00.000Z"
}
],
"meta": {
"request_id": "req_4f2a9c1e8b7d4a5f9e3c2b1a8d7f6e5c",
"next_cursor": null,
"has_more": false
}
}{
"error": {
"code": "INVALID_INPUT",
"message": "Invalid request",
"details": {
"formErrors": [],
"fieldErrors": {
"name": [
"String must contain at least 1 character(s)"
]
}
},
"request_id": "req_4f2a9c1e8b7d4a5f9e3c2b1a8d7f6e5c"
}
}{
"error": {
"code": "INVALID_TOKEN",
"message": "Invalid or revoked API key",
"request_id": "req_4f2a9c1e8b7d4a5f9e3c2b1a8d7f6e5c"
}
}{
"error": {
"code": "INSUFFICIENT_SCOPE",
"message": "This API key lacks the required scope: write.",
"request_id": "req_4f2a9c1e8b7d4a5f9e3c2b1a8d7f6e5c"
}
}{
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded for write requests (200/hour). Retry after 2026-01-15T13:00:00.000Z.",
"details": {
"limit": 200,
"remaining": 0,
"reset": 1768482000
},
"request_id": "req_4f2a9c1e8b7d4a5f9e3c2b1a8d7f6e5c"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "Internal server error",
"request_id": "req_4f2a9c1e8b7d4a5f9e3c2b1a8d7f6e5c"
}
}Authorizations
Your API key, live (sk_live_…) or test (sk_test_…). Create one in Settings → API keys. Send it as Authorization: Bearer <key> — never in a query string.
Query Parameters
Only this assessment.
Only this candidate.
Restrict to one submission status. Note there is no completed — a graded submission is evaluated.
initialized, in_progress, paused, submitted, evaluating, evaluated, expired, failed ISO-8601 lower bound on created_at.
ISO-8601 upper bound on created_at.
From a previous meta.next_cursor. Opaque.
Items per page, max 100.
Was this page helpful?