Skip to main content
A session represents one AI interview โ€” the conversation, the recording, the transcript, and the scorecard. Sessions are the core unit of usage and the most-handled object in the API.

Status lifecycle

Session row created. AI hasnโ€™t joined yet. The candidate can join via the join_url from the invite at any time.
Candidate joined and the AI is actively interviewing. Transcript + authenticity signals stream into the session record live.
Interview finished naturally โ€” the AI delivered the closing line and ended the call. Scorecard ready within 2 minutes.
The candidateโ€™s connection dropped mid-interview and they did not return within the reconnect grace window. Distinct from failed: nothing broke on our side โ€” the network did. The partial transcript is retained, and if the candidate was in the interview long enough, a scorecard flagged incomplete is still produced. error.message carries the LiveKit disconnect reason (CLIENT_INITIATED, SIGNAL_CLOSE, โ€ฆ) and a connection-quality trail.
A platform or agent error interrupted the session (missing interview context, an unrecoverable agent error, a crash). Reserved for problems on our side โ€” candidate connection drops surface as disconnected instead. Partial transcript may still be available; no scorecard.
Before the disconnected status existed, connection drops were also reported as failed. The value is additive: existing integrations that only branch on failed keep working, but new code should treat disconnected as the โ€œcandidateโ€™s networkโ€ case and failed as the โ€œsomething brokeโ€ case.
Recruiter cancelled the session via the API or UI before the candidate joined. No interview happened.
The candidate never joined before the scheduled window elapsed. No interview happened; no scorecard.

Reconnecting after a drop

A candidateโ€™s connection dropping is not immediately terminal. When the candidateโ€™s client disconnects mid-interview:
1

Grace window (3 minutes)

The room and AI interviewer stay alive. The candidateโ€™s existing join_url remains valid โ€” reopening it drops them back into the same session. On rejoin the AI welcomes them back and repeats its last question verbatim; it does not restart or re-introduce itself.
2

Grace window expires

If the candidate hasnโ€™t returned within the window, the session moves to disconnected. If they were in the interview long enough, a scorecard flagged incomplete is still produced from the partial transcript.
3

Automatic resume email

The candidate is emailed a one-click link to resume, which starts a fresh attempt โ€” subject to the roundโ€™s max_attempts. Once that budget is spent, no further automatic retry is sent.
Drops are also headed off before they happen: the candidate lobby runs a pre-join mic check plus a browser/network preflight (warning on non-Chrome browsers, weak connections, and VPNs), and mid-interview the AI proactively tells the candidate when their audio is breaking up so they can fix it before the line fully drops.

Status changes emit events

Every state transition fires a webhook. Configure your endpoint to receive them โ€” see Webhooks for the payload shape + HMAC signing.
Listen for session.scored, not session.completed, when you want the full rubric scorecard. session.completed fires the moment the AI hangs up; scoring happens asynchronously and session.scored is the signal that the scorecard is final.

Reading a session

Returns:
See Get Session for the full schema.

Re-runs and retries

Each session is immutable once it lands in a terminal state (completed / failed / cancelled). If you need another interview for the same candidate โ€” say after a technical failure โ€” create a fresh session. Sessions for the same (participant, stage) are independent rows; the platform doesnโ€™t try to โ€œmergeโ€ or โ€œsupersedeโ€ them. The Applications panel on each templateโ€™s detail page automatically picks the latest session per stage when displaying the rolled-up status, so retries surface immediately.

Multi-stage progression

Multi-stage templates auto-create a fresh session for the next stage when a candidate passes a stage. You donโ€™t need to manually invoke this โ€” the session-status mirror trigger handles it. A candidateโ€™s full trajectory through a 3-Round Role ends up as 3 sessions, one per Round, linked through the same candidate_id. See Roles for how Rounds chain together.

Session vs application

These are two different objects, easy to confuse: The Applications panel on the template detail page reads from template_applications, but the data shown (scores, transcripts, status) comes from the latest session joined onto the application. Theyโ€™re paired 1:N โ€” one application can have many sessions over time (retries, multi-stage progressions).
Last modified on July 10, 2026