Hellou AI · Schema
call
A phone call, as kept in the call history -- a WhatsApp call or a call an AI agent answered.
Artificial IntelligenceCommunicationsCustomer ServiceWhatsAppSoftware-as-a-Service
Properties
| Name | Type | Description |
|---|---|---|
| id | integer | |
| provider | string | `ai_agent` for a phone call an AI agent answered on one of the account's phone lines. |
| direction | string | |
| status | string | `ringing` and `in_progress` are live calls; the rest are final. `completed` was answered, `no_answer` rang out or was hung up before pickup, `rejected` was declined. |
| end_reason | stringnull | Why the call ended, for example `agent_hangup` or `contact_hangup`. |
| duration_seconds | integernull | Talk time, from pickup to hang-up. |
| created_at | string | When the call started ringing. |
| started_at | stringnull | When it was picked up. |
| ended_at | stringnull | |
| from_number | stringnull | |
| to_number | stringnull | |
| inbox | object | |
| contact | object | |
| conversation_id | integer | Display ID of the conversation the call belongs to. |
| message_id | integernull | The call's entry in the conversation. |
| accepted_by_agent | objectnull | |
| recording_url | stringnull | A link to the recording, when the agent's browser uploaded one. |
| recording_duration_s | numbernull | Length of the recording in seconds, as measured by the edge. Null when unknown. |
| ai_handled | boolean | Whether an AI agent answered the call. Its words are at the call's `transcript` path. |
| engine | stringnull | The voice engine that answered an AI call: `realtime` (speech to speech), `live` (full duplex, answered by the agent's own model) or `premium` (regional-accent voices, answered by the agent's own mode |
| agent_bot | objectnull | The AI agent that answered. |
| voice_line_id | integernull | The phone line the call came in on. |
| parent_call_id | integernull | For a call an AI agent handed to another AI agent, the call's first leg; each leg is its own call. Null for a first leg and for any other call. |
| ai_transfer_hop | integernull | On a leg that follows a hand-off between AI agents, the number of the pass that started it. Null on any other call. |
| sentiment | objectnull | The caller's mood at the start and at the end of an AI call, read the way Sentiment reads a chat. Null until the call is read. |
| call_outcome | object | |
| dial_cause | object | |
| disposition_gap | object | |
| campaign_id | integernull | The voice campaign the call was placed for. |
| campaign_contact_id | integernull | The campaign contact the call was placed to. |
| campaign_interest | stringnull | The interest recorded for the campaign contact this call was placed to. Null when the call has no campaign contact or no interest yet. |
| updated_at | string |
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://artifacts.apis.io/hellou-ai/json-schema/hellou-ai-call-schema.json",
"title": "call",
"description": "A phone call, as kept in the call history -- a WhatsApp call or a call an AI agent answered.",
"x-generated": "2026-11-11",
"x-method": "derived",
"x-generator": "derive-json-schema.py",
"x-source": "openapi/hellou-ai-openapi.json#/components/schemas/call",
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"provider": {
"type": "string",
"enum": [
"whatsapp",
"ai_agent"
],
"description": "`ai_agent` for a phone call an AI agent answered on one of the account's phone lines."
},
"direction": {
"type": "string",
"enum": [
"incoming",
"outgoing"
]
},
"status": {
"type": "string",
"enum": [
"ringing",
"in_progress",
"completed",
"no_answer",
"failed",
"rejected"
],
"description": "`ringing` and `in_progress` are live calls; the rest are final. `completed` was answered,\n`no_answer` rang out or was hung up before pickup, `rejected` was declined.\n"
},
"end_reason": {
"type": [
"string",
"null"
],
"description": "Why the call ended, for example `agent_hangup` or `contact_hangup`."
},
"duration_seconds": {
"type": [
"integer",
"null"
],
"description": "Talk time, from pickup to hang-up."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "When the call started ringing."
},
"started_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "When it was picked up."
},
"ended_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"from_number": {
"type": [
"string",
"null"
]
},
"to_number": {
"type": [
"string",
"null"
]
},
"inbox": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
},
"required": [
"id",
"name"
]
},
"contact": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": [
"string",
"null"
]
},
"phone_number": {
"type": [
"string",
"null"
]
}
},
"required": [
"id"
]
},
"conversation_id": {
"type": "integer",
"description": "Display ID of the conversation the call belongs to."
},
"message_id": {
"type": [
"integer",
"null"
],
"description": "The call's entry in the conversation."
},
"accepted_by_agent": {
"type": [
"object",
"null"
],
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"recording_url": {
"type": [
"string",
"null"
],
"description": "A link to the recording, when the agent's browser uploaded one."
},
"recording_duration_s": {
"type": [
"number",
"null"
],
"description": "Length of the recording in seconds, as measured by the edge. Null when unknown."
},
"ai_handled": {
"type": "boolean",
"description": "Whether an AI agent answered the call. Its words are at the call's `transcript` path."
},
"engine": {
"type": [
"string",
"null"
],
"enum": [
"realtime",
"live",
"premium",
null
],
"description": "The voice engine that answered an AI call: `realtime` (speech to speech), `live` (full duplex, answered by the agent's own model) or `premium` (regional-accent voices, answered by the agent's own model). Until 2026-10-20 this engine went out under another value; match `premium`."
},
"agent_bot": {
"type": [
"object",
"null"
],
"description": "The AI agent that answered.",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"voice_line_id": {
"type": [
"integer",
"null"
],
"description": "The phone line the call came in on."
},
"parent_call_id": {
"type": [
"integer",
"null"
],
"description": "For a call an AI agent handed to another AI agent, the call's first leg; each leg is its own call. Null for a first leg and for any other call."
},
"ai_transfer_hop": {
"type": [
"integer",
"null"
],
"description": "On a leg that follows a hand-off between AI agents, the number of the pass that started it. Null on any other call."
},
"sentiment": {
"type": [
"object",
"null"
],
"description": "The caller's mood at the start and at the end of an AI call, read the way Sentiment reads a chat. Null until the call is read.",
"properties": {
"opening": {
"type": "string",
"enum": [
"positive",
"neutral",
"negative"
]
},
"closing": {
"type": "string",
"enum": [
"positive",
"neutral",
"negative"
]
}
}
},
"call_outcome": {
"$ref": "#/$defs/call_outcome"
},
"dial_cause": {
"$ref": "#/$defs/call_dial_cause"
},
"disposition_gap": {
"$ref": "#/$defs/call_disposition_gap"
},
"campaign_id": {
"type": [
"integer",
"null"
],
"description": "The voice campaign the call was placed for."
},
"campaign_contact_id": {
"type": [
"integer",
"null"
],
"description": "The campaign contact the call was placed to."
},
"campaign_interest": {
"type": [
"string",
"null"
],
"enum": [
"interested",
"undecided",
"not_interested",
"not_presented",
null
],
"description": "The interest recorded for the campaign contact this call was placed to. Null when the call has no campaign contact or no interest yet."
},
"updated_at": {
"type": "string",
"format": "date-time"
}
},
"required": [
"id",
"provider",
"direction",
"status",
"created_at",
"inbox",
"contact",
"conversation_id",
"ai_handled"
],
"$defs": {
"call_dial_cause": {
"type": [
"object",
"null"
],
"description": "Why a call HellouOne placed reached nobody. `null` for a call under way, one a person talked on, or one that is not an outbound AI call.",
"properties": {
"code": {
"type": "string",
"enum": [
"voicemail_detected",
"busy",
"declined",
"unavailable",
"no_answer",
"number_not_found",
"no_route",
"carrier_rejected",
"timeout",
"platform_error",
"unknown"
],
"description": "The cause. `voicemail_detected` is a machine that answered, or a call the edge cancelled once the line started forwarding."
},
"reason": {
"type": "string",
"description": "The cause in words, localized, for example \"Number does not exist\"."
},
"sip_code": {
"type": "integer",
"description": "The final SIP response code of the dial, when one came back."
},
"sip_final": {
"type": "string",
"description": "The final SIP response code with its standard (RFC 3261) reason phrase, for example `404 Not Found`; a code the standard does not name is given alone."
},
"who": {
"type": "string",
"enum": [
"network",
"carrier",
"caller"
],
"description": "Who gave the final response. `network` is the phone network the call left from, `carrier` the contact's carrier, `caller` the side that placed the call."
},
"edge_action": {
"type": "string",
"enum": [
"cancel_on_181",
"caller_cancel"
],
"description": "What the phone edge did to the contact's leg on its own. `cancel_on_181` is its voicemail guard; `caller_cancel` is a leg dropped before anyone answered."
},
"ring_seconds": {
"type": "integer",
"description": "How long the contact's phone could have rung, from the dial request to the end of the call."
},
"source": {
"type": "string",
"enum": [
"edge",
"platform"
],
"description": "Where the cause was reported from, the phone edge or the voice platform."
}
},
"required": [
"code",
"reason"
]
},
"call_disposition_gap": {
"type": [
"object",
"null"
],
"description": "Why a voice campaign call ended with no disposition, when neither the AI agent nor the call summary chose one. `null` for any other call, a call the platform settled with its own disposition included.",
"properties": {
"reason": {
"type": "string",
"enum": [
"undetermined",
"missing",
"unknown",
"failed"
],
"description": "`undetermined`: the summary could not tell which disposition applied. `missing`: the summary named none. `unknown`: it named one the campaign does not have. `failed`: the summary could not be made."
},
"at": {
"type": "string",
"format": "date-time",
"description": "When the call was flagged."
}
},
"required": [
"reason",
"at"
]
},
"call_outcome": {
"type": [
"string",
"null"
],
"enum": [
"contained",
"escalated",
"voicemail",
"screening",
"unanswered",
"unreachable",
"unknown",
"error",
null
],
"description": "What an AI call came to. `null` for a call under way, one a person talked on (contained or escalated: the AI call report\ncounts those, the call record does not), or a call that is not an AI call. `voicemail`: a machine answered. `screening`: a call screener answered. `unanswered`:\nbusy, declined, off or rang out. `unreachable`: the number does not exist, has no route or was rejected by the carrier, or a carrier announcement said it is not available.\n`unknown`: the call's last event never arrived. `error`: the dial, the accept or the voice platform failed.\n"
}
}
}
Work with this as data
Every JSON Schema 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 schemas
4 MCP tools reach this
find_json_schemasBrowse and filter every JSON Schema in the catalog.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.
Call it yourself
curl for this page
This JSON Schema
curl "https://apis.io/api/v1/json-schemas/hellou-ai-call"
All schemas
curl "https://apis.io/api/v1/json-schemas?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Get an API 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.