Assessments
Assessments are the core building block of Gradient. Each assessment defines a task, time limits, available data sources, and a scoring rubric.List Assessments
integer
default:"20"
Results per page (1-100)
integer
default:"0"
Offset for pagination
boolean
Filter by active status
Response
Response
Get Assessment
Response
Response
orgBranding is null when the org row can’t be loaded.Update Assessment
name, role, roleId, is_active, jd_link, due_date, send_feedback, feedback_delay_hours, timer_mode, pause_between_phases. Any org member or API key can change these.
Content fields: task_prompt, phases, scoring_rubric, connector_config, candidate_permissions, admin_guide, task_outline, setup_time_minutes, task_time_minutes, bonus_phase_enabled, bonus_phase_minutes. Only Gradient staff can change these. If a request from another caller includes a content field, the API returns 403 and changes nothing. To change the content of an assessment, contact hi@trygradient.ai.
Role
roleId is the id of an existing roles row to link (Plan 54’s Settings-tab role picker). When provided, the server resolves the role’s title and writes it to the denormalized role string, then reconciles the assessment_roles join table (unlinking whatever was previously linked, linking the new pick) — mirroring the sequence assessment creation already uses (insert with role.title, then a separate link call). role remains independently settable as a raw string for callers that don’t use the picker; sending both role and roleId in the same request lets roleId’s resolved title win. An unknown or soft-deleted roleId returns a not_found error rather than silently no-op-ing.
send_feedback and feedback_delay_hours are still accepted for backward compatibility but are inert — automated candidate feedback is not currently delivered.Candidate Permissions
Thecandidate_permissions field is a JSON object controlling what candidates can do during the assessment:
can_browse_connector_documents is deprecated. Candidates always see connector data files in the workspace Files cabinet, so the key has no effect and the admin UI no longer shows it. The API still accepts and returns it, and stored values are unchanged.can_use_scratchpad is off by default and no longer a toggle in the admin UI. It is also forced off for every v7 session (v7 scores the deliverable only), so GET /api/assessments/:id returns it as false for a v7 org even if a stored value says true. The stored value itself is not changed.Response
Response
Reviewer Documents
403 — the answer-key document would expose the grading key.
string
required
brief returns the candidate-facing task brief; key returns the answer key (what strong sessions do, watchouts, the “if they get it wrong” notes, and the sample strong session).string
required
The phase id, as it appears in the assessment’s
phases array (or reflection). Numbering follows the Reviewer Guide, so the ungraded Explore warm-up is excluded..docx with Content-Disposition: attachment; the filename leads with the assessment name and phase. A phase/kind pair with no content (for example a phase whose answer key has not been generated) returns 404.
Delete Assessment
deleted_at timestamp). This is the everyday delete, and it is reversible with Restore Assessment. The assessment no longer appears in the admin lists, but all sessions, scores, connector data, and files stay intact. In-flight sessions and scoring keep working, because by-id reads do not filter soft-deleted assessments. Requires owner or admin. To erase the data permanently, use Purge Assessment.
Response
Response
Restore Assessment
deleted_at). Requires owner or admin, the same as delete.
Response
Response
Purge Assessment
assessments.purge). API-key callers have no role and are refused: a machine credential cannot trigger an irreversible erasure.
Response
Response
Invite Candidate
sendEmail is false.
string
required
Candidate’s email address
string
required
Candidate’s display name
string
ISO 8601 per-candidate deadline (overrides assessment-level deadline)
boolean
default:"true"
When
false, Gradient does not send its default invitation email — the caller is expected to deliver a custom email using the returned inviteUrl. Only affects newly-created sessions; idempotent hits on an existing session never re-send (use POST /api/assessments/:id/invite/resend instead).Response - 201 Created (new session)
Response - 201 Created (new session)
200 OK:
Response - 200 OK (existing session)
Response - 200 OK (existing session)
Batch Invite Candidates
POST /api/assessments/:id/invite: creates/re-uses a candidate and session for each {name, email} pair in one request, instead of one HTTP round trip per candidate. Each row is processed independently — one row failing (e.g. a bad email) doesn’t stop the rest — and the response reports a per-row outcome in the same order as the request.
array
required
Array of
{ name: string, email: string, dueDate?: string }. Max 500 per request; larger pastes should be split client-side.boolean
default:"false"
Same semantics as the single-invite endpoint, applied to every row.
Response - 200 OK
Response - 200 OK
Resend Invite Email
string
required
The session ID to resend the invite for
Response
Response
Export Invited Candidates (CSV)
Content-Type: text/csv, Content-Disposition: attachment). Every row is one session; every row has every column, blank where a column doesn’t apply to that row. Timestamps render as YYYY-MM-DD HH:mm in the org’s time zone (Excel/Sheets parse this as a datetime). Org-scoped; admin or API-key auth.
Columns, in order:
- Fixed:
name, email, link, status, test_candidate, invited_at, started_at, submitted_at, due_at, timezone, time_taken_minutes, scored_at, score, level, feedback_state, feedback_sent_at, flag_count, flags.linkis the candidate’s absolute/assess/:tokenURL;test_candidateistrue/false(email matches a test/internal pattern, same rule as Billing);levelis the overall band word that the candidate page shows next to the score (Strong,Proficient,Developing,Limited, orNot attempted), blank when the session has no score;feedback_stateisnot_scored,not_sent, orsent.flag_countis the number of integrity flags on the score (blank when the session has no score).flagshas one line per flag, in the form<label>: <detail>, with the same label and sentence that the candidate page shows. The auditevidencestring is not included. - Human review (only when the org requires human review, or a session in the export has a recorded decision):
review_status, review_note, reviewed_at, reviewed_by, afterflags.review_statusisNeeds review,Moving on, orNot moving on, and is blank for a session that is not submitted.reviewed_byis the reviewer’s name, and is blank for an API key or a removed member. - Category levels (blank on an unscored session):
work_quality_level, ai_fluency_level. Each is the level word that the candidate page shows for that category (Advanced,Proficient,Developing,Emerging, orNot Shown), and includes reviewer overrides. - v7 numeric sub-scores (blank on a v5/v6 or unscored session):
work_quality_score, setup_score, direction_score, judgment_score, mindset_score— each0-100. - v7 report content (blank on a v5/v6 or unscored session): for each of
setup, direction, judgment, mindset—<axis>_level(the band word, e.g.Advanced),<axis>_what_happened,<axis>_next_time; then for each scored output, in phase order —output_<n>_name, output_<n>_level, output_<n>_what_happened, output_<n>_next_time(nruns1..N, whereNis the most outputs any session in this export has scored — a session with fewer leaves the rest blank); thenfeedback_verdict. - Priority Skills evidence: one
priority_<skill>_evidencecolumn per distinct Priority Skill name on this assessment’s rubric, alphabetical (<skill>is the name, lowercased with non-alphanumerics collapsed to_). Each cell is that skill’s trap outcomes and cited examples, one per line — blank when the skill wasn’t scored evidence-only or the session predates it.
Response - 200 OK (text/csv)
Response - 200 OK (text/csv)