Skip to content

Objects

What every lead endpoint answers with, and what lead events carry.

Field Type Required Notes
id string (uuid) yes
external_id string or null yes Your own ID for the lead.
campaign_id string (uuid) yes
name string or null yes
phone string yes +1 and 10 digits.
email string or null yes
address string or null yes
fields object yes Your custom fields.
consent Consent or null yes
consent.source string yes Where the lead agreed, for example web_form, crm or purchased_list. At most 100 characters.
consent.agreed_at string (date-time) yes When the lead agreed.
consent.text string The words the lead agreed to. Send text or url. At most 5000 characters.
consent.url string (uri) The page the lead agreed on. Send text or url.
consent.ip string The lead’s IP address when agreeing, if you have it.
lead_source string or null yes
owner object or null yes The SDR the latest call was dialed for, or null.
owner.id string yes
owner.name string yes
created string (date-time) yes
updated string (date-time) yes
status string yes Where the lead is now. See the Speed to lead guide for each word. One of new / queued / scheduled / held / dialing / on_call / callback_scheduled / done / out_of_queue.
call_now boolean yes
place_in_line integer or null yes 1 = next, 0 = being dialed now. Only on a single-lead read.
estimated_wait_seconds integer or null yes A guess, in seconds.
scheduled_for string (date-time) or null yes status scheduled: when the lead can be called.
scheduled_reason string or null yes One of outside_calling_hours / recent_contact_cooldown / retry_after_outcome / next_dial_time.
held_reason string or null yes One of campaign_paused / campaign_not_started / spend_cap_reached.
callback_at string (date-time) or null yes status callback_scheduled: the booked time (UTC).
late boolean yes A call_now lead that waited past the late limit (15 minutes by default).
attempts integer yes
last_outcome string or null yes A stable outcome word (see the Outcomes guide). null while there is no outcome yet. One of interested / not_interested / callback / voicemail / no_answer / busy / failed / dnc / wrong_number / hung_up / screened / language_barrier / not_qualified / undetermined / other.
last_outcome_label string or null yes
next_dial_at string (date-time) or null yes
calls array of LeadCallSummary yes The last 10 calls, newest first.
livemode boolean On every API reply. A lead inside a live event leaves it out.
{
"id": "2b8e4c1d-9f3a-4b7e-8c21-6a5d4e3f2b10",
"external_id": "crm-10442",
"campaign_id": "7c1f2b9e-4a3d-4e8f-9b21-5d6a7e8f9a01",
"name": "LEAD_NAME",
"phone": "+15555550142",
"email": "[email protected]",
"address": "1 Example Street, Springfield",
"fields": {
"roof_age": "12"
},
"consent": {
"source": "web_form",
"agreed_at": "2026-10-06T16:58:02Z",
"url": "https://example.com/quote"
},
"lead_source": "Example CRM",
"owner": null,
"created": "2026-10-06T16:58:04.000Z",
"updated": "2026-10-06T16:58:04.000Z",
"status": "queued",
"call_now": true,
"place_in_line": 3,
"estimated_wait_seconds": 90,
"scheduled_for": null,
"scheduled_reason": null,
"held_reason": null,
"callback_at": null,
"late": false,
"attempts": 0,
"last_outcome": null,
"last_outcome_label": null,
"next_dial_at": null,
"calls": [],
"livemode": true
}

What every call endpoint answers with, and what call events carry.

Field Type Required Notes
id string (uuid)
object string One of call.
livemode boolean
lead object or null
lead.id string (uuid)
lead.external_id string or null
lead.name string or null
lead.phone string or null E.164 (+1…)
campaign_id string (uuid) or null
direction string One of outbound / inbound.
status string One of ringing / in_progress / ended.
outcome string or null A stable word. null while the call has no outcome yet; other only for a label we don’t know (see outcome_label). One of interested / not_interested / callback / voicemail / no_answer / busy / failed / dnc / wrong_number / hung_up / screened / language_barrier / not_qualified / undetermined / other.
outcome_label string or null Your organization’s name for the outcome, e.g. Hung Up
note string or null The AI’s after-call note, or what a person wrote
duration_seconds integer or null
started string (date-time)
answered string (date-time) or null
ended string (date-time) or null
updated string (date-time)
handled_by object
handled_by.id string or null The user’s ID; null for the AI and for a closer
handled_by.name string
handled_by.role string One of sdr / closer / ai.
owner object or null
owner.id string
owner.name string
tth_seconds number or null Seconds from buying intent to a person on the call
callback_at string (date-time) or null
recording_available boolean
transcript_available boolean
started_by object
started_by.type string One of dialer / api / person.
started_by.api_key_id string or null
{
"id": "e4d3c2b1-a09f-4e8d-9c7b-6a5f4e3d2c1b",
"object": "call",
"livemode": true,
"lead": {
"id": "2b8e4c1d-9f3a-4b7e-8c21-6a5d4e3f2b10",
"external_id": "crm-10442",
"name": "LEAD_NAME",
"phone": "+15555550142"
},
"campaign_id": "7c1f2b9e-4a3d-4e8f-9b21-5d6a7e8f9a01",
"direction": "outbound",
"status": "ended",
"outcome": "interested",
"outcome_label": "Interested",
"note": "Wants a quote for a 6 kW system; home owner, roof replaced 2019.",
"duration_seconds": 412,
"started": "2026-10-06T16:58:06.000Z",
"answered": "2026-10-06T16:58:14.000Z",
"ended": "2026-10-06T17:04:58.000Z",
"updated": "2026-10-06T17:05:20.000Z",
"handled_by": {
"id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"name": "SDR_NAME",
"role": "sdr"
},
"owner": null,
"tth_seconds": 9.3,
"callback_at": null,
"recording_available": true,
"transcript_available": true,
"started_by": {
"type": "api",
"api_key_id": "key_example"
}
}

The reply to POST /leads (and each ok result in a batch).

Field Type Required Notes
id string (uuid) or null yes Our ID for the lead. null on a dry run.
external_id string or null yes
status string yes One of dialing / queued / scheduled / held.
call_now boolean yes
place_in_line integer or null yes 1 = next, 0 = being dialed now.
estimated_wait_seconds integer or null yes
scheduled_for string (date-time) or null yes
scheduled_reason string or null yes One of outside_calling_hours / recent_contact_cooldown.
held_reason string or null yes One of campaign_paused / campaign_not_started / spend_cap_reached.
dry_run boolean yes
requeued boolean Only when the lead already existed and was put back in the queue. Set to true.
livemode boolean yes false for a test key: sample data, never real.
{
"id": "2b8e4c1d-9f3a-4b7e-8c21-6a5d4e3f2b10",
"external_id": "crm-10442",
"status": "queued",
"call_now": true,
"place_in_line": 1,
"estimated_wait_seconds": 20,
"scheduled_for": null,
"scheduled_reason": null,
"held_reason": null,
"dry_run": false,
"livemode": true
}

What the lead agreed to, if you send it. Stored with the lead and returned.

Field Type Required Notes
source string yes Where the lead agreed, for example web_form, crm or purchased_list. At most 100 characters.
agreed_at string (date-time) yes When the lead agreed.
text string The words the lead agreed to. Send text or url. At most 5000 characters.
url string (uri) The page the lead agreed on. Send text or url.
ip string The lead’s IP address when agreeing, if you have it.
{
"source": "string",
"agreed_at": "2026-10-06T17:05:20Z",
"text": "string",
"url": "https://example.com",
"ip": "string"
}

Every event, from GET /events or a webhook.

Field Type Required Notes
id string yes Unique. If you have seen this id before, skip it.
type string yes One of lead.created / lead.queued / lead.interested / lead.opted_out / lead.late / call.started / call.answered / call.completed / handover.accepted / voicemail.left / callback.booked.
created string (date-time) yes
livemode boolean yes false for a test key: sample data, never real.
api_version string yes
data object yes
data.object object yes The lead or the call, as GET /leads/{id} or GET /calls/{id} returns it, plus the event’s own fields.
sample boolean Only on a “Send test event” sample. Set to true.
{
"id": "string",
"type": "lead.created",
"created": "2026-10-06T17:05:20Z",
"livemode": true,
"api_version": "2026-10-01",
"data": {
"object": {}
},
"sample": true
}

Where events go.

Field Type Required Notes
id string (uuid) yes
object string yes Set to "webhook_endpoint".
url string (uri) yes
events array of string yes
campaign_ids array of string (uuid) or null yes null = every campaign.
mode string yes One of live / test.
livemode boolean yes false for a test key: sample data, never real.
status string yes paused: by you, or by us after 24 hours of failures in a row. One of active / paused.
failing_since string (date-time) or null yes
paused_at string (date-time) or null yes
last_success_at string (date-time) or null yes
previous_secret_expires_at string (date-time) or null yes During a secret roll: when the old secret stops signing.
created string (date-time) yes
updated string (date-time) yes
{
"id": "3f6a9c2e-1b7d-4e5f-8a90-1c2d3e4f5a6b",
"object": "webhook_endpoint",
"url": "https://crm.example.com/callview",
"events": [
"call.completed",
"lead.interested"
],
"campaign_ids": null,
"mode": "live",
"livemode": true,
"status": "active",
"failing_since": null,
"paused_at": null,
"last_success_at": "2026-10-06T17:05:21.000Z",
"previous_secret_expires_at": null,
"created": "2026-10-01T09:00:00.000Z",
"updated": "2026-10-01T09:00:00.000Z"
}

One event sent (or waiting) to one endpoint.

Field Type Required Notes
id string yes
object string yes Set to "webhook_delivery".
endpoint_id string (uuid) yes
event_id string or null yes
event_type string yes
status string yes One of pending / sent / failed / gave_up / skipped_paused.
attempts integer yes Tries so far (7 at most).
next_attempt_at string (date-time) or null yes
last_attempt_at string (date-time) or null yes
response_status integer or null yes
response_body string or null yes The first 4 KB of your answer.
duration_ms integer or null yes
resent_from string or null yes
created string (date-time) yes
livemode boolean yes false for a test key: sample data, never real.
{
"id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
"object": "webhook_delivery",
"endpoint_id": "3f6a9c2e-1b7d-4e5f-8a90-1c2d3e4f5a6b",
"event_id": "evt_callcompletedxxxxxxxxxxx",
"event_type": "call.completed",
"status": "sent",
"attempts": 1,
"next_attempt_at": null,
"last_attempt_at": "2026-10-06T17:05:21.000Z",
"response_status": 200,
"response_body": "ok",
"duration_ms": 182,
"resent_from": null,
"created": "2026-10-06T17:05:20.000Z",
"livemode": true
}

GET /usage.

Field Type Required Notes
object string yes Set to "usage".
period string yes
timezone string yes Your organization’s time zone. Months follow it.
livemode boolean yes false for a test key: sample data, never real.
totals UsageCounts yes
group_by string or null yes One of key / campaign / day.
groups array of UsageCounts + object yes
updated string (date-time) or null yes When the numbers were last counted (every 5 minutes).
{
"object": "usage",
"period": "2026-10",
"timezone": "America/New_York",
"livemode": true,
"totals": {
"requests": 1840,
"leads_added": 212,
"calls": 260,
"calls_connected": 141,
"minutes": 388,
"cost_usd": 58.2
},
"group_by": null,
"groups": [],
"updated": "2026-10-06T17:05:00.000Z"
}

Every error, from every endpoint. See Error codes.

Field Type Required Notes
error object yes
error.type string yes One of invalid_request_error / authentication_error / permission_error / rate_limit_error / idempotency_error / api_error.
error.code string yes A stable word. Branch on this, never on the message. One of invalid_request / invalid_phone / on_dnc_list / outside_calling_hours / duplicate_lead / number_retired / consent_required / campaign_closed / queue_full / test_flows_busy / phone_cannot_change / ambiguous_external_id / duplicate_dnc_entry / not_found / authentication_failed / permission_denied / rate_limited / too_many_concurrent_requests / lead_rate_limited / idempotency_mismatch / idempotency_in_progress / limit_reached / endpoint_paused / service_unavailable / internal_error / lead_busy / lead_taken_out_of_queue / call_limit_reached / number_not_allowed / recording_not_available.
error.message string yes For people. Phone numbers and emails in it are masked.
error.param string or null yes The field the error is about, when there is one.
error.request_id string or null yes The same as the Request-Id header. Quote it when you contact us.
error.reason string The specific cause when the code is a broader word (for example why authentication failed).
error.lead_id string (uuid) or null duplicate_lead only: the lead that already exists.
error.missing_permission string permission_denied only: the permission the key is missing, for example “calls:read”.
error.campaign_id string (uuid) or null permission_denied only: the campaign outside the key’s scope (null when the endpoint needs a key for every campaign).
error.candidates array of object ambiguous_external_id only: the leads that match, so you can add campaign_id.
{
"error": {
"type": "invalid_request_error",
"code": "invalid_request",
"message": "string",
"param": "string",
"request_id": "string",
"reason": "string",
"lead_id": "2b8e4c1d-9f3a-4b7e-8c21-6a5d4e3f2b10",
"missing_permission": "string",
"campaign_id": "7c1f2b9e-4a3d-4e8f-9b21-5d6a7e8f9a01",
"candidates": [
{
"id": "e4d3c2b1-a09f-4e8d-9c7b-6a5f4e3d2c1b",
"campaign_id": "7c1f2b9e-4a3d-4e8f-9b21-5d6a7e8f9a01"
}
]
}
}