Get Attempt
GET /v1/nextexams/attempts/{id}
Get an attempt
The attempt with every response, how it was graded, and its integrity signals. Scope attempts:read.
Request
GET https://your-site.example/api/index.php/v1/nextexams/attempts/{id}
Parameters
| Name | Type | In | Required | Description |
|---|---|---|---|---|
id |
integer |
path |
Yes | The record's id. (min 1) |
Responses
200 — The attempt.
{
"data": {
"id": 1,
"exam_id": 1,
"exam_title": "string",
"user_id": 1,
"user_name": "string",
"guest_name": "string",
"guest_email": "string",
"attempt_number": 1,
"status": "in_progress",
"started": "2026-01-01T12:00:00Z",
"submitted": "2026-01-01T12:00:00Z",
"expires_at": "2026-01-01T12:00:00Z",
"time_spent": 1,
"score": 1.5,
"max_score": 1.5,
"percent": 1.5,
"passed": true,
"is_graded": true,
"integrity_signals": {},
"grader_comment": "string",
"responses": [
{
"id": 1,
"question_id": 1,
"question_type": "string",
"question_title": "string",
"response": "string",
"is_correct": true,
"points_awarded": 1.5,
"points_possible": 1.5,
"auto_graded": true,
"grader_comment": "string",
"graded_at": "2026-01-01T12:00:00Z"
}
]
}
}
| Field | Type | Meaning |
|---|---|---|
data.id |
integer |
|
data.exam_id |
integer |
|
data.exam_title |
string|null |
|
data.user_id |
integer|null |
|
data.user_name |
string|null |
|
data.guest_name |
string|null |
|
data.guest_email |
string|null |
|
data.attempt_number |
integer |
|
data.status |
string |
One of in_progress, submitted, graded, locked_review, abandoned. |
data.started |
string|null |
ISO 8601 in UTC, or null when not set. (date-time) |
data.submitted |
string|null |
ISO 8601 in UTC, or null when not set. (date-time) |
data.expires_at |
string|null |
ISO 8601 in UTC, or null when not set. (date-time) |
data.time_spent |
integer|null |
|
data.score |
number|null |
|
data.max_score |
number|null |
|
data.percent |
number|null |
|
data.passed |
boolean|null |
|
data.is_graded |
boolean |
|
data.integrity_signals |
object|null |
Detection-only counters (focus losses, pastes, tab switches, fullscreen exits, per-question timings). Never a verdict on their own. |
data.grader_comment |
string|null |
|
data.responses[].id |
integer |
|
data.responses[].question_id |
integer |
|
data.responses[].question_type |
string |
|
data.responses[].question_title |
string|null |
|
data.responses[].response |
object |
What the examinee answered, in the question type's own shape; null when unanswered. |
data.responses[].is_correct |
boolean|null |
|
data.responses[].points_awarded |
number|null |
|
data.responses[].points_possible |
number|null |
|
data.responses[].auto_graded |
boolean |
|
data.responses[].grader_comment |
string|null |
|
data.responses[].graded_at |
string|null |
ISO 8601 in UTC, or null when not set. (date-time) |
Errors
| Status | Code | When |
|---|---|---|
401 |
INVALID_TOKEN |
No token (MISSING_TOKEN), or one that is wrong, expired, revoked, or whose owner can no longer sign in (INVALID_TOKEN). |
403 |
MISSING_SCOPE |
The token is valid but this request is not allowed, and code says why: MISSING_SCOPE (the token lacks the scope), FORBIDDEN (the owner's role does not allow it), ACCESS_DENIED (the owner cannot manage Next Exams), API_DISABLED (the API Tokens app is off), APP_DISABLED (the feature's app is off — meta.app names it), ACCOUNT_UNUSABLE (the owner is blocked or must reset their password), DEMO_LOCKED (a demo site). |
404 |
NOT_FOUND |
No record has this id. |
Examples
curl
curl -s "https://your-site.example/api/index.php/v1/nextexams/attempts/1" \
-H "Authorization: Bearer $API_TOKEN"
PHP
<?php
$ch = curl_init('https://your-site.example/api/index.php/v1/nextexams/attempts/1');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('API_TOKEN'),
],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
JavaScript
const API_TOKEN = process.env.API_TOKEN;
const response = await fetch("https://your-site.example/api/index.php/v1/nextexams/attempts/1", {
headers: {
"Authorization": `Bearer ${API_TOKEN}`,
},
});
const data = await response.json();