Hail Agents API
The agents API from Hail — 2 operation(s) for agents.
The agents API from Hail — 2 operation(s) for agents.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
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.curl "https://apis.io/api/v1/apis/hail-so:hail-so-agents-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Hail Agents API
description: 'Give your AI agent a voice, a real phone number, and an inbox.
This file is the source of truth for the Go CLI. Regenerate it after
changing API routes — see docs/public/contributing.md.'
version: 0.1.0
servers:
- url: https://api.hail.so
description: Hail Cloud
tags:
- name: Agents
paths:
/v1/agents:
post:
tags:
- Agents
summary: Create Agent
description: 'Create an agent. Route numbers to it with PATCH /numbers/{id}, or
place calls with it via ``agent_id`` on POST /calls.'
operationId: create_agent_v1_agents_post
parameters:
- name: authorization
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Authorization
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/AgentCreate'
responses:
'201':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/AgentResponse'
'429':
description: Rate limited. This caller exceeded the general request-rate ceiling. Retry after the Retry-After header (seconds).
headers:
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
RateLimit-Limit:
description: The request ceiling for the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests remaining in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the current window resets.
schema:
type: integer
'409':
description: An agent with this name already exists, or a handover contact changed while saving.
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
get:
tags:
- Agents
summary: List Agents
description: List the organization's agents, newest first.
operationId: list_agents_v1_agents_get
parameters:
- name: authorization
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Authorization
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/AgentListResponse'
'429':
description: Rate limited. This caller exceeded the general request-rate ceiling. Retry after the Retry-After header (seconds).
headers:
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
RateLimit-Limit:
description: The request ceiling for the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests remaining in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the current window resets.
schema:
type: integer
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
/v1/agents/{agent_id}:
get:
tags:
- Agents
summary: Get Agent
description: Fetch one agent by id, including its instructions and voice settings.
operationId: get_agent_v1_agents__agent_id__get
parameters:
- name: agent_id
in: path
required: true
schema:
type: string
format: uuid
title: Agent Id
- name: authorization
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Authorization
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/AgentResponse'
'429':
description: Rate limited. This caller exceeded the general request-rate ceiling. Retry after the Retry-After header (seconds).
headers:
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
RateLimit-Limit:
description: The request ceiling for the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests remaining in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the current window resets.
schema:
type: integer
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
patch:
tags:
- Agents
summary: Update Agent
description: 'Change some fields. Fields left out keep their value; ``null`` clears
first_message, ai_disclosure_line, tools, max_duration_seconds or
handover_max_duration_seconds. Live
calls keep the settings they started with. ``handover_contacts`` replaces
the list; ``[]`` clears it and ``null`` leaves it.'
operationId: update_agent_v1_agents__agent_id__patch
parameters:
- name: agent_id
in: path
required: true
schema:
type: string
format: uuid
title: Agent Id
- name: authorization
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Authorization
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/AgentUpdate'
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/AgentResponse'
'429':
description: Rate limited. This caller exceeded the general request-rate ceiling. Retry after the Retry-After header (seconds).
headers:
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
RateLimit-Limit:
description: The request ceiling for the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests remaining in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the current window resets.
schema:
type: integer
'409':
description: An agent with this name already exists, or a handover contact changed while saving.
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
delete:
tags:
- Agents
summary: Delete Agent
description: 'Delete an agent. Numbers that routed calls to it are unregistered
for inbound and ring out again; numbers that routed texts to it go back
to webhooks only.'
operationId: delete_agent_v1_agents__agent_id__delete
parameters:
- name: agent_id
in: path
required: true
schema:
type: string
format: uuid
title: Agent Id
- name: authorization
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Authorization
responses:
'204':
description: Successful Response
'429':
description: Rate limited. This caller exceeded the general request-rate ceiling. Retry after the Retry-After header (seconds).
headers:
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
RateLimit-Limit:
description: The request ceiling for the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests remaining in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the current window resets.
schema:
type: integer
'502':
description: A number could not be taken off the inbound trunk; nothing was deleted.
'503':
description: A number is registered for inbound calls and this server is not configured for them; nothing was deleted.
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
components:
schemas:
AgentUpdate:
properties:
name:
anyOf:
- type: string
maxLength: 80
minLength: 1
- type: 'null'
title: Name
description: New display name.
system_prompt:
anyOf:
- type: string
minLength: 1
- type: 'null'
title: System Prompt
description: New task instructions.
first_message:
anyOf:
- type: string
maxLength: 1000
- type: 'null'
title: First Message
description: New opening line; null makes the agent wait for the other side.
recording_enabled:
anyOf:
- type: boolean
- type: 'null'
title: Recording Enabled
description: Null inherits workspace recording; true or false sets it for this agent's calls.
ai_disclosure:
anyOf:
- type: boolean
- type: 'null'
title: Ai Disclosure
description: Whether the AI line is spoken first.
ai_disclosure_line:
anyOf:
- type: string
maxLength: 300
- type: 'null'
title: Ai Disclosure Line
description: New AI line template ('{org}' = organization name); null returns to the workspace line.
voice_config:
anyOf:
- $ref: '#/components/schemas/VoiceConfig'
- type: 'null'
description: New TTS voice and language settings.
tools:
anyOf:
- items:
type: string
type: array
- type: 'null'
title: Tools
description: New allowed tools; null allows every tool.
max_duration_seconds:
anyOf:
- type: integer
maximum: 3600.0
minimum: 60.0
- type: 'null'
title: Max Duration Seconds
description: New soft cap per call; null returns to the workspace limit.
handover_max_duration_seconds:
anyOf:
- type: integer
maximum: 3600.0
minimum: 60.0
- type: 'null'
title: Handover Max Duration Seconds
description: New call limit after a handover contact answers; null returns to 1800 (30 minutes).
voice_enabled:
anyOf:
- type: boolean
- type: 'null'
title: Voice Enabled
description: Whether the agent answers calls.
sms_enabled:
anyOf:
- type: boolean
- type: 'null'
title: Sms Enabled
description: Whether the agent answers texts.
status:
anyOf:
- type: string
enum:
- live
- paused
- type: 'null'
title: Status
description: '''live'' or ''paused''.'
handover_contacts:
anyOf:
- items:
$ref: '#/components/schemas/HandoverContactIn'
type: array
maxItems: 10
- type: 'null'
title: Handover Contacts
description: New handover list; replaces the old one. [] removes all; null leaves it.
additionalProperties: false
type: object
title: AgentUpdate
description: 'PATCH /agents/{id}. Fields left out keep their value; ``null`` clears
the nullable ones (first_message, ai_disclosure_line, tools,
max_duration_seconds, handover_max_duration_seconds).'
HandoverContactIn:
properties:
contact_id:
type: string
title: Contact Id
description: 'A person with a phone number, as GET /contacts returns it: a contact''s id, or `member:<user id>` for a team member.'
examples:
- member:6f1c2a9e-3b7d-4c51-9a8e-2d4f6b1e0c37
note:
type: string
maxLength: 200
minLength: 1
title: Note
description: When the agent should hand over to this person, e.g. 'billing questions'. Read by the agent.
additionalProperties: false
type: object
required:
- contact_id
- note
title: HandoverContactIn
AgentResponse:
properties:
id:
type: string
format: uuid
title: Id
description: Unique identifier for this agent.
organization_id:
type: string
format: uuid
title: Organization Id
description: Organization that owns this agent.
name:
type: string
title: Name
description: Display name, unique per organization.
system_prompt:
type: string
title: System Prompt
description: Task instructions.
first_message:
anyOf:
- type: string
- type: 'null'
title: First Message
description: Opening line, or null to wait.
recording_enabled:
anyOf:
- type: boolean
- type: 'null'
title: Recording Enabled
description: Null inherits the workspace recording choice; true or false sets recording for this agent's calls, whatever the workspace setting.
ai_disclosure:
type: boolean
title: Ai Disclosure
description: Whether the AI line is spoken first.
ai_disclosure_line:
anyOf:
- type: string
- type: 'null'
title: Ai Disclosure Line
description: This agent's AI line template, or null for the workspace line.
voice_config:
additionalProperties: true
type: object
title: Voice Config
description: TTS voice and language settings.
tools:
anyOf:
- items:
type: string
type: array
- type: 'null'
title: Tools
description: Allowed tools; null means all.
max_duration_seconds:
anyOf:
- type: integer
- type: 'null'
title: Max Duration Seconds
description: Soft cap per call; null means the workspace limit.
handover_max_duration_seconds:
anyOf:
- type: integer
- type: 'null'
title: Handover Max Duration Seconds
description: Call limit after a handover contact answers; null means 1800 (30 minutes).
voice_enabled:
type: boolean
title: Voice Enabled
description: Whether the agent answers calls.
sms_enabled:
type: boolean
title: Sms Enabled
description: Whether the agent answers texts.
status:
type: string
enum:
- live
- paused
title: Status
description: '''live'' or ''paused''.'
handover_contacts:
items:
$ref: '#/components/schemas/HandoverContactOut'
type: array
title: Handover Contacts
description: People the agent may hand a live call to.
created_at:
type: string
format: date-time
title: Created At
description: ISO 8601 timestamp.
updated_at:
type: string
format: date-time
title: Updated At
description: ISO 8601 timestamp.
type: object
required:
- id
- organization_id
- name
- system_prompt
- first_message
- ai_disclosure
- ai_disclosure_line
- voice_config
- tools
- max_duration_seconds
- handover_max_duration_seconds
- voice_enabled
- sms_enabled
- status
- created_at
- updated_at
title: AgentResponse
HTTPValidationError:
properties:
detail:
items:
$ref: '#/components/schemas/ValidationError'
type: array
title: Detail
description: 'List of validation errors: each entry gives the field location (loc), the problem (msg), and the error type (type).'
type: object
title: HTTPValidationError
ValidationError:
properties:
loc:
items:
anyOf:
- type: string
- type: integer
type: array
title: Location
description: Path to the invalid field within the request, as a list of keys/indices (e.g. ['body', 'to']).
msg:
type: string
title: Message
description: Human-readable description of the validation failure.
type:
type: string
title: Error Type
description: Machine-readable error type code (e.g. 'missing', 'string_type').
input:
title: Input
description: The value that was actually provided and failed validation.
ctx:
type: object
title: Context
description: Additional machine-readable context for the error, when the error type provides one.
type: object
required:
- loc
- msg
- type
title: ValidationError
VoiceConfig:
properties:
tts:
type: string
const: cartesia
title: Tts
description: Text-to-speech provider. Currently only 'cartesia'.
default: cartesia
vad:
type: string
const: silero
title: Vad
description: Voice-activity-detection engine. Currently only 'silero'.
default: silero
turn_detection:
type: string
const: livekit
title: Turn Detection
description: Turn-detection engine. Currently only 'livekit'.
default: livekit
voice_id:
anyOf:
- type: string
- type: 'null'
title: Voice Id
description: 'Per-call TTS voice override, applied to whichever TTS provider serves the call. Omitted: the organization''s or environment''s default voice.'
language:
anyOf:
- type: string
enum:
- ar
- bg
- bn
- cs
- da
- de
- el
- en
- es
- fi
- fr
- gu
- he
- hi
- hr
- hu
- id
- it
- ja
- kn
- ko
- mr
- ms
- nl
- 'no'
- pl
- pt
- ro
- ru
- sk
- sv
- ta
- te
- th
- tl
- tr
- uk
- vi
- zh
- type: 'null'
title: Language
description: 'Spoken language for the call as a lowercase ISO 639-1 code (e.g. ''da''). One of the 39 supported codes — see docs/languages.md. Applied to STT, TTS, and turn detection. Omitted: the providers'' defaults (English).'
additionalProperties: false
type: object
title: VoiceConfig
HandoverContactOut:
properties:
contact_id:
type: string
title: Contact Id
description: 'The person: a contact''s id, or `member:<user id>` for a team member.'
name:
type: string
title: Name
description: Name, as the agent says it.
phone_e164:
anyOf:
- type: string
- type: 'null'
title: Phone E164
description: Number Hail dials. Null when the contact lost its number; it is then skipped.
note:
type: string
title: Note
description: When the agent hands over to this person.
type: object
required:
- contact_id
- name
- phone_e164
- note
title: HandoverContactOut
AgentCreate:
properties:
name:
type: string
maxLength: 80
minLength: 1
title: Name
description: Display name, unique per organization.
system_prompt:
type: string
minLength: 1
title: System Prompt
description: Task instructions, sent as the agent's leading system message.
first_message:
anyOf:
- type: string
maxLength: 1000
- type: 'null'
title: First Message
description: 'Opening line spoken after the AI line. Omitted: the agent waits for the other side to speak first.'
recording_enabled:
anyOf:
- type: boolean
- type: 'null'
title: Recording Enabled
description: Null inherits the workspace recording choice; true or false sets recording for this agent's calls, whatever the workspace setting.
ai_disclosure:
type: boolean
title: Ai Disclosure
description: Speak the AI line first on every call. Enabled by default. Disable only if you have verified the disclosure is not required (47 CFR 64.1200(b)(1) and several AI bot-disclosure laws). Hail does not verify this for you.
default: true
ai_disclosure_line:
anyOf:
- type: string
maxLength: 300
- type: 'null'
title: Ai Disclosure Line
description: 'The AI line this agent speaks. ''{org}'' is replaced by the organization''s name. Omitted: the workspace line, else Hail''s built-in line for the call''s direction.'
voice_config:
$ref: '#/components/schemas/VoiceConfig'
description: TTS voice and spoken language, same shape as on POST /calls.
tools:
anyOf:
- items:
type: string
type: array
- type: 'null'
title: Tools
description: 'Agent tools to allow. Omitted: every tool the organization''s channels support. Empty list: none.'
max_duration_seconds:
anyOf:
- type: integer
maximum: 3600.0
minimum: 60.0
- type: 'null'
title: Max Duration Seconds
description: 'Soft cap per call in seconds (60..3600). Omitted: the workspace limit.'
handover_max_duration_seconds:
anyOf:
- type: integer
maximum: 3600.0
minimum: 60.0
- type: 'null'
title: Handover Max Duration Seconds
description: 'Call limit in seconds (60..3600) once a handover contact answers, counted from the answer. Omitted: 1800 (30 minutes).'
voice_enabled:
type: boolean
title: Voice Enabled
description: Answer calls on numbers that route calls to this agent.
default: true
sms_enabled:
type: boolean
title: Sms Enabled
description: Answer texts on numbers that route texts to this agent.
default: true
status:
type: string
enum:
- live
- paused
title: Status
description: '''paused'' agents do not answer; calls to their numbers fail with end_reason ''no_agent''.'
default: live
handover_contacts:
items:
$ref: '#/components/schemas/HandoverContactIn'
type: array
maxItems: 10
title: Handover Contacts
description: People the agent may hand a live call to, in order. The agent never sees their numbers.
additionalProperties: false
type: object
required:
- name
- system_prompt
title: AgentCreate
description: 'A saved agent: what a number answers with, and what POST /calls can
place calls with via ``agent_id``.'
AgentListResponse:
properties:
items:
items:
$ref: '#/components/schemas/AgentResponse'
type: array
title: Items
description: Agents, newest first.
type: object
required:
- items
title: AgentListResponse