- What is TestInvite?
- Build Your First Test
- Run Your First Assessment
- Taking the Assessment
- Viewing the Results
- Question Bank Overview
- Common Question Features
- Scoring
- Question Types
- Question Authoring
- Browsing Questions
- Content Blocks
- Media Library
- Metadata Rules & Schema
- Roles & Access
- Tests Overview
- My Tests
- Creating a Test
- The Test Editor
- Test Settings
- Sections & Pages
- Adding Questions
- Page Builders
- Test Profile
- Reporting
- Test Papers
- Analytics
- Publishing a Test
- Test Library
- Marketplace
- Tasks Overview
- Creating a Task
- Task Dashboard
- Steps
- Task Settings
- Candidates
- Test Sessions
- Sent Mails
- Proctoring
- Analytics
- Analytics Overview
- Test Analytics
- Question Analytics
- Per-Question Analytics
- Results Explorer
- Segment Analysis
Candidates
Create, list, fetch, update, and delete Candidates under a Task through the REST API — the only resource with full write access, since registering candidates is the core integration use case.
Candidates are always scoped to one Task — every endpoint below is under /tasks/:taskId/candidates. Requires List tickets to read, Write tickets to create/update/delete. This is the only resource with full write access through the REST API — registering a candidate is the core use case most integrations exist for.
Basic vs. Detailed
- basic —
candidateId, kind ("user"|"temp"), taskId, loggedIn, fullname, email, invitationCode, directAccessUrl(nullfor internal/user candidates). - detailed — adds
organizationId, source ("self-registration"|"pre-registration"), active, activeAfter, activeBefore, group, tags, labels, rating (1–5 or null), stage.
List, Fetch
GET /tasks/:taskId/candidates— query params:mode, limit, page, fullname, email, code. These three filters are exact, case-sensitive matches — unlike Users'usernamefilter, which is partial and case-insensitive.GET /tasks/:taskId/candidates/:id— query param:mode.
Create
POST /tasks/:taskId/candidates — body is one of two kinds:
kind: "temporary-candidate"— a candidate that only exists for this task:fullname, email, credential1, credential2(whichever the task's access method needs), plus optionaltracking: { uniqId }for your own external reference.kind: "internal-candidate"— registers an existing org User as a candidate on this task: justid(the user ID). Fullname and email are copied from the user; the user's username becomes both the candidate'suniqIdand their login credential, so the same user can never be added to the same task twice.
Both kinds also accept: group, labels, tags, externalId, externalData, programIds, extraEmails, dates: { before?, after? }, price: { amount, currency }, customizedSteps: [{ stepId, customization: { activeAfter?, activeBefore? } }], inviteByEmail: { emailTemplateName, dateToSend? }, callback: { url, params?, resource }. See Webhooks & Callbacks for how callback and inviteByEmail work.
Returns the basic candidate object, with loggedIn: false.
Update (Beta)
PATCH /tasks/:taskId/candidates/:id — body:
fields— any offullname, email, group, favorite, active, activeAfter, activeBefore, pluslabels: { add?, remove? }.steps— optional, keyed by step ID, each ofactive,dates, andlimitset to either{ isDefault: true }(use the task's own setting for this candidate) or{ isDefault: false, value: ... }(override it). Fordates, the value is{ after?, before? }; omit a field to leave it unchanged, or set it tonullto remove that restriction. Forlimit,-1means unlimited attempts.
Returns the full detailed candidate object.
Delete
DELETE /tasks/:taskId/candidates/:id — no body. Only allowed if the candidate has never logged in — not via direct link, invitation code, or credentials — and has no test sessions, ongoing or completed. Returns 403 Forbidden if either condition isn't met, and an empty object on success.