HeyMilo API - Complete Public API Documentation
Overview
The HeyMilo API provides programmatic access to the HeyMilo recruitment and interview platform, empowering developers to seamlessly integrate with our AI-powered hiring system. With this API, you can:- Retrieve and manage candidate information
- Oversee and update job postings
- Set up webhooks for real-time event notifications
- Access detailed interview data and transcripts
- Ingest candidate data for processing
Base URL
All API endpoints use the following base URL:https://api.heymilo.network
Authentication
Important: All API requests require authentication using theX-API-KEY header.
X-API-KEY: your_api_key_here
Rate Limiting
The API implements rate limiting to ensure fair usage:- Default Rate Limit: 300 requests per minute per API key
- Rate limit headers are included in responses to help you track usage
- If you exceed the rate limit, you’ll receive a 429 Too Many Requests response
Response Codes
The API uses standard HTTP status codes:200- Success401- Unauthorized (missing or invalid API key)404- Not Found422- Validation Error429- Too Many Requests (rate limit exceeded)500- Internal Server Error
API Endpoints
1. Health Check
GET/health
Check the health status of the API Gateway.
Response
{
"message": "API Gateway is running successfully",
"status": 200
}
Response Schema
| Field | Type | Description |
|---|---|---|
message | string | Status message |
status | integer | HTTP status code |
2. Get Job Postings
GET/postings
Retrieve job postings with pagination support.
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
page | integer | No | 1 | Page number for pagination |
limit | integer | No | 10 | Number of results per page |
Example Request
curl -X GET "https://api.heymilo.network/api/postings?page=1&limit=10" \
-H "X-API-KEY: your_api_key_here"
Response
{
"postings": [
{
"posting_id": "posting_123",
"title": "Software Engineer",
"name": "software-engineer",
"description": "We are looking for a talented software engineer to join our team...",
"company_id": "comp_67890",
"created_at": 1652345678,
"last_updated": 1652345678,
"archived": false,
"deadline": 1662345678,
"finalized": true,
"phone_number_id": "pn_12345",
"root_level_configs": {
"instructions": "General instructions for all agents in this posting",
"company_overview": "Our company is a leading tech firm specializing in AI solutions",
"job_overview": "This role involves developing backend services using Python and FastAPI",
"interview_process_overview": "The interview process consists of resume screening, technical interview, and culture fit assessment",
"language": "en",
"interviewer_name": "Alex Johnson"
},
"agentic_workflow": [
{
"type": "resume",
"unique_id": "resume_screen_1",
"config": {
"instructions": "Evaluate resumes based on technical skills and experience",
"knockout_enabled": true,
"min_evaluation_score": 0.7,
"mandatory": true
}
},
{
"type": "web_interview",
"unique_id": "tech_interview_1",
"config": {
"instructions": "Conduct a technical interview focusing on Python and system design",
"interviewer_name": "Alex Johnson",
"video": true,
"voice_id": "voice-2",
"web_interview_config": {
"backdrop_image_url": "https://example.com/backdrop.jpg",
"avatar_image_url": "https://example.com/avatar.jpg",
"show_transcript": true,
"vapi_call_config": {
"end_call_message": "Thank you for your time. The interview is now complete.",
"idle_message_max_spoken_count": 3,
"idle_timeout_seconds": 10,
"wait_seconds": 2.4,
"backoff_seconds": 2
}
}
}
},
{
"type": "conversational_sms",
"unique_id": "sms_screen_1",
"config": {
"instructions": "Ask preliminary questions about availability and salary expectations",
"knockout_enabled": true
}
}
],
"url_key": "unique_url_key_for_posting"
},
{
"posting_id": "post_67890",
"title": "Product Manager",
"name": "product-manager",
"description": "Join our product team to help shape the future of our platform...",
"company_id": "comp_67890",
"created_at": 1652345679,
"last_updated": 1652345679,
"archived": false,
"deadline": 1662345679,
"finalized": true,
"phone_number_id": "pn_67890",
"root_level_configs": {
"instructions": "General instructions for all agents in this posting",
"company_overview": "Our company is a leading tech firm specializing in AI solutions",
"job_overview": "This role involves product management for our AI platform",
"language": "en"
},
"agentic_workflow": [
{
"type": "resume",
"unique_id": "resume_screen_1",
"config": {
"instructions": "Evaluate resumes based on product management experience",
"knockout_enabled": true,
"min_evaluation_score": 0.7,
"mandatory": true
}
}
],
"url_key": "unique_url_key_for_posting"
}
],
"total": 42,
"page": 1,
"limit": 10,
"total_pages": 5
}
Response Schema
| Field | Type | Description |
|---|---|---|
postings | array | List of job posting objects |
total | integer | Total number of postings |
page | integer | Current page number |
limit | integer | Number of postings per page |
total_pages | integer | Total number of pages |
| Field | Type | Description |
|---|---|---|
posting_id | string | Unique identifier for the posting |
title | string | Job title |
name | string | URL-friendly name for the posting |
description | string | Job description |
company_id | string | Company identifier |
created_at | float | Timestamp when posting was created |
last_updated | float | Timestamp when posting was last updated |
archived | boolean | Whether the posting is archived |
deadline | float | Deadline for the posting (optional) |
finalized | boolean | Whether the posting is finalized |
phone_number_id | string | Associated phone number ID |
root_level_configs | object | Top-level settings like instructions and company/job overview |
agentic_workflow | array | List of agent-driven steps (e.g., resume, web interview) |
url_key | string | Unique URL key for candidate ingestion |
| Field | Type | Description |
|---|---|---|
instructions | string | General instructions for agents |
company_overview | string | Overview of the company (optional) |
job_overview | string | Overview of the job (optional) |
interview_process_overview | string | Interview process overview (optional) |
language | string | Communication language |
interviewer_name | string | Name of the interviewer (optional) |
| Field | Type | Description |
|---|---|---|
type | string | Step type (e.g., resume, web_interview, conversational_sms) |
unique_id | string | Unique ID for the workflow step |
config | object | Configuration specific to the workflow type |
3. Get Interview Details by Interview ID
GET/interview/{interview_id}
Retrieve detailed information about a specific interview, including candidate details, scores, and recordings.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
interview_id | string | Yes | The unique identifier for the interview |
Example Request
curl -X GET "https://api.heymilo.network/api/interview/{interview_id}" \
-H "X-API-KEY: your_api_key_here"
Response
{
"interview_id": "int_abc123",
"details": {
"interview_id": "int_abc123",
"candidate_id": "cand_xyz789",
"interviewed_on": 1676452800,
"score": 85.5,
"name": "John Smith",
"email": "john.smith@example.com",
"actions": {
"can_view": true,
"can_download": true
},
"status": "completed",
"workflow_status": {
"interview_id": "int_abc123",
"step_by_step": [
{
"complete": true,
"required": true,
"order": 1,
"id": "resume_upload",
"started": true,
"details": {
"details": "Resume uploaded and analyzed"
},
"last_updated_timestamp": 1676452800
},
{
"complete": true,
"required": true,
"order": 2,
"id": "web_interview",
"started": true,
"is_analyzing_call": false,
"last_updated_timestamp": 1676456400
}
],
"all_complete": true,
"last_engagement": 1676456400
},
"metadata": {
"resume": {
"file_link": "https://example.com/resumes/abc123.pdf"
},
"web_interview": {
"final_score": 85.5,
"skill_highlights": ["Communication", "Problem Solving"],
"audio_recording_link": "https://example.com/recordings/abc123.mp3",
"video_recording_link": "https://example.com/recordings/abc123.mp4"
}
}
},
"workflow": {
"interview_id": "int_abc123",
"step_by_step": [
{
"complete": true,
"required": true,
"order": 1,
"id": "resume_upload",
"started": true,
"details": {
"details": "Resume uploaded and analyzed"
},
"last_updated_timestamp": 1676452800
},
{
"complete": true,
"required": true,
"order": 2,
"id": "web_interview",
"started": true,
"is_analyzing_call": false,
"last_updated_timestamp": 1676456400
}
],
"all_complete": true,
"last_engagement": 1676456400
},
"agentic_data": {
"web_interview_info": {
"summary": {
"interview_id": "int_abc123",
"highlights": ["Strong communication skills", "Problem-solving abilities"],
"lowlights": ["Limited experience with Python"],
"match_score": 85
},
"scorecard": {
"interview_id": "int_abc123",
"match_details": ["Good fit for the role"],
"questions": [
{
"question_id": "q1",
"question": "Tell me about your experience with JavaScript",
"evaluation_summary": "Strong experience with modern JavaScript frameworks",
"evaluation_criteria": "JavaScript experience",
"preview_timestamp": 1676453000,
"evaluation_score": 4,
"rank": 1,
"chat_transcript": [
{
"speaker": "interviewer",
"text": "Tell me about your experience with JavaScript",
"timestamp": 1676453000,
"timestamp_str": "00:05:00"
},
{
"speaker": "candidate",
"text": "I've been working with JavaScript for 5 years...",
"timestamp": 1676453010,
"timestamp_str": "00:05:10"
}
],
"score_weight": 2,
"not_scored": false
}
],
"tags": ["JavaScript", "React", "Frontend"]
},
"communication": {
"interview_id": "int_abc123",
"speech_score": 4.2,
"evaluations": [
{
"score": 4,
"remarks": [
{
"details": "Clear and concise communication",
"transcript_reference": {
"speaker": "candidate",
"text": "I believe clear communication is essential...",
"timestamp": 1676453100,
"timestamp_str": "00:06:40"
}
}
]
}
]
},
"transcript": {
"interview_id": "int_abc123",
"transcript": [
{
"speaker": "interviewer",
"text": "Welcome to the interview. Can you introduce yourself?",
"timestamp": 1676452800,
"timestamp_str": "00:00:00"
},
{
"speaker": "candidate",
"text": "Hi, I'm John Smith, a software engineer with 5 years of experience...",
"timestamp": 1676452810,
"timestamp_str": "00:00:10"
}
]
},
"audio_recording_link": "https://example.com/recordings/abc123.mp3",
"video_recording_link": "https://example.com/recordings/abc123.mp4"
},
"resume_interview_info": {
"score_criteria": {
"interview_id": "int_abc123",
"overall_score": 4.2,
"confidence_score": 0.85,
"criteria": [
{
"criteria_id": "c1",
"criteria_text": "JavaScript Experience",
"score": 4.5,
"confidence_score": 0.9,
"reasons": ["5 years of experience with JavaScript", "Experience with React and Vue"],
"standout_parts": ["Led a team of 3 developers"]
}
],
"highlights": ["Strong JavaScript experience", "Team leadership"],
"improvement_areas": ["Limited Python experience"]
},
"eligibility_criteria": {
"interview_id": "int_abc123",
"is_eligible": true,
"confidence_score": 0.95,
"criteria": [
{
"criteria_id": "e1",
"criteria_text": "Minimum 3 years of experience",
"pass_criteria": true,
"confidence_score": 0.98,
"reasons": ["5 years of experience as a software engineer"]
}
],
"skill_gaps": ["Python", "AWS"]
},
"resume_link": "https://example.com/resumes/abc123.pdf"
}
},
"company_name": "Example Corp",
"company_image": "https://example.com/logos/example-corp.png",
"posting_title": "Senior Frontend Developer",
"posting_interview_type": "web",
"posting_id": "posting_123"
}
4. Get Interviews by Posting
GET/interviews/{posting_id}?page=1&limit=10
Retrieve a paginated list of candidate interviews for a job posting. Optionally
filter by the date the candidate was invited to the posting using start_date
and/or end_date.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
posting_id | string | Yes | The ID of the job posting |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
page | integer | No | Page number (default: 1) |
limit | integer | No | Number of interviews per page (default: 10, max: 10) |
start_date | string | No | Only return candidates invited on or after this instant (inclusive). Accepts a YYYY/MM/DD date (e.g. 2025/09/19) or Unix epoch seconds (e.g. 1710288000). UTC. |
end_date | string | No | Only return candidates invited on or before this instant (inclusive). Accepts a YYYY/MM/DD date (e.g. 2025/09/19) or Unix epoch seconds (e.g. 1710288000). UTC. |
Example Request
curl -X GET "https://api.heymilo.network/api/interviews/{posting_id}?page=1&limit=10" \
-H "X-API-KEY: your_api_key_here"
Response Schema
| Field | Type | Description |
|---|---|---|
candidates | array | List of candidate interview objects |
total | integer | Total number of interviews |
page | integer | Current page number |
limit | integer | Number of items per page |
total_pages | integer | Total number of pages |
| Field | Type | Description |
|---|---|---|
interview_id | string | Unique ID for the interview |
details | object | Core interview details |
workflow | object | Workflow progress and status |
agentic_data | object | AI-generated analysis of resume/interview |
company_name | string | Name of the company |
company_image | string | Company logo URL |
posting_title | string | Title of the job posting |
posting_interview_type | string | Interview type (e.g. web, voice, etc.) |
posting_id | string | Job posting ID |
details fields
| Field | Type | Description |
|---|---|---|
invited_on | number | Unix timestamp (seconds, UTC) for when the candidate was invited to this posting. This is the value the start_date/end_date filters operate on. |
interviewed_on | number | Unix timestamp (seconds, UTC) for when the candidate completed the interview. |
Response
{
"candidates": [
{
"interview_id": "int_abc123",
"details": {
"interview_id": "int_abc123",
"candidate_id": "cand_xyz789",
"invited_on": 1676449200,
"interviewed_on": 1676452800,
"score": 85.5,
"name": "John Smith",
"email": "john.smith@example.com",
"actions": {
"can_view": true,
"can_download": true
},
"status": "completed",
"workflow_status": {
"interview_id": "int_abc123",
"step_by_step": [
{
"complete": true,
"required": true,
"order": 1,
"id": "resume_upload",
"started": true,
"details": {
"details": "Resume uploaded and analyzed"
},
"last_updated_timestamp": 1676452800
},
{
"complete": true,
"required": true,
"order": 2,
"id": "web_interview",
"started": true,
"is_analyzing_call": false,
"last_updated_timestamp": 1676456400
}
],
"all_complete": true,
"last_engagement": 1676456400
},
"metadata": {
"resume": {
"file_link": "https://example.com/resumes/abc123.pdf"
},
"web_interview": {
"final_score": 85.5,
"skill_highlights": ["Communication", "Problem Solving"],
"audio_recording_link": "https://example.com/recordings/abc123.mp3",
"video_recording_link": "https://example.com/recordings/abc123.mp4"
}
}
},
"workflow": {
"interview_id": "int_abc123",
"step_by_step": [
{
"complete": true,
"required": true,
"order": 1,
"id": "resume_upload",
"started": true,
"details": {
"details": "Resume uploaded and analyzed"
},
"last_updated_timestamp": 1676452800
},
{
"complete": true,
"required": true,
"order": 2,
"id": "web_interview",
"started": true,
"is_analyzing_call": false,
"last_updated_timestamp": 1676456400
}
],
"all_complete": true,
"last_engagement": 1676456400
},
"agentic_data": {
"web_interview_info": {
"summary": {
"interview_id": "int_abc123",
"highlights": ["Strong communication skills", "Problem-solving abilities"],
"lowlights": ["Limited experience with Python"],
"match_score": 85
},
"scorecard": {
"interview_id": "int_abc123",
"match_details": ["Good fit for the role"],
"questions": [
{
"question_id": "q1",
"question": "Tell me about your experience with JavaScript",
"evaluation_summary": "Strong experience with modern JavaScript frameworks",
"evaluation_criteria": "JavaScript experience",
"preview_timestamp": 1676453000,
"evaluation_score": 4,
"rank": 1,
"chat_transcript": [
{
"speaker": "interviewer",
"text": "Tell me about your experience with JavaScript",
"timestamp": 1676453000,
"timestamp_str": "00:05:00"
},
{
"speaker": "candidate",
"text": "I've been working with JavaScript for 5 years...",
"timestamp": 1676453010,
"timestamp_str": "00:05:10"
}
],
"score_weight": 2,
"not_scored": false
}
],
"tags": ["JavaScript", "React", "Frontend"]
},
"communication": {
"interview_id": "int_abc123",
"speech_score": 4.2,
"evaluations": [
{
"score": 4,
"remarks": [
{
"details": "Clear and concise communication",
"transcript_reference": {
"speaker": "candidate",
"text": "I believe clear communication is essential...",
"timestamp": 1676453100,
"timestamp_str": "00:06:40"
}
}
]
}
]
},
"transcript": {
"interview_id": "int_abc123",
"transcript": [
{
"speaker": "interviewer",
"text": "Welcome to the interview. Can you introduce yourself?",
"timestamp": 1676452800,
"timestamp_str": "00:00:00"
},
{
"speaker": "candidate",
"text": "Hi, I'm John Smith, a software engineer with 5 years of experience...",
"timestamp": 1676452810,
"timestamp_str": "00:00:10"
}
]
},
"audio_recording_link": "https://example.com/recordings/abc123.mp3",
"video_recording_link": "https://example.com/recordings/abc123.mp4"
},
"resume_interview_info": {
"score_criteria": {
"interview_id": "int_abc123",
"overall_score": 4.2,
"confidence_score": 0.85,
"criteria": [
{
"criteria_id": "c1",
"criteria_text": "JavaScript Experience",
"score": 4.5,
"confidence_score": 0.9,
"reasons": ["5 years of experience with JavaScript", "Experience with React and Vue"],
"standout_parts": ["Led a team of 3 developers"]
}
],
"highlights": ["Strong JavaScript experience", "Team leadership"],
"improvement_areas": ["Limited Python experience"]
},
"eligibility_criteria": {
"interview_id": "int_abc123",
"is_eligible": true,
"confidence_score": 0.95,
"criteria": [
{
"criteria_id": "e1",
"criteria_text": "Minimum 3 years of experience",
"pass_criteria": true,
"confidence_score": 0.98,
"reasons": ["5 years of experience as a software engineer"]
}
],
"skill_gaps": ["Python", "AWS"]
},
"resume_link": "https://example.com/resumes/abc123.pdf"
}
},
"company_name": "Example Corp",
"company_image": "https://example.com/logos/example-corp.png",
"posting_title": "Senior Frontend Developer",
"posting_interview_type": "web",
"posting_id": "posting_123"
}
],
"total": 42,
"page": 1,
"limit": 10,
"total_pages": 5
}
5. Export Interviews
GETinterviews/export/json
Retrieve JSON file of interviews
Path Parameters
| Field | Type | Required | Description |
|---|---|---|---|
posting_id | string | Yes | ID of the job posting to export |
Example Request
curl --request POST \
--url "https://api.heymilo.network/api/interviews/export/json" \
--header 'X-API-KEY: your_api_key_here' \
--data '{
"posting_id": "A03EBF1A"
}'
Response Schema
| Field | Type | Description |
|---|---|---|
job_id | string | ID of the export job (used for tracking) |
status | string | Status of the export job (e.g., success) |
file_url | string | Direct URL to download the exported JSON file |
Response
{
"job_id": "1ce5b174-611f-4cec-b955-cd48da195fcb",
"status": "success",
"file_url": "https://cdn.heymilo.ai/exports/json/CFE6B6A30C63EF347F5E2BD67D171/B26029F7/candidates-B26029F7-2025-08-14-14-35.json"
}
6. Create Webhook
POST/create
Create a new webhook configuration to receive real-time notifications about interview events.
Request Body
{
"posting_id": "posting_123",
"url": "https://your-domain.com/webhook-endpoint",
"event_type": "interview_completed",
"http_method": "post"
}
Example Request
curl -X POST "https://api.heymilo.network/api/webhook/create" \
-H "X-API-KEY: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"posting_id": "posting_123",
"url": "https://your-domain.com/webhook-endpoint",
"event_type": "interview_completed",
"http_method": "post"
}'
Response
{
"webhook_id": "webhook_789",
"posting_id": "posting_123",
"url": "https://your-domain.com/webhook-endpoint",
"event_type": "interview_completed",
"http_method": "post",
"is_active": true,
"created_at": 1703097600.0,
"updated_at": 1703097600.0
}
Request Schema
| Field | Type | Required | Description |
|---|---|---|---|
posting_id | string | Yes | ID of the posting this webhook is for |
url | string (URL) | Yes | Destination URL for the webhook |
event_type | string | Yes | Event type: “interview_started”, “interview_completed”, “report_available” |
http_method | string | No | HTTP method: “get” or “post” (default: “post”) |
7. Get Webhook
GET/fetch/{webhook_id}
Retrieve a webhook configuration by its ID.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
webhook_id | string | Yes | The webhook ID |
Example Request
curl -X GET "https://api.heymilo.network/api/webhook/fetch/webhook_789" \
-H "X-API-KEY: your_api_key_here"
Response
{
"webhook_id": "webhook_789",
"posting_id": "posting_123",
"url": "https://your-domain.com/webhook-endpoint",
"event_type": "interview_completed",
"http_method": "post",
"is_active": true,
"created_at": 1703097600.0,
"updated_at": 1703097600.0
}
8. Get All Webhooks
GET/all
Retrieve webhooks with optional filters.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
posting_id | string | No | Filter by posting ID |
event_type | string | No | Filter by event type |
9. Deactivate Webhook
POST/deactivate/{webhook_id}
Deactivate a webhook.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
webhook_id | string | Yes | The webhook ID |
10. Ingest Single Candidate
POST/ingest/x/{url_key}
Ingest a single candidate into the system using a posting-specific url_key.
Spectial Note
retake: false(default) - Returns existing interview if candidate already has one for this postingretake: true- Always creates a new interview, even if candidate already has one
Path Parameters
| Field | Type | Required | Description |
|---|---|---|---|
url_key | string | Yes | Unique key identifying the target pipeline |
Example Request
curl --request POST \
--url "https://api.heymilo.network/api/ingest/x/{url_key}" \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: your_api_key_here' \
--data '{
"name": "John Doe",
"email": "john.doe@example.com",
"phone_number": "+1234567890",
"metadata": {
"source": "careers_page",
"job_id": "job123"
},
"data": {
"experience": "5 years",
"education": "Bachelor'\''s in Computer Science"
},
"retake" : true
}'
Response Schema
| Field | Type | Description |
|---|---|---|
message | string | Confirmation message about ingestion initiation |
ingestion_id | string | Unique ID for the ingestion process |
interview_details | array | List of interviews created/linked for the candidate |
Each interview details:
| Field | Type | Description |
|---|---|---|
interview_id | string | Unique identifier for the interview |
interview_link | string | URL link for candidate’s interview access |
Response
{
"message": "Data Ingestion initiated for john.doe@example.com",
"ingestion_id": "550e8400-e29b-41d4-a716-446655440000",
"interview_details": [
{
"interview_id": "int_id_78658707",
"interview_link": "https://candidates.sample/heymiloai/i/interview_id"
}
]
}
11. Bulk Ingest Candidates
POST/ingest/x/bulk/{url_key}
Ingest multiple candidates into the system in a single request, using a posting-specific url_key.
Spectial Note
retake: false(default) - Returns existing interview if candidate already has one for this postingretake: true- Always creates a new interview, even if candidate already has one
Path Parameters
| Field | Type | Required | Description |
|---|---|---|---|
url_key | string | Yes | Unique key identifying the target pipeline |
Example Request
curl --request POST \
--url "https://api.heymilo.network/api/ingest/x/bulk/{url_key}" \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: your_api_key_here' \
--data '{
"data": [
{
"name": "John Doe",
"email": "john.doe@example.com",
"phone_number": "+1234567890",
"metadata": {
"source": "careers_page",
"job_id": "job123"
},
"data": {
"experience": "5 years",
"education": "Bachelor'\''s in Computer Science"
},
"retake" : true
},
{
"name": "Jane Smith",
"email": "jane.smith@example.com",
"phone_number": "+1987654321",
"metadata": {},
"data": {},
"retake" : false
}
]
}'
Response Schema
| Field | Type | Description |
|---|---|---|
message | string | Confirmation message about bulk ingestion initiation |
ingestion_id | string | Unique ID for the bulk ingestion process |
interview_details | array | List of interviews created/linked for the candidates |
Each interview details:
| Field | Type | Description |
|---|---|---|
interview_id | string | Unique identifier for the interview |
interview_link | string | URL link for candidate’s interview access |
Response
{
"message": "Bulk candidate ingestion job created successfully",
"ingestion_id": "ing_123456789",
"interview_details": [
{
"interview_id": "int_id_78658707",
"interview_link": "https://candidates.sample/heymiloai/i/interview_id"
},
{
"interview_id": "int_id_78658703",
"interview_link": "https://candidates.sample/heymiloai/i/interview_id"
}
]
}
Webhook Event Types
The API supports the following webhook event types:| Event Type | Description |
|---|---|
interview_started | Triggered when a candidate starts an interview |
interview_completed | Triggered when a candidate completes an interview |
report_available | Triggered when an interview report becomes available |
Error Handling
All API endpoints return structured error responses:{
"detail": "Error description",
"status_code": 422,
"error_type": "validation_error"
}
Support
For API support and questions:- Email: support@heymilo.ai
- Documentation: https://docs.heymilo.cloud
- Status Page: https://status.heymilo.ai
Last updated: Jun 17, 2026