> ## Documentation Index
> Fetch the complete documentation index at: https://docs.heymilo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Public API Documentation

> Complete HeyMilo Public API reference for candidates, job postings, interviews, and programmatic integrations.

# 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 the `X-API-KEY` header.

```http theme={null}
X-API-KEY: your_api_key_here
```

This header must be included in every request to the API. Requests without a valid API key will receive a 401 Unauthorized response.

## 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` - Success
* `401` - Unauthorized (missing or invalid API key)
* `404` - Not Found
* `422` - Validation Error
* `429` - 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

```json theme={null}
{
  "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

```bash theme={null}
curl -X GET "https://api.heymilo.network/api/postings?page=1&limit=10" \
  -H "X-API-KEY: your_api_key_here"
```

#### Response

```json theme={null}
{
  "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       |

**Posting Object Schema:**

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

**Root Level Configs Schema:**

| 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)    |

**Agentic Workflow Configs Schema:**

| 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

```bash theme={null}
curl -X GET "https://api.heymilo.network/api/interview/{interview_id}" \
  -H "X-API-KEY: your_api_key_here"
```

#### Response

```json theme={null}
{
    "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

```bash theme={null}
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               |

**Candidate Object Schema**

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

**Selected `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

```json theme={null}
{
  "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

**GET** `interviews/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

```bash theme={null}
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

```json theme={null}
{
  "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

```json theme={null}
{
  "posting_id": "posting_123",
  "url": "https://your-domain.com/webhook-endpoint",
  "event_type": "interview_completed",
  "http_method": "post"
}
```

#### Example Request

```bash theme={null}
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

```json theme={null}
{
  "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

```bash theme={null}
curl -X GET "https://api.heymilo.network/api/webhook/fetch/webhook_789" \
  -H "X-API-KEY: your_api_key_here"
```

#### Response

```json theme={null}
{
  "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 posting
* `retake: 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

```bash theme={null}
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

```json theme={null}
{
  "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 posting
* `retake: 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

```bash theme={null}
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

```json theme={null}
{
  "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:

```json theme={null}
{
  "detail": "Error description",
  "status_code": 422,
  "error_type": "validation_error"
}
```

## Support

For API support and questions:

* Email: [support@heymilo.ai](mailto:support@heymilo.ai)
* Documentation: [https://docs.heymilo.cloud](https://docs.heymilo.cloud)
* Status Page: [https://status.heymilo.ai](https://status.heymilo.ai)

***

*Last updated: Jun 17, 2026*
