Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/heymilo-questions-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no email required.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: HeyMilo Public ATS Questions API
description: External developer-facing API for HeyMilo. Create interviewers with agentic workflows, ingest candidates, retrieve interview results, and manage workspace resources.
version: 2.0.0
servers:
- url: https://api.heymilo.ai
description: Production
security:
- ApiKeyAuth: []
tags:
- name: Questions
description: 'Create, read, update, delete, and reorder questions and criteria for an interviewer''s workflow. Covers all modalities: voice, sms, form, resume_eligibility, resume_scoring, and voice_tags.'
paths:
/api/v2/postings/{posting_id}/questions:
get:
tags:
- Questions
summary: List questions
description: Returns all questions and criteria for a posting. Optionally filter by modality (voice, sms, form, resume_eligibility, resume_scoring, voice_tags).
operationId: listQuestions
parameters:
- name: posting_id
in: path
required: true
schema:
type: string
title: Posting Id
- name: modality
in: query
required: false
schema:
anyOf:
- enum:
- voice
- sms
- form
- resume_eligibility
- resume_scoring
- voice_tags
type: string
- type: 'null'
description: 'Filter by question modality: voice, sms, form, resume_eligibility, resume_scoring, voice_tags.'
title: Modality
description: 'Filter by question modality: voice, sms, form, resume_eligibility, resume_scoring, voice_tags.'
- name: limit
in: query
required: false
schema:
type: integer
maximum: 100
minimum: 1
default: 20
title: Limit
- name: starting_after
in: query
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Starting After
- name: X-API-KEY
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: X-Api-Key
- name: Authorization
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Authorization
- name: X-Workspace-Id
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: X-Workspace-Id
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/ListResponse_QuestionResponse_'
'401':
description: Invalid or missing API key.
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'404':
description: Resource not found.
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'429':
description: Rate limit exceeded.
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
post:
tags:
- Questions
summary: Create a question
description: Creates a new question or criterion for a posting. The ``modality`` field determines the question type.
operationId: createQuestion
parameters:
- name: posting_id
in: path
required: true
schema:
type: string
title: Posting Id
- name: X-API-KEY
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: X-Api-Key
- name: Authorization
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Authorization
- name: X-Workspace-Id
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: X-Workspace-Id
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateQuestionRequest'
responses:
'201':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/SingleResponse_QuestionResponse_'
'401':
description: Invalid or missing API key.
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'404':
description: Resource not found.
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'429':
description: Rate limit exceeded.
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
/api/v2/postings/{posting_id}/questions/{question_id}:
get:
tags:
- Questions
summary: Retrieve a question
description: Returns a single question or criterion by its ID.
operationId: getQuestion
parameters:
- name: posting_id
in: path
required: true
schema:
type: string
title: Posting Id
- name: question_id
in: path
required: true
schema:
type: string
title: Question Id
- name: X-API-KEY
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: X-Api-Key
- name: Authorization
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Authorization
- name: X-Workspace-Id
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: X-Workspace-Id
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/SingleResponse_QuestionResponse_'
'401':
description: Invalid or missing API key.
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'404':
description: Resource not found.
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'429':
description: Rate limit exceeded.
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
patch:
tags:
- Questions
summary: Update a question
description: Updates the specified question. Only fields present in the request body are modified; omitted fields remain unchanged.
operationId: updateQuestion
parameters:
- name: posting_id
in: path
required: true
schema:
type: string
title: Posting Id
- name: question_id
in: path
required: true
schema:
type: string
title: Question Id
- name: X-API-KEY
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: X-Api-Key
- name: Authorization
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Authorization
- name: X-Workspace-Id
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: X-Workspace-Id
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateQuestionRequest'
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/SingleResponse_QuestionResponse_'
'401':
description: Invalid or missing API key.
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'404':
description: Resource not found.
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'429':
description: Rate limit exceeded.
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
delete:
tags:
- Questions
summary: Delete a question
description: Soft-deletes a question or criterion. It will no longer appear in listings.
operationId: deleteQuestion
parameters:
- name: posting_id
in: path
required: true
schema:
type: string
title: Posting Id
- name: question_id
in: path
required: true
schema:
type: string
title: Question Id
- name: X-API-KEY
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: X-Api-Key
- name: Authorization
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Authorization
- name: X-Workspace-Id
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: X-Workspace-Id
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/SingleResponse_QuestionResponse_'
'401':
description: Invalid or missing API key.
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'404':
description: Resource not found.
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'429':
description: Rate limit exceeded.
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
/api/v2/postings/{posting_id}/questions/reorder:
post:
tags:
- Questions
summary: Reorder questions
description: Sets the display order for questions of a given modality. You must include every active question ID for the specified modality in the desired order.
operationId: reorderQuestions
parameters:
- name: posting_id
in: path
required: true
schema:
type: string
title: Posting Id
- name: X-API-KEY
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: X-Api-Key
- name: Authorization
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Authorization
- name: X-Workspace-Id
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: X-Workspace-Id
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ReorderQuestionsRequest'
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/ListResponse_QuestionResponse_'
'401':
description: Invalid or missing API key.
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'404':
description: Resource not found.
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'429':
description: Rate limit exceeded.
content:
application/json:
schema:
$ref: '#/components/schemas/APIErrorResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
components:
schemas:
APIErrorDetail:
properties:
code:
type: string
title: Code
description: Machine-readable error code
examples:
- invalid_param
message:
type: string
title: Message
description: Human-readable explanation
examples:
- title must be between 3 and 200 characters
param:
anyOf:
- type: string
- type: 'null'
title: Param
description: Parameter that caused the error
examples:
- title
type: object
required:
- code
- message
title: APIErrorDetail
ReorderQuestionsRequest:
properties:
modality:
type: string
enum:
- voice
- sms
- form
- resume_eligibility
- resume_scoring
- voice_tags
title: Modality
description: 'Modality to reorder: voice, sms, form, resume_eligibility, resume_scoring, voice_tags.'
examples:
- voice
order:
items:
type: string
type: array
title: Order
description: Ordered list of question IDs. Every active question for the specified modality must be included.
examples:
- - Q1
- Q3
- Q2
type: object
required:
- modality
- order
title: ReorderQuestionsRequest
description: Request body for reordering questions within a modality.
APIErrorResponse:
properties:
error:
$ref: '#/components/schemas/APIError'
type: object
required:
- error
title: APIErrorResponse
PaginationMeta:
properties:
has_more:
type: boolean
title: Has More
description: Whether more results exist beyond this page
total_count:
anyOf:
- type: integer
- type: 'null'
title: Total Count
description: Total number of results (if available)
url:
anyOf:
- type: string
- type: 'null'
title: Url
description: URL of this resource
type: object
required:
- has_more
title: PaginationMeta
HTTPValidationError:
properties:
detail:
items:
$ref: '#/components/schemas/ValidationError'
type: array
title: Detail
type: object
title: HTTPValidationError
CreateQuestionRequest:
properties:
modality:
type: string
enum:
- voice
- sms
- form
- resume_eligibility
- resume_scoring
- voice_tags
title: Modality
description: 'Question modality: voice, sms, form, resume_eligibility, resume_scoring, voice_tags.'
examples:
- voice
text:
type: string
title: Text
description: The question text, criterion text, or tag name.
examples:
- Tell me about a challenging project you led.
evaluation_criteria:
anyOf:
- type: string
- type: 'null'
title: Evaluation Criteria
description: Evaluation criteria.
score_of_1:
anyOf:
- type: string
- type: 'null'
title: Score Of 1
description: Score-1 description.
score_of_5:
anyOf:
- type: string
- type: 'null'
title: Score Of 5
description: Score-5 description.
score_weight:
anyOf:
- type: integer
maximum: 10.0
minimum: 1.0
- type: 'null'
title: Score Weight
description: Importance weight for scoring (1–10).
not_scored:
anyOf:
- type: boolean
- type: 'null'
title: Not Scored
description: Ask but don't score.
question_type:
anyOf:
- type: string
- type: 'null'
title: Question Type
description: Question format.
min_follow_ups:
anyOf:
- type: integer
minimum: 0.0
- type: 'null'
title: Min Follow Ups
description: Min follow-ups.
max_follow_ups:
anyOf:
- type: integer
minimum: 0.0
- type: 'null'
title: Max Follow Ups
description: Max follow-ups.
additional_instructions:
anyOf:
- type: string
- type: 'null'
title: Additional Instructions
description: Per-question instructions.
post_processing_evaluation_criteria:
anyOf:
- type: string
- type: 'null'
title: Post Processing Evaluation Criteria
description: Post-interview evaluation criteria.
expected_answer:
anyOf:
- type: string
- type: 'null'
title: Expected Answer
description: Expected answer (SMS).
expected_value:
anyOf:
- type: integer
- type: 'null'
title: Expected Value
description: Expected numeric value (SMS).
is_dealbreaker:
anyOf:
- type: boolean
- type: 'null'
title: Is Dealbreaker
description: Dealbreaker flag (SMS).
answer:
anyOf:
- {}
- type: 'null'
title: Answer
description: Expected answer (form).
is_knockout:
anyOf:
- type: boolean
- type: 'null'
title: Is Knockout
description: Knockout flag (form).
dropdown_values:
anyOf:
- items:
additionalProperties:
type: string
type: object
type: array
- type: 'null'
title: Dropdown Values
description: Dropdown options.
is_answer_mandated:
anyOf:
- type: boolean
- type: 'null'
title: Is Answer Mandated
description: Require answer (form).
mcq_type:
anyOf:
- type: string
- type: 'null'
title: Mcq Type
description: MCQ type (form).
operator:
anyOf:
- type: string
- type: 'null'
title: Operator
description: Validation operator (form).
file_types:
anyOf:
- items:
type: string
type: array
- type: 'null'
title: File Types
description: Allowed file types (form).
allow_multiple_files:
anyOf:
- type: boolean
- type: 'null'
title: Allow Multiple Files
description: Multiple files (form).
slider_min:
anyOf:
- type: number
- type: 'null'
title: Slider Min
description: Slider min (form).
slider_max:
anyOf:
- type: number
- type: 'null'
title: Slider Max
description: Slider max (form).
slider_step:
anyOf:
- type: number
- type: 'null'
title: Slider Step
description: Slider step (form).
response_format:
anyOf:
- type: string
enum:
- text
- freeform
- date
- number
- type: 'null'
title: Response Format
description: 'Response format for voice_tags: ''text'', ''freeform'', ''date'', or ''number''.'
instructions:
anyOf:
- type: string
- type: 'null'
title: Instructions
description: Instructions (voice_tags).
options:
anyOf:
- items:
type: string
type: array
- type: 'null'
title: Options
description: Options (voice_tags).
structured_config:
anyOf:
- additionalProperties: true
type: object
- type: 'null'
title: Structured Config
description: Advanced structured configuration (voice). Opaque key-value object forwarded to the AI interviewer.
type: object
required:
- modality
- text
title: CreateQuestionRequest
description: 'Request body for creating a new question or criterion.
The ``modality`` field determines the question type. Only fields
relevant to the chosen modality need to be provided.'
UpdateQuestionRequest:
properties:
text:
anyOf:
- type: string
- type: 'null'
title: Text
description: Updated question text.
evaluation_criteria:
anyOf:
- type: string
- type: 'null'
title: Evaluation Criteria
description: Updated evaluation criteria.
score_of_1:
anyOf:
- type: string
- type: 'null'
title: Score Of 1
description: Updated score-1 description.
score_of_5:
anyOf:
- type: string
- type: 'null'
title: Score Of 5
description: Updated score-5 description.
score_weight:
anyOf:
- type: integer
maximum: 10.0
minimum: 1.0
- type: 'null'
title: Score Weight
description: Updated importance weight for scoring (1–10).
not_scored:
anyOf:
- type: boolean
- type: 'null'
title: Not Scored
description: Updated not-scored flag.
question_type:
anyOf:
- type: string
- type: 'null'
title: Question Type
description: Updated question format.
min_follow_ups:
anyOf:
- type: integer
minimum: 0.0
- type: 'null'
title: Min Follow Ups
description: Updated min follow-ups.
max_follow_ups:
anyOf:
- type: integer
minimum: 0.0
- type: 'null'
title: Max Follow Ups
description: Updated max follow-ups.
additional_instructions:
anyOf:
- type: string
- type: 'null'
title: Additional Instructions
description: Updated instructions.
post_processing_evaluation_criteria:
anyOf:
- type: string
- type: 'null'
title: Post Processing Evaluation Criteria
description: Updated post-processing criteria.
expected_answer:
anyOf:
- type: string
- type: 'null'
title: Expected Answer
description: Updated expected answer.
expected_value:
anyOf:
- type: integer
- type: 'null'
title: Expected Value
description: Updated expected value.
is_dealbreaker:
anyOf:
- type: boolean
- type: 'null'
title: Is Dealbreaker
description: Updated dealbreaker flag.
answer:
anyOf:
- {}
- type: 'null'
title: Answer
description: Updated expected answer (form).
is_knockout:
anyOf:
- type: boolean
- type: 'null'
title: Is Knockout
description: Updated knockout flag.
dropdown_values:
anyOf:
- items:
additionalProperties:
type: string
type: object
type: array
- type: 'null'
title: Dropdown Values
description: Updated dropdown options.
is_answer_mandated:
anyOf:
- type: boolean
- type: 'null'
title: Is Answer Mandated
description: Updated require-answer flag.
mcq_type:
anyOf:
- type: string
- type: 'null'
title: Mcq Type
description: Updated MCQ type.
operator:
anyOf:
- type: string
- type: 'null'
title: Operator
description: Updated operator.
file_types:
anyOf:
- items:
type: string
type: array
- type: 'null'
title: File Types
description: Updated file types.
allow_multiple_files:
anyOf:
- type: boolean
- type: 'null'
title: Allow Multiple Files
description: Updated multiple files flag.
slider_min:
anyOf:
- type: number
- type: 'null'
title: Slider Min
description: Updated slider min.
slider_max:
anyOf:
- type: number
- type: 'null'
title: Slider Max
description: Updated slider max.
slider_step:
anyOf:
- type: number
- type: 'null'
title: Slider Step
description: Updated slider step.
response_format:
anyOf:
- type: string
enum:
- text
- freeform
- date
- number
- type: 'null'
title: Response Format
description: 'Updated response format: ''text'', ''freeform'', ''date'', or ''number''.'
instructions:
anyOf:
- type: string
- type: 'null'
title: Instructions
description: Updated instructions.
options:
anyOf:
- items:
type: string
type: array
- type: 'null'
title: Options
description: Updated options.
structured_config:
anyOf:
- additionalProperties: true
type: object
- type: 'null'
title: Structured Config
description: Updated advanced structured configuration (voice).
type: object
title: UpdateQuestionRequest
description: 'Request body for updating a question.
Only provided fields are modified; omitted fields remain unchanged.'
QuestionResponse:
properties:
object:
type: string
const: question
title: Object
description: Object type identifier.
default: question
id:
type: string
title: Id
description: Unique question/criterion identifier.
examples:
- A1B2C3D4
posting_id:
type: string
title: Posting Id
description: ID of the posting this question belongs to.
examples:
- 13D77095
modality:
type: string
title: Modality
description: 'Question modality: voice, sms, form, resume_eligibility, resume_scoring, voice_tags.'
examples:
- voice
text:
type: string
title: Text
description: The question text, criterion text, or tag name.
examples:
- Tell me about a challenging project you led.
rank:
anyOf:
- type: integer
- type: 'null'
title: Rank
description: Display order (1-based). Lower ranks appear first.
examples:
- 1
evaluation_criteria:
anyOf:
- type: string
- type: 'null'
title: Evaluation Criteria
description: Evaluation criteria for scoring.
score_of_1:
anyOf:
- type: string
- type: 'null'
title: Score Of 1
description: Description of what a score of 1 means.
score_of_5:
anyOf:
- type: string
- type: 'null'
title: Score Of 5
description: Description of what a score of 5 means.
score_weight:
anyOf:
- type: integer
- type: 'null'
title: Score Weight
description: Importance weight for scoring (1–10).
not_scored:
anyOf:
- type: boolean
- type: 'null'
title: Not Scored
description: Whether this question is asked but not scored (voice).
question_type:
anyOf:
- type: string
- type: 'null'
title: Question Type
description: 'Question format. For voice: ''open-ended'' or ''scored''. Auto-inferred by the backend for SMS (''YES_NO'', ''NUMERIC'') and form (''dropdown'', ''file_upload'', ''slider'', etc.) modalities.'
min_follow_ups:
anyOf:
- type: integer
- type: 'null'
title: Min Follow Ups
description: Minimum follow-up questions (voice).
max_follow_ups:
anyOf:
- type: integer
- type: 'null'
title: Max Follow Ups
description: Maximum follow-up questions (voice).
additional_instructions:
anyOf:
- type: string
- type: 'null'
title: Additional Instructions
description: Per-question instructions for the AI interviewer.
post_processing_evaluation_criteria:
anyOf:
- type: string
- type: 'null'
title: Post Processing Evaluation Criteria
description: Evaluation criteria applied post-interview.
expected_answer:
anyOf:
- type: string
- type: 'null'
title: Expected Answer
description: Expected answer text (SMS yes/no).
expected_value:
anyOf:
- type: integer
- type: 'null'
title: Expected Value
description: Expected numeric value (SMS numeric).
is_dealbreaker:
anyOf:
- type: boolean
- type: 'null'
title: Is Dealbreaker
description: Whether wrong answer disqualifies (SMS).
answer:
anyOf:
- {}
- type: 'null'
title: Answer
description: Expected answer for knockout evaluation (form).
is_knockout:
anyOf:
- type: boolean
- type: 'null'
title: Is Knockout
description: Whet
# --- truncated at 32 KB (38 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/heymilo/refs/heads/main/openapi/heymilo-questions-api-openapi.yml