Envelope
Every webhook request is aPOST with a JSON body:
{
"event": "<event_name>",
"data": { ... }
}
| Field | Type | Description |
|---|---|---|
event | string | The event name (e.g. interview.ended) |
data | object | Event-specific payload data |
data payload contains a workspace, project, and candidate object, plus the event-specific object (interview or call).
interview.ended
Sent when a candidate completes a Charlie interview. Example payload:{
"event": "interview.ended",
"data": {
"workspace": { "id": "64a1b2c3d4e5f6a7b8c9d0e1", "name": "Acme Hiring" },
"project": {
"id": "64a1b2c3d4e5f6a7b8c9d0e2",
"name": "Backend Engineer Hiring",
"ats_job_id": "ats-job-123"
},
"candidate": {
"id": "cand_001",
"internal_id": "64a1b2c3d4e5f6a7b8c9d0e3",
"name": "Jane Smith",
"email": "jane.smith@example.com",
"custom_fields": { "ats_candidate_id": "ATS-456" }
},
"interview": {
"id": "intv_001",
"summary": "The candidate demonstrated strong technical skills in Node.js and system design.",
"transcript": [
{ "role": "assistant", "transcription": "Tell me about your experience with Node.js.", "time": "2026-02-12T14:00:05.000Z" },
{ "role": "user", "transcription": "I have been working with Node.js for over 5 years...", "time": "2026-02-12T14:00:12.000Z" }
],
"overall_score": 78,
"recommendation": "good_fit",
"report_url": "https://example.com/report/intv_001",
"video_url": "https://example.com/video/intv_001",
"duration": 1200,
"completed_at": "2026-02-12T14:20:00.000Z"
}
}
}
| Interview field | Description |
|---|---|
summary | AI summary of the interview |
transcript | Turn-by-turn transcript (role, transcription, time) |
overall_score | Final interview score |
recommendation | Fit recommendation (e.g. good_fit) |
report_url | Link to the full interview report |
video_url | Link to the interview recording |
duration | Interview duration in seconds |
completed_at | ISO timestamp of completion |
call.ended
Sent when a Ria AI call ends. Example payload:{
"event": "call.ended",
"data": {
"workspace": { "id": "64a1b2c3d4e5f6a7b8c9d0e1", "name": "Acme Hiring" },
"project": {
"id": "64a1b2c3d4e5f6a7b8c9d0e2",
"name": "Backend Engineer Hiring",
"ats_job_id": "ats-job-123"
},
"candidate": {
"id": "cand_001",
"internal_id": "64a1b2c3d4e5f6a7b8c9d0e3",
"name": "John Doe",
"email": "john.doe@example.com",
"phone": "+19876543210"
},
"call": {
"id": "64a1b2c3d4e5f6a7b8c9d0e4",
"call_sequence_id": 1,
"next_call_scheduled_at": null,
"status": "call_answered",
"summary": "Candidate confirmed interest in the role and is available to interview next week.",
"transcript": [
{ "role": "assistant", "transcription": "Hi John, this is the AI recruiter from Acme. Do you have a minute?" },
{ "role": "user", "transcription": "Yes, go ahead." }
],
"duration": 600,
"recording_url": "https://example.com/recording/64a1b2c3d4e5f6a7b8c9d0e4.mp3",
"started_at": "2026-02-12T14:00:00.000Z",
"ended_at": "2026-02-12T14:10:00.000Z",
"extracted_variables": { "interested": true, "availability": "next_week" }
}
}
}
| Call field | Description |
|---|---|
call_sequence_id | Attempt number (1 = first call) |
next_call_scheduled_at | Present if a retry call is scheduled |
status | Call status (e.g. call_answered) |
summary | AI summary of the call |
transcript | Turn-by-turn transcript (role, transcription) |
recording_url | Link to the call recording |
extracted_variables | The extract_variables you configured, with extracted values |
started_at / ended_at | ISO timestamps |
extracted_variables reflects the extract_variables you set in the Initiate AI Call request. A disposition you configured is returned as part of the call result as well.