Skillflare
API

Sessions

List, get, create, and control assessment sessions

A session is one assessment attempt. Auth: organization API key.

Only for partner customers. Pass the active organization with the optional x-organization-id header. Omit it to use the organization that owns the API key. A partner key may pass a direct child. An unknown organization returns 404. An organization the key cannot access returns 403. A non-empty organization_id query or body field returns 400 VALIDATION_ERROR.

MethodPathSummary
GET/v1/sessionsList sessions
GET/v1/sessions/:idGet one session by UUID
POST/v1/sessionsCreate a session

Session status

session_status is the lifecycle of one attempt. Poll GET /v1/sessions/:id until it is COMPLETED, FAILED, DROPPED_OUT, or EXPIRED.

StatusMeaning
PENDINGCreated. The environment is not ready yet.
PROVISIONINGCompute is starting.
READYThe lobby is ready. Recording has not started.
DROPPED_OUTThe candidate clicked "I am ready" and never began recording within 30 minutes. A container sandbox is destroyed. No evaluation runs and no session webhooks fire.
EXPIREDStill PENDING when expires_at passed. The lobby link is already closed at expires_at. A minute cron writes this status. No evaluation runs and no session webhooks fire.
RECORDINGThe candidate is in the assessment. recording_started_at is set. Webhooks: SESSION.STARTED on entry, SESSION.STOPPED on exit.
STORING_INPUT_EVENTSRecording stopped. Input events are being stored (container and VM sessions).
CONVERTING_VIDEOThe recording is being converted.
GENERATING_NARRATIVEThe narrative is being written (container and VM sessions).
GENERATING_EVALUATIONAn evaluation set is running. EVALUATION_SET.STARTED fires when latest_evaluation_set_id is set.
COMPLETEDThe attempt finished. latest_evaluation_set is present when automatic evaluation ran, and null when the organization scores later. EVALUATION_SET.STOPPED fires only when status becomes COMPLETED and a set id is set.
FAILEDProvisioning or evaluation failed.

Local sessions skip STORING_INPUT_EVENTS and GENERATING_NARRATIVE: they go from RECORDING to CONVERTING_VIDEO, then to GENERATING_EVALUATION or straight to COMPLETED.

Older sessions may still report SAVING, WAITING_FOR_EVALUATION, or CANCELLED from an earlier pipeline.

lobby_url uses the organization's active vanity domain when one is configured, including a domain inherited from a parent organization, and otherwise uses the default Skillflare origin.

List

curl "https://api.skillflare.co/v1/sessions?limit=20&offset=0" \
  -H "x-api-key: sk_skillflare_YOUR_KEY" \
  -H "x-organization-id: CHILD_ORG_UUID"

Returns { data, meta } as described in Errors and pagination. Each item:

{
  "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
  "created_at": "2026-01-15T12:00:00.000Z",
  "session_status": "PENDING",
  "candidate_full_name": "Alex Example",
  "candidate_email": "alex@example.com",
  "candidate_meta": { "external_id": "ats-123" },
  "lobby_url": "https://skillflare.co/sessions/b2c3d4e5-f6a7-8901-bcde-f12345678901/lobby?t=...",
  "expires_at": null
}
  • id — session UUID (use this in path params).
  • created_at — when the session was created (ISO 8601).
  • session_status — current session status.
  • candidate_full_name — candidate display name, or null if unknown.
  • candidate_email — candidate email, or null if unknown.
  • candidate_meta — opaque partner metadata from create-candidate meta, or {} when unset. Same value webhooks send as candidate_meta.
  • lobby_url — candidate link to open the session lobby, or null.
  • expires_at — when the lobby link stops working (ISO 8601), or null when the link does not expire. After this time the candidate lobby returns 403 SESSION_LINK_EXPIRED. List and get still return the session.

Get by id

curl https://api.skillflare.co/v1/sessions/b2c3d4e5-f6a7-8901-bcde-f12345678901 \
  -H "x-api-key: sk_skillflare_YOUR_KEY" \
  -H "x-organization-id: CHILD_ORG_UUID"

A session that belongs to another organization is NOT_FOUND.

Returns the session at the top level. Detail adds publish and recording fields, the latest evaluation set, and a signed URL for the canonical evaluation file:

{
  "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
  "created_at": "2026-01-15T12:00:00.000Z",
  "session_status": "COMPLETED",
  "candidate_full_name": "Alex Example",
  "candidate_email": "alex@example.com",
  "candidate_meta": { "external_id": "ats-123" },
  "lobby_url": "https://skillflare.co/sessions/b2c3d4e5-f6a7-8901-bcde-f12345678901/lobby?t=...",
  "expires_at": "2026-02-01T23:59:59.999Z",
  "published_at": null,
  "recording_started_at": "2026-01-15T12:06:00.000Z",
  "latest_evaluation_set": {
    "id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
    "created_at": "2026-01-15T13:00:00.000Z",
    "total_score_avg": 0,
    "total_score_min": 0,
    "total_score_max": 0,
    "score_confidence": 1,
    "evaluations": [
      {
        "id": "d4e5f6a7-b8c9-0123-def0-234567890123",
        "total_score": 0,
        "evaluation_status": "COMPLETED",
        "evaluation_error": null,
        "scores": [{ "title": "Discovery", "points": 0, "max_points": 0 }]
      }
    ]
  },
  "url": "https://sessions.example/signed-recording",
  "evaluation_url": "https://evaluations.example/signed-evaluation.json"
}
  • id — session UUID (use this in path params).
  • created_at — when the session was created (ISO 8601).
  • session_status — current session status.
  • candidate_full_name — candidate display name, or null if unknown.
  • candidate_email — candidate email, or null if unknown.
  • candidate_meta — opaque partner metadata from create-candidate meta, or {} when unset. Same value webhooks send as candidate_meta.
  • lobby_url — candidate link to open the session lobby, or null.
  • expires_at — when the lobby link stops working (ISO 8601), or null when the link does not expire.
  • published_at — when the candidate published the session, or null.
  • recording_started_at — when recording began, or null.
  • latest_evaluation_set — latest evaluation set with aggregates and member evaluations, or null. Point totals on this object are the set aggregates. They are not re-read from the evaluation file.
  • url — signed URL for the session recording, or null when it cannot be signed.
  • evaluation_url — signed GET URL for the canonical evaluation's evaluation.json, or null when no completed member exists or the URL cannot be signed. The link expires after one hour. Fetch it separately. The file stays in object storage and is not copied into the database. A low score_confidence still includes this URL when a canonical file exists.

Member evaluation_status is PREPARING, COMPLETED, FAILED, or FURTHER_REVIEW. FURTHER_REVIEW is set on completed member evaluations when the set reaches its grader cap without a cluster (score_confidence is 0).

Invalid UUIDs → VALIDATION_ERROR. Missing session → NOT_FOUND.

Create

Creates a session for a candidate on a challenge.

curl https://api.skillflare.co/v1/sessions \
  -H "x-api-key: sk_skillflare_YOUR_KEY" \
  -H "x-organization-id: CHILD_ORG_UUID" \
  -H "content-type: application/json" \
  -d '{
    "candidate_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "challenge_id": "e5f6a7b8-c9d0-1234-ef01-345678901234",
    "expires_at": "2027-02-01T23:59:59.999Z"
  }'
FieldRequiredNotes
candidate_idYesCandidates resource id, linked to the active organization. Missing → candidate_id is required. Not a UUID → candidate_id must be a uuid. Unknown or outside the org → 404 Candidate does not exist
challenge_idYesA challenge the active organization can access. Missing → challenge_id is required. Not a UUID → challenge_id must be a uuid. Unknown or inaccessible → 404 Challenge does not exist
expires_atNoISO 8601 timestamp. Omit, null, or "" for a lobby link that does not expire. Not a timestamp → 400 expires_at must be an ISO 8601 timestamp. At or before now → 400 expires_at must be in the future

The challenge status must be READY, WARMING_UP, or PREPARING. Any other status returns 400 VALIDATION_ERROR with message Challenge must be READY before creating a session. A CONTAINER challenge also needs a packaged image: Challenge has no packaged image; finish packaging first when the image is missing, and Challenge image has no E2B template when the image has no template.

Success: 201 with:

{
  "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
  "invite_sent": true,
  "lobby_url": "https://skillflare.co/sessions/b2c3d4e5-f6a7-8901-bcde-f12345678901/lobby?t=...",
  "expires_at": "2027-02-01T23:59:59.999Z"
}
  • id — session UUID.
  • invite_sent — true when an invite email was queued for the candidate. The email uses the active organization's name and branding. See Where branding is applied.
  • lobby_url — candidate link to open the session lobby.
  • expires_at — the stored deadline, or null when the link does not expire.

After expires_at, opening the lobby link returns 403 SESSION_LINK_EXPIRED with message This assessment link has expired. The candidate sees an Expired screen. A minute cron then sets session_status to EXPIRED when the session is still PENDING. List and get still return the session.

A missing session, a session outside the key's organization, or a session with no VM returns 404 Session does not exist.

On this page