API reference · Calls
Place a phone call
Rings a number from your workspace's default outbound number, with the key's agent speaking. For apps and backends that want the agent to call a customer.
Billed as voice minutes (400 credits a minute), metered from the post-call webhook exactly like any other phone call.
The do-not-call list and contact opt-outs are always enforced. Every call placed through the API is written to the audit log (api.call_placed) with the key that placed it.
The calls:create scope is off by default. Grant it on the key under Settings, API keys.
Request
curl -X POST "https://icebot.icebergaisolutions.com/api/v1/calls" \
-H "Authorization: Bearer $ICEBOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"to":"+60123456789","variables":{"customer_name":"Aisyah","order_number":"IB-1042"}}'Body
| Field | Type | Description |
|---|---|---|
to (required) | string | E.164 (+60123456789) or a Malaysian local number (012-345 6789). |
variables | object | Up to 20 values your agent can use during the call, e.g. the customer name. Keys match ^[a-z][a-z0-9_]{0,39}$; values are strings, numbers or booleans up to 500 characters. Reserved keys are refused: is_test, is_sandbox, caller_phone, campaign_id, campaign_contact_id, icebot_web_session and anything starting system__. |
{
"to": "+60123456789",
"variables": {
"customer_name": "Aisyah",
"order_number": "IB-1042"
}
}Responses
202
The provider accepted the dial and the phone is ringing. id may be null if the call row is written later by the post-call webhook.
{
"data": {
"id": "c3a1f0e2-7b64-4d9a-8e21-5f0c9d8b7a66",
"conversation_id": "conv_01j9x7k2m4p6q8r0s2t4v6w8y0",
"status": "dialing",
"to": "+60123456789",
"from": "+60360432781"
}
}Errors
Every endpoint can also return 401 (missing, unknown or revoked key), 403 (origin not allowed, or the key lacks calls:create) and 429 (rate limited). See Errors.
| Status | error | When |
|---|---|---|
400 | invalid body | to is not a phone number, or variables breaks a rule above. details lists each problem. |
402 | insufficient_credits | The workspace is out of credits (the spend gate). message says what to do. |
403 | plan_no_voice | The workspace is on the free (web-only) plan, or a self-serve business is not yet verified. |
422 | do_not_call | The number is on your do-not-call list. |
422 | opted_out | That contact has opted out of calls. |
422 | no_voice_agent | The key's agent has no voice agent provisioned. |
422 | no_outbound_number | No default outbound number is attached to the workspace. |
429 | call rate limit exceeded | More than 10 calls in a minute for this workspace. |
502 | provider_declined | The telephony provider refused the dial. Nothing is billed. |
503 | dnc_unreadable | The do-not-call list or opt-outs (opt_out_unreadable) could not be read. The call is not placed; retry. |
503 | voice_unconfigured | Voice calling is not configured on this deployment. |
Source of truth: /api/v1/calls in apps/dashboard/app/api/v1/calls/route.ts.