Enable Webhooks
Open Developer Settings
In the HR portal, open the sidebar and navigate to Developer Settings, then select the Webhooks tab.

Create a webhook endpoint
Click Create Webhook. In the dialog that appears, enter your Endpoint URL (e.g., 
https://your-app.com/webhooks) and confirm.
Save your signing secret
After creation, a dialog displays your signing secret (prefixed with 
whsec_). It is automatically copied to your clipboard. You’ll use this to verify webhook signatures.
Available Webhooks
All webhook payloads share this envelope structure:| Header | Description |
|---|---|
Content-Type | application/json |
webhook-id | Unique message ID (e.g., msg_a1b2c3...) |
webhook-timestamp | Unix timestamp in seconds |
webhook-signature | HMAC-SHA256 signature (e.g., v1,base64...) |
Every endpoint you register receives all event types. Branch on the
event_type field and ignore
the events you don’t handle.job_application.deleted
Fired when an HR portal user deletes a job application. The payload
is a snapshot of the application captured immediately before the record is
removed. Treat this as the definitive “record is gone” signal — any associated interview, CV evaluation,
insights, and pre-screening data are removed along with the application.
Example payload
Example payload
| Field | Description |
|---|---|
payload.id | The deleted application’s ID. Use this to locate and remove the matching record on your side. |
payload.status | The application’s status at the moment of deletion (e.g. applied, shortlisted, interviewed, hired). |
payload.created_at | When the application was originally created. |
payload.candidate | Contact details for the candidate. |
payload.job | The job posting the application belonged to. |
pre_screening.completed
Fired when a candidate finishes pre-screening questions for a job application.
Example payload
Example payload
| Field | Description |
|---|---|
payload.application | The job application that triggered the event, including its current status |
payload.candidate | Contact details for the candidate |
payload.pre_screening.knockout_count | Number of answers that matched knockout criteria |
payload.pre_screening.questions | Array of questions with the candidate’s answers. options is populated for multiple-choice questions |
payload.job | The job listing the candidate applied to |
interview.completed
Fired when a candidate’s AI interview finishes and scores are ready. The payload carries enough to triage
(score, eligibility, a short summary, strengths/weaknesses/red flags) without a follow-up call. For the full
transcript, per-criteria scores, and per-question detail, fetch the interview by payload.interview.id via
the API.
Example payload
Example payload
| Field | Description |
|---|---|
payload.application | The job application, including its current pipeline status |
payload.candidate | Contact details for the candidate |
payload.job | The job posting the candidate interviewed for |
payload.interview.id | The interview’s ID. Use it to fetch the full transcript, per-criteria scores, and per-question detail via the API |
payload.interview.completed_at | When the interview finished (null if no call time is recorded) |
payload.interview.result.overall_score | Overall score on a 1-5 scale, or null for qualifications-only interviews |
payload.interview.result.is_eligible | false when the candidate failed a required criterion |
payload.interview.result.outcome | eligible or knocked_out |
payload.interview.result.summary | One-paragraph summary of the candidate’s performance |
payload.interview.result.strengths | Key strengths from the AI evaluation (may be empty) |
payload.interview.result.weaknesses | Areas for improvement from the AI evaluation (may be empty) |
payload.interview.result.red_flags | Concerns surfaced during the interview (may be empty) |
interview_v2.completed
Fired when a candidate’s interview finishes on the v2 (legacy) interview pipeline. Unlike
interview.completed, this is a lightweight notification: it carries identifiers plus the candidate and
job, but no scores. Fetch the score, transcript, and per-criteria detail via the API using
payload.interview_call_id.
Knocked-out candidates also produce this event with
status: "completed" — there is no separate
knocked_out status. Whether the candidate passed or was knocked out is only derivable via the API.Example payload
Example payload
| Field | Description |
|---|---|
payload.interview_call_id | The interview’s ID. Use it to fetch the score, transcript, and per-criteria detail via the API |
payload.job_application_id | The job application this interview belonged to |
payload.status | The interview call’s terminal status (completed) |
payload.completed_at | When the interview finished |
payload.candidate | Contact details for the candidate |
payload.job | The job posting the candidate interviewed for |
Verifying Signatures
The signature is computed over a specific message string using HMAC-SHA256:- Extract the
webhook-id,webhook-timestamp, andwebhook-signatureheaders from the request. - Concatenate the signed content:
{webhook-id}.{webhook-timestamp}.{body} - Compute the HMAC-SHA256 hash using your base64-decoded signing secret.
- Compare the result against the signature header using a constant-time comparison function.
Testing Webhooks
During local development, use a tunnel service like ngrok or localtunnel to expose your local server to the internet and receive webhook deliveries.- Respond with a
200status code as quickly as possible, then process the payload asynchronously. Webhook deliveries will time out if your endpoint takes too long to respond. - Log incoming payloads during development to inspect the data structure before writing your handler logic.
Design your webhook handler to be idempotent. Use the
webhook-id header to detect duplicate deliveries — the
same event may be sent more than once during retries.Retries & Deactivation
Failed deliveries are retried up to 6 times with exponential backoff, starting at 2 minutes and increasing by a factor of 4 up to a maximum interval of 8 hours.A
2xx response is considered successful. Any other response — including 4xx, 5xx, or a timeout — triggers a
retry.Upcoming Events
Only
pre_screening.completed, job_application.deleted, interview.completed, and interview_v2.completed are currently available. The events below are planned for future releases.| Event | Description |
|---|---|
cv_evaluation.completed | Fired when a CV evaluation finishes processing |
insights.completed | Fired when combined AI insights are generated for an application |
application.status_changed | Fired when an application’s status changes (e.g., moved to shortlisted) |

