Webhook Configuration

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

  1. 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.

  2. HeyMilo fires an HTTP request to your URL whenever the subscribed event occurs.

  3. Your endpoint receives the payload containing all relevant event data (candidate info, interview details, scores, etc.).

┌──────────┐         Event occurs         ┌────────────────┐
│  HeyMilo │ ──── HTTP POST/GET ────────► │  Your Endpoint │
└──────────┘   (JSON payload)             └────────────────┘

Authentication

Webhook API endpoints require authentication using the X-API-KEY header, the same key used for all Public API requests.


Webhook Event Types

HeyMilo supports the following webhook event types:

Event Type
Description

interview_started

Triggered when a candidate begins an interview session

interview_completed

Triggered when a candidate finishes all steps of an interview

report_available

Triggered when the AI-generated interview report is ready to view

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

Field
Type
Required
Description

posting_id

string

Yes

ID of the job posting this webhook applies to

url

string (URL)

Yes

The destination URL that will receive the webhook payload

event_type

string

Yes

One of: interview_started, interview_completed, report_available

http_method

string

No

HTTP method used to deliver the webhook: get or post (default: post)

Example Request

Response

Response Schema

Field
Type
Description

webhook_id

string

Unique identifier for the created webhook

posting_id

string

The job posting this webhook is associated with

url

string

Destination URL for webhook delivery

event_type

string

The subscribed event type

http_method

string

HTTP method used for delivery (get or post)

is_active

boolean

Whether the webhook is currently active

created_at

float

Unix timestamp when the webhook was created

updated_at

float

Unix timestamp when the webhook was last modified


2. Get Webhook

GET /fetch/{webhook_id}

Retrieve a specific webhook configuration by its ID.

Path Parameters

Parameter
Type
Required
Description

webhook_id

string

Yes

The unique ID of the webhook

Example Request

Response


3. Get All Webhooks

GET /all

Retrieve all webhooks for your workspace, with optional filters.

Query Parameters

Parameter
Type
Required
Description

posting_id

string

No

Filter webhooks by job posting ID

event_type

string

No

Filter by event type: interview_started, interview_completed, report_available

Example Request

Response


4. Deactivate Webhook

POST /deactivate/{webhook_id}

Deactivate an existing webhook. Deactivated webhooks will no longer receive event notifications.

Path Parameters

Parameter
Type
Required
Description

webhook_id

string

Yes

The unique ID of the webhook

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

Field
Type
Description

interview_id

string

Unique identifier for the interview

posting_id

string

The job posting ID

timestamp

float

Unix timestamp when the interview started

metadata

object

Candidate metadata object (see below)

Candidate Metadata Object:

Field
Type
Description

candidate_name

string

Candidate's full name

candidate_email

string

Candidate's email address

candidate_id

string

Unique identifier for the candidate

metadata

object/null

Additional ingestion metadata (can be null). See inner metadata below.

Inner Metadata Object (nullable):

Field
Type
Description

source

string

How the candidate was ingested (e.g., user_ingestion)

job_id

string

The job/posting ID associated with the ingestion

Note: The inner metadata object can be null if no additional ingestion context is available.


Payload: interview_completed

Sent when a candidate finishes all required steps of an interview.

interview_completed Payload Schema

Field
Type
Description

interview_id

string

Unique identifier for the interview

agent_conversation_id

string

Conversation ID for the agent interaction (empty string if not applicable)

parent_conversation_id

string

Parent conversation ID linking related interview sessions

engagement_id

string

Engagement tracking ID (empty string if not applicable)

posting_id

string

The job posting ID

timestamp

float

Unix timestamp when the event was emitted

workflow_completed

boolean

Whether the full agentic workflow has been completed

completion_timestamp

float

Unix timestamp when the interview was actually completed


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

Field
Type
Description

interview_id

string

Unique identifier for the interview

posting_id

string

The job posting ID

metadata

object

Candidate metadata (same structure as interview_started)

report_url

string

Direct URL to download the generated PDF report

timestamp

float

Unix timestamp when the report became available

interview_type

string

Type of interview (e.g., web_interview)

agentic_data

object

AI-generated analysis data (summary, scorecard, transcript, etc.)

interview_data_model

object

Full interview record with candidate details, company & posting info


agentic_data Object

Field
Type
Description

web_interview_info

object/null

AI analysis of web/voice interview (present if interview type is web)

agentic_data.web_interview_info Object

Field
Type
Description

summary

object

High-level interview summary with highlights and match score

scorecard

object

Detailed question-by-question scoring

communication

object

Communication and speech quality evaluation

transcript

object

Full interview transcript

audio_recording_link

string

URL to the audio recording of the interview

video_recording_link

string

URL to the video recording (if video enabled)

summary Object

Field
Type
Description

interview_id

string

Interview identifier

highlights

array

List of candidate strengths (strings)

lowlights

array

List of candidate weaknesses or gaps (strings)

match_score

integer

Overall match score (0-100)

scorecard Object

Field
Type
Description

interview_id

string

Interview identifier

match_details

array

List of match assessment details (strings)

questions

array

List of scored question objects

tags

array

Skill tags identified during the interview

scorecard.questions[] Object

Field
Type
Description

question_id

string

Unique identifier for the question

question

string

The interview question text

evaluation_summary

string

AI-generated summary of the candidate's answer

evaluation_criteria

string

The criteria used for evaluation

preview_timestamp

integer

Timestamp offset (seconds) for the answer preview

evaluation_score

integer

Score for this question (1-10)

rank

integer

Ranking position of this question

chat_transcript

array

Relevant transcript excerpts for this question

score_of_1

string

Description of what constitutes the lowest score

score_of_5

string

Description of what constitutes the highest score

score_weight

integer

Weight multiplier for this question's score

not_scored

boolean

Whether this question was excluded from scoring

chat_transcript[] Object

Field
Type
Description

speaker

string

Who spoke (Candidate, bot, user)

text

string

The spoken text

timestamp

integer

Timestamp offset in seconds from interview start

timestamp_str

string

Human-readable timestamp (e.g., "04:34")

communication Object

Field
Type
Description

interview_id

string

Interview identifier

speech_score

float

Overall speech/communication score (-1 if not scored)

evaluations

array

List of communication evaluation objects (can be empty)

template_id

string/null

Template ID used for evaluation (if applicable)

transcript Object

Field
Type
Description

interview_id

string

Interview identifier

transcript

array

List of transcript entry objects


interview_data_model Object

Field
Type
Description

interview_id

string

Unique identifier for the interview

details

object

Core interview details (candidate info, workflow, metadata)

company_info

object

Full company/workspace configuration

posting_info

object

Full job posting configuration

web_interview_info

object/null

Web interview analysis (duplicated from agentic_data)

resume_interview_info

object/null

Resume screening analysis (null if no resume step)

sms_interview_info

object/null

SMS screening analysis (null if no SMS step)

form_interview_info

object/null

Form screening analysis (null if no form step)

interview_data_model.details Object

Field
Type
Description

interview_id

string

Interview identifier

candidate_id

string

Unique identifier for the candidate

interviewed_on

float

Unix timestamp when the interview was conducted

score

float

Overall score

name

string

Candidate's full name

email

string

Candidate's email address

actions

object/null

Available actions for this interview

status

string/null

Interview status

workflow_status

object

Detailed workflow step statuses

metadata

object

Per-stage metadata (resume, web_interview, sms, form)

candidate_feedback

object/null

Candidate's feedback on the interview

candidate_next_steps

object/null

Next steps for the candidate

candidate_interview_url

string

The candidate-facing interview URL

workflow_status Object

Field
Type
Description

interview_id

string

Interview identifier

step_by_step

array

List of workflow step status objects

all_complete

boolean

Whether all required steps are complete

last_engagement

float

Unix timestamp of the last candidate interaction

metadata

object/null

Additional workflow metadata

workflow_status.step_by_step[] Object

Field
Type
Description

complete

boolean

Whether this step is complete

required

boolean

Whether this step is required

order

integer

Position in the workflow sequence (1-based)

id

string

Step identifier (e.g., web_interview, resume_upload)

started

boolean

Whether the candidate has started this step

details

object/null

Human-readable status details (details, title, description)

raw_status

string

Internal status code (e.g., INTERVIEW_PROCESSED_RAW_FILES)

last_updated_timestamp

float

Unix timestamp of the last update to this step

knocked_out

boolean

Whether the candidate was disqualified at this step

completion_percentage

float

Step completion progress (0 to 1)

completion_metadata

object/null

Additional completion metadata

is_analyzing_call

boolean

Whether AI analysis is still in progress

total_duration

float/null

Total duration of the step in seconds

state_flags

object

Boolean state flags for the step

state_flags Object

Field
Type
Description

is_completed

boolean

Whether the step is fully completed

is_incomplete

boolean

Whether the step is incomplete

is_analyzing_call

boolean

Whether AI analysis is in progress

is_in_progress

boolean

Whether the step is currently in progress

details.metadata Object

Field
Type
Description

resume

object/null

Resume metadata (null if no resume step)

web_interview

object/null

Web interview metadata (score, highlights, recording links)

sms

object/null

SMS screening metadata (null if no SMS step)

form

object/null

Form screening metadata (null if no form step)

details.metadata.web_interview Object

Field
Type
Description

final_score

float

Final interview score

skill_highlights

array

List of skill tags (strings)

audio_recording_link

string

URL to audio recording

video_recording_link

string

URL to video recording

company_info Object

Field
Type
Description

company_id

string

Unique company identifier

workspace_id

string

Workspace identifier

created_at

float

Unix timestamp when the company was created

updated_at

float/null

Unix timestamp of last update

created_by

string

Creator identifier

name

string

Company name

image_url

string

Company logo URL

intro_message

string/null

Custom intro message

company_background

string/null

Company background info

voice_id

string/null

Default voice ID for interviews

knowledge_base

object/null

Company knowledge base configuration

interview_domain

string/null

Custom interview domain

interview_domain_id

string/null

Custom interview domain ID

sender_email_id

string/null

Sender email configuration ID

address

string/null

Company address

address_data

object/null

Structured address data

timezone

string/null

Company timezone

base_web_interview_config

object

Default web interview config (backdrop, avatar, branding)

message_settings

object/null

Messaging configuration

sms_agent_config

object/null

SMS agent configuration

pdf_generation_config

object/null

PDF report generation settings

cheat_detection

object/null

Cheat detection configuration

allow_white_labeling

boolean/null

Whether white labeling is enabled

disable_all_candidate_communications

boolean/null

Whether all candidate communications are disabled

interview_completion_confidence_threshold

float

Confidence threshold for interview completion (0-1)

retention_policy_days

integer/null

Data retention policy in days

video_cheat_detection_enabled

boolean/null

Whether video cheat detection is enabled

form_agent_enabled

boolean/null

Whether form agent is enabled

calendar_management_enabled

boolean/null

Whether calendar management is enabled

email_templates_enabled

boolean/null

Whether email templates are enabled

phone_calls_enabled

boolean/null

Whether phone calls are enabled

profile_picture_processing

boolean/null

Whether profile picture processing is enabled

chat_agent_enabled

boolean/null

Whether chat agent is enabled

copilot_enabled

boolean/null

Whether copilot is enabled

design_templates_enabled

boolean/null

Whether design templates are enabled

interview_templates_enabled

boolean/null

Whether interview templates are enabled

sourcing_configs_enabled

boolean/null

Whether sourcing configs are enabled

pbac_enabled

boolean/null

Whether permissions-based access control is enabled

email_report_to_candidate_enabled

boolean/null

Whether email reports to candidates are enabled

posting_info Object

Field
Type
Description

posting_id

string

Unique posting identifier

title

string

Job title

name

string

URL-friendly posting name

internal_name

string/null

Internal posting name

description

string

Job description (HTML)

root_level_configs

object

Top-level agent configuration

company_id

string

Company identifier

created_at

float

Unix timestamp when the posting was created

last_updated

float

Unix timestamp when the posting was last updated

archived

boolean

Whether the posting is archived

deadline

float

Posting deadline (Unix timestamp)

finalized

boolean

Whether the posting is finalized

test_posting

boolean

Whether this is a test posting

agentic_workflow

array

List of agent workflow steps with configurations

step_workflow

object

Workflow definition with steps and dependencies

phone_number_id

string/null

Associated phone number ID

sender_email_id

string

Sender email ID

email_template_group_id

string/null

Email template group ID

design_template_group_id

string/null

Design template group ID

sourcing_config_ids

array

List of sourcing config IDs

redirect_url

string/null

Post-interview redirect URL

scheduling_url

string/null

Scheduling page URL

event_slug

string/null

Calendar event slug

cal_team_id

string/null

Calendar team ID

team_slug

string/null

Team slug

mascot_url

string

Mascot image URL

mascot_id

string

Mascot identifier

days_to_complete

integer/null

Days allowed to complete the interview

ats_metadata

object/null

ATS integration metadata

allow_sms_comms

boolean

Whether SMS communications are enabled

max_retakes

integer/null

Maximum number of interview retakes

retake_cooldown_days

integer/null

Cooldown period between retakes

is_template

boolean

Whether this posting is a template

email_report_to_candidate

boolean

Whether to email reports to candidates


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 (or GET) requests

  • Return a 200 status code to acknowledge receipt

  • Process the payload asynchronously if heavy processing is required

Example endpoint (Node.js / Express):

Example endpoint (Python / FastAPI):

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 posting


Best Practices

chevron-rightRespond Quicklyhashtag

Return a 200 status code as soon as you receive the webhook. Perform any heavy processing (database writes, downstream API calls, etc.) asynchronously to avoid timeouts.

chevron-rightHandle Duplicate Eventshashtag

Use the interview_id field to deduplicate events. In rare cases, the same event may be delivered more than once. Design your handler to be idempotent.

chevron-rightValidate Payloadshashtag

Always validate the structure of incoming payloads before processing. Check for required fields and handle missing or unexpected data gracefully. Many fields can be null depending on the interview configuration.

chevron-rightUse HTTPS Endpointshashtag

Always use HTTPS URLs for your webhook endpoints to ensure data is encrypted in transit. HeyMilo sends sensitive candidate information in webhook payloads.

chevron-rightMonitor Webhook Healthhashtag

Log all incoming webhook requests and monitor for failures. If your endpoint becomes unreachable, events may be missed. Consider implementing alerting for webhook processing errors.

chevron-rightScope Webhooks to Postingshashtag

Register webhooks only for the job postings you need to monitor. This reduces noise and ensures your endpoint only receives relevant events.

chevron-rightHandle Nullable Fieldshashtag

Many fields in the report_available payload can be null depending on the posting configuration (e.g., resume_interview_info, sms_interview_info, form_interview_info). Always check for null before accessing nested properties.


Common Use Cases

chevron-rightATS Synchashtag

Use interview_completed or report_available webhooks to automatically push interview results back to your Applicant Tracking System. Extract the score, workflow status, and report data to update candidate records in real time.

chevron-rightRecruiter Notificationshashtag

Trigger Slack, email, or SMS notifications to recruiters when candidates complete interviews. Use the interview_completed event to alert team members and include the candidate name, score, and a link to the full report.

chevron-rightAutomated Candidate Progressionhashtag

Use report_available to automatically advance or reject candidates based on their scores. For example, candidates with a match_score above a threshold can be moved to the next stage, while those below can receive an automated rejection email.

chevron-rightAnalytics & Dashboardshashtag

Stream webhook events into your analytics platform to build custom hiring dashboards. Track metrics like time-to-complete, average scores, and candidate throughput across postings.

chevron-rightWorkflow Automation (Zapier / Make)hashtag

Use webhook URLs as triggers in Zapier, Make, or other automation platforms. This enables no-code workflows like adding candidates to Google Sheets, sending calendar invites, or updating CRM records when interviews are completed.


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

Scenario
Recommendation

Endpoint returns 4xx

Check your endpoint URL and ensure it accepts the correct HTTP method

Endpoint returns 5xx

Investigate server-side errors in your application

Endpoint unreachable

Verify your endpoint is publicly accessible and DNS is configured

Payload parsing fails

Validate the Content-Type header and JSON body parsing logic


Support

For webhook support and questions:

  • Documentation: https://docs.heymilo.cloud

  • Status Page: https://status.heymilo.ai

Last updated