Get result for an invitation
curl --request GET \
--url https://assess.praxicraft.com/api/v1/public/invites/{token}/result/ \
--header 'Authorization: Bearer <token>'import requests
url = "https://assess.praxicraft.com/api/v1/public/invites/{token}/result/"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://assess.praxicraft.com/api/v1/public/invites/{token}/result/', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));const url = 'https://assess.praxicraft.com/api/v1/public/invites/{token}/result/';
const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://assess.praxicraft.com/api/v1/public/invites/{token}/result/"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"candidate_email": "[email protected]",
"candidate_name": "Jane Doe",
"assessment": "Senior Backend Engineer Screen",
"status": "completed",
"started_at": "2025-03-15T14:00:00Z",
"completed_at": "2025-03-15T15:21:00Z",
"score": 255,
"max_score": 300,
"score_percentage": 85,
"passed": true,
"passing_score": 70,
"violation_counts": {
"fullscreen_violations": 0,
"copy_paste_violations": 1,
"screen_share_violations": 0,
"webcam_violations": 0,
"focus_loss_violations": 2,
"total_violations": 3
},
"integrity_review_status": null,
"violation_events": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"violation_type": "copy_paste",
"task_order": 2,
"created_at": "2025-03-15T14:45:00Z"
}
],
"detailed_report_url": "https://assess.praxicraft.com/api/v1/assess/assessments/senior-backend-screen/results/e1f2a3b4/",
"tasks": [
{
"task_order": 1,
"task_title": "SQL Fundamentals",
"score": 90,
"max_score": 100,
"status": "correct",
"time_spent_seconds": 1200
}
]
}Public API — Results
Get result for an invitation
Required scope:
candidates:read
Returns the scored result for a candidate invitation. If the candidate has not started, returns HTTP 200 with { status, message } only. When completed, includes violation_events, per-task tasks[], and detailed_report_url.
Responses
| Status | When |
|---|---|
200 | Full result or not-started message (status + message only) |
404 | Invitation token not found |
Authentication & rate limits (all endpoints)
| Status | Code | When |
|---|---|---|
401 | INVALID_API_KEY | Missing or invalid bearer token |
401 | EXPIRED_API_KEY | API key past its optional expires_at |
403 | INSUFFICIENT_SCOPE | API key lacks the required scope for this operation |
403 | IP_NOT_ALLOWED | Client IP is outside this key’s CIDR allowlist |
429 | RATE_LIMITED | Rate limit exceeded — plan-tiered reads/writes per organisation per hour |
GET
/
api
/
v1
/
public
/
invites
/
{token}
/
result
/
Get result for an invitation
curl --request GET \
--url https://assess.praxicraft.com/api/v1/public/invites/{token}/result/ \
--header 'Authorization: Bearer <token>'import requests
url = "https://assess.praxicraft.com/api/v1/public/invites/{token}/result/"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://assess.praxicraft.com/api/v1/public/invites/{token}/result/', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));const url = 'https://assess.praxicraft.com/api/v1/public/invites/{token}/result/';
const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://assess.praxicraft.com/api/v1/public/invites/{token}/result/"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"candidate_email": "[email protected]",
"candidate_name": "Jane Doe",
"assessment": "Senior Backend Engineer Screen",
"status": "completed",
"started_at": "2025-03-15T14:00:00Z",
"completed_at": "2025-03-15T15:21:00Z",
"score": 255,
"max_score": 300,
"score_percentage": 85,
"passed": true,
"passing_score": 70,
"violation_counts": {
"fullscreen_violations": 0,
"copy_paste_violations": 1,
"screen_share_violations": 0,
"webcam_violations": 0,
"focus_loss_violations": 2,
"total_violations": 3
},
"integrity_review_status": null,
"violation_events": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"violation_type": "copy_paste",
"task_order": 2,
"created_at": "2025-03-15T14:45:00Z"
}
],
"detailed_report_url": "https://assess.praxicraft.com/api/v1/assess/assessments/senior-backend-screen/results/e1f2a3b4/",
"tasks": [
{
"task_order": 1,
"task_title": "SQL Fundamentals",
"score": 90,
"max_score": 100,
"status": "correct",
"time_spent_seconds": 1200
}
]
}Authorizations
Organisation API key created in Assess → Developer → API Keys. Format: Bearer ct_live_<your-key> (live) or Bearer ct_test_<your-key> (test). Optional per-key CIDR allowlists return 403 IP_NOT_ALLOWED.
Path Parameters
Response
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Last modified on September 5, 2026