Retrieve a challenge
curl --request GET \
--url https://app.dotportion.com/api/v1/challenges/{id} \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.dotportion.com/api/v1/challenges/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://app.dotportion.com/api/v1/challenges/{id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text){
"data": {
"id": "00000000-0000-4000-8000-000000000002",
"slug": "spell-cooldown-arbiter",
"name": "Spell Cooldown Arbiter",
"domain": "backend",
"difficulty": "hard",
"level": "senior",
"stack": "node",
"time_limit_minutes": 180,
"budget_dollars_cap": 6,
"is_platform": true,
"is_multi_task": true,
"published_at": "2026-01-15T12:00:00.000Z",
"created_at": "2026-01-15T12:00:00.000Z",
"brief_md": "# Brief\n\nSee the challenge repository for the full task description.",
"tasks": [
{
"id": "00000000-0000-4000-8000-000000000051",
"task_key": "T1",
"kind": "bug",
"title": "Fix the cooldown race",
"order_index": 0,
"weight": 0.3333,
"time_limit_minutes": 60
},
{
"id": "00000000-0000-4000-8000-000000000052",
"task_key": "T2",
"kind": "feature",
"title": "Add mana reservation",
"order_index": 1,
"weight": 0.3333,
"time_limit_minutes": 60
},
{
"id": "00000000-0000-4000-8000-000000000053",
"task_key": "T3",
"kind": "efficiency",
"title": "Speed up the arbiter hot path",
"order_index": 2,
"weight": 0.3333,
"time_limit_minutes": 60
}
]
},
"meta": {
"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": "NOT_FOUND",
"message": "Resource not found",
"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"
}
}Challenges
Retrieve a challenge
Full metadata including the candidate-facing brief. Multi-task challenges also return their task list.
GET
/
api
/
v1
/
challenges
/
{id}
Retrieve a challenge
curl --request GET \
--url https://app.dotportion.com/api/v1/challenges/{id} \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.dotportion.com/api/v1/challenges/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://app.dotportion.com/api/v1/challenges/{id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text){
"data": {
"id": "00000000-0000-4000-8000-000000000002",
"slug": "spell-cooldown-arbiter",
"name": "Spell Cooldown Arbiter",
"domain": "backend",
"difficulty": "hard",
"level": "senior",
"stack": "node",
"time_limit_minutes": 180,
"budget_dollars_cap": 6,
"is_platform": true,
"is_multi_task": true,
"published_at": "2026-01-15T12:00:00.000Z",
"created_at": "2026-01-15T12:00:00.000Z",
"brief_md": "# Brief\n\nSee the challenge repository for the full task description.",
"tasks": [
{
"id": "00000000-0000-4000-8000-000000000051",
"task_key": "T1",
"kind": "bug",
"title": "Fix the cooldown race",
"order_index": 0,
"weight": 0.3333,
"time_limit_minutes": 60
},
{
"id": "00000000-0000-4000-8000-000000000052",
"task_key": "T2",
"kind": "feature",
"title": "Add mana reservation",
"order_index": 1,
"weight": 0.3333,
"time_limit_minutes": 60
},
{
"id": "00000000-0000-4000-8000-000000000053",
"task_key": "T3",
"kind": "efficiency",
"title": "Speed up the arbiter hot path",
"order_index": 2,
"weight": 0.3333,
"time_limit_minutes": 60
}
]
},
"meta": {
"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": "NOT_FOUND",
"message": "Resource not found",
"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.
Path Parameters
The challenge id.
Was this page helpful?