Overview
HeyMilo Webhooks allow you to receive real-time HTTP notifications when key events occur during the candidate interview lifecycle. Instead of polling the API for updates, webhooks push data to your specified endpoint as soon as an event happens — enabling seamless automation, ATS syncing, and custom workflow triggers. With webhooks, you can:- Get notified instantly when a candidate starts or completes an interview
- Receive full interview reports as soon as they are generated
- Automate downstream actions like ATS updates, email notifications, or scoring pipelines
- Build event-driven integrations without continuous API polling
How Webhooks Work
- Register a webhook via the API, specifying a destination URL, the event type you want to subscribe to, and the posting (job) it applies to.
- HeyMilo fires an HTTP request to your URL whenever the subscribed event occurs.
- Your endpoint receives the payload containing all relevant event data (candidate info, interview details, scores, etc.).
Authentication
Webhook API endpoints require authentication using theX-API-KEY header, the same key used for all Public API requests.
Webhook Event Types
HeyMilo supports the following webhook event types:Event Lifecycle
A typical candidate journey triggers events in this order:
Note: The report_available event fires after AI analysis is complete, which may occur several seconds to minutes after the interview is marked as completed.
Webhook API Endpoints
All webhook endpoints use the base URL:1. Create Webhook
POST/create
Register a new webhook to receive event notifications for a specific job posting.
Request Body
Request Schema
Example Request
Response
Response Schema
2. Get Webhook
GET/fetch/{webhook_id}
Retrieve a specific webhook configuration by its ID.
Path Parameters
Example Request
Response
3. Get All Webhooks
GET/all
Retrieve all webhooks for your workspace, with optional filters.
Query Parameters
Example Request
Response
4. Deactivate Webhook
POST/deactivate/{webhook_id}
Deactivate an existing webhook. Deactivated webhooks will no longer receive event notifications.
Path Parameters
Example Request
Webhook Payload Schemas
When an event fires, HeyMilo sends an HTTP request to your registered URL with a JSON payload. The payload structure varies by event type. Each event type has a distinct schema — see the full payloads and field-by-field breakdowns below.Payload: interview_started
Sent when a candidate begins an interview session.
interview_started Payload Schema
Candidate Metadata Object:
Inner Metadata Object (nullable):
Note: The innermetadataobject can benullif no additional ingestion context is available.
Payload: interview_completed
Sent when a candidate finishes all required steps of an interview.
interview_completed Payload Schema
Payload: report_available
Sent when the AI-generated interview report is ready. This is the most comprehensive payload, containing the full analysis data: scores, highlights, scorecard, communication evaluation, transcript, interview data model, company info, and posting info.
report_available Top-Level Schema
agentic_data Object
agentic_data.web_interview_info Object
summary Object
scorecard Object
scorecard.questions[] Object
chat_transcript[] Object
communication Object
transcript Object
interview_data_model Object
interview_data_model.details Object
workflow_status Object
workflow_status.step_by_step[] Object
state_flags Object
details.metadata Object
details.metadata.web_interview Object
company_info Object
posting_info Object
Verifying Webhook Signatures
Webhooks registered through the v2 or v4 create endpoints are signed with HMAC-SHA256, so you can confirm the request genuinely came from HeyMilo and was not altered in transit. Verification is optional — deliveries succeed whether or not you check the signature — but it is strongly recommended for any endpoint that handles candidate data.Getting Your Signing Secret
When you register a webhook throughPOST /api/v2/webhooks, the create response includes a signing_secret beginning with whsec_, nested inside the data object:
POST /api/v4/webhooks returns the same object under data, alongside a top-level "object": "webhook". With either endpoint, read the secret from data.signing_secret.
A few things to know about the secret:
- It is returned only once. The
signing_secretappears in the create response and is never included in get or list responses. Store it securely as soon as you receive it. - It cannot be retrieved or rotated. If you lose it, delete the webhook and register a new one to obtain a fresh secret.
- Each webhook has its own secret. Registering three webhooks for three event types gives you three distinct secrets.
- It is returned by the v2 and v4 create endpoints only. Use
POST /api/v2/webhooks(Public API v2) orPOST /api/v4/webhooks. The legacyPOST /api/webhook/createendpoint does not return a signing secret. - Webhooks registered before signing was introduced have no secret. Their deliveries are sent unsigned. To start receiving signed deliveries on an existing registration, delete it and create it again.
Signature Headers
Signed deliveries carry two additional headers:
What
X-HeyMilo-Delivery identifies depends on the event type:
- For
interview_started,interview_completedandreport_available, it is a per-event notification ID. The value stays the same across retries of that event, so you can use it as a deduplication key. - For
candidate_shortlistedandcandidate_rejected, it identifies the webhook registration rather than the individual event, so every delivery to that webhook carries the same value. Deduplicate these events on the payload instead.
How the Signature Is Computed
The signed string is the timestamp, a literal. character, and the raw request body:
- Read
tandv1from theX-HeyMilo-Signatureheader. - Concatenate
t, a., and the raw request body. - Compute the HMAC-SHA256 of that string using your signing secret and hex-encode it.
- Compare the result against
v1using a constant-time comparison.
Replay Protection
The timestamp is included in the signed string so that a captured request cannot be replayed indefinitely. HeyMilo does not impose a validity window — you choose the tolerance that suits your system. A common choice is to reject any delivery whose timestamp is more than five minutes away from your current time. A timestamp check does not by itself prevent duplicate processing: a delivery that fails is retried with the same body, so the same event can arrive more than once. Deduplicate on a key derived from the payload — for example the interview or candidate identifier combined with the event type — or onX-HeyMilo-Delivery for the event types where it carries a per-event ID.
Example: Node.js / Express
Useexpress.raw() for the webhook route so the original body is preserved.
Example: Python / FastAPI
Setting Up Webhooks
Step 1: Prepare Your Endpoint
Your webhook endpoint must be a publicly accessible URL that can receive HTTP requests. The endpoint should:- Accept
POST(orGET) requests - Return a
200status code to acknowledge receipt - Process the payload asynchronously if heavy processing is required
- Verify the
X-HeyMilo-Signatureheader before trusting the payload — see Verifying Webhook Signatures
Step 2: Register the Webhook
Use the Create Webhook API to register your endpoint for the desired event type and job posting.Step 3: Verify Delivery
After registering, trigger a test event (e.g., start an interview for a test candidate) and confirm your endpoint receives the payload. Check the response status and payload structure to ensure your integration handles the data correctly.Multiple Webhooks Per Posting
You can register multiple webhooks for the same posting to subscribe to different event types or send events to different endpoints. Example: Subscribe to all events for a single postingBest Practices
Common Use Cases
Error Handling
If your endpoint returns a non-200 status code, the webhook delivery is considered failed. Ensure your endpoint is reliable and returns 200 promptly.
Common Errors
Support
For webhook support and questions:- Email: support@heymilo.ai
- Documentation: https://docs.heymilo.cloud
- Status Page: https://status.heymilo.ai