Candidate Flow
Candidate Flow
The end-to-end candidate experience from receiving an interview link to completing the live AI interview.
When a recruiter approves an interview plan, the system generates a time-limited, token-based interview link and sends it to the candidate. The candidate follows a guided two-step flow: device pre-check to confirm camera and microphone are working, then the live AI-conducted interview session.
Flow Steps
| Step | Page | Description |
|---|---|---|
| 1 | /interview/join/:token | View interview details and proceed to device check |
| 2 | /interview/pre-check/:token | Test camera and microphone before joining |
| 3 | /interview/:sessionId | Live AI interview — audio + real-time conversation |
Guides
Interview Link
The interview link is generated when the recruiter approves the plan. It contains a signed access token that expires in 7 days (configurable per tenant).
{YOUR_APP_URL}/interview/join/abc123token
^^^^^^^^^^^
Access token embedded in URL path| Property | Value |
|---|---|
| Token type | URL-safe signed string (UUID-based) |
| Expiry | 7 days from generation (configurable) |
| Auth method | Token itself is the credential — no JWT required |
| Single-use | No — candidate can rejoin if session disconnects |
Live Interview — WebSocket Connection
Once the candidate starts the session, the frontend connects to the Vert.x WebSocket edge. The connection uses sessionId and tenantId as query parameters. Vert.x registers the connection in Redis so agent audio responses can be routed back to the correct WebSocket regardless of which interviewer pod processes the audio.
wss://mayaedge.teamcast.ai/ws?sessionId=<session-uuid>&tenantId=<tenant-uuid>
Audio frames sent as JSON text:
{ "type": "AUDIO", "sessionId": "...", "tenantId": "...", "streaming": "start", "data": "" }
{ "type": "AUDIO", "sessionId": "...", "tenantId": "...", "streaming": "chunk", "data": "<base64>" }
{ "type": "AUDIO", "sessionId": "...", "tenantId": "...", "streaming": "end", "data": "" }
{ "type": "AUDIO", "sessionId": "...", "tenantId": "...", "data": "<base64 full chunk>" }
Messages received from agent:
{ "type": "TRANSCRIPTION", "text": "..." } ← live interim transcript
{ "type": "AGENT_RESPONSE", "data": "<base64 PCM L16 24kHz>" } ← agent TTS audio
{ "type": "INTERVIEW_ENDED" } ← session completeSession Storage Keys
The candidate frontend stores session state in sessionStorage (cleared when the browser tab closes):
| Key | Value | Set At |
|---|---|---|
| interview_token | URL access token | On join page load |
| interview_candidate_name | Candidate full name | On join page load |
| interview_position | Job position title | On join page load |
| interview_tenant_id | Tenant UUID | After start call |