Make Outbound Calls
There are three ways to trigger an outbound call from Bolti, in order of how often you'll reach for each:
- One-off, right now — fire a single call from the dashboard or API.
- One-off, at a future time — schedule a single call for an instant in the future.
- A list or schedule — run a recurring or bulk campaign. Covered separately in Batch Calling.
All three converge on the same dialing pipeline, so call quality, billing, and recording behave identically.
For exact request/response shapes for any endpoint mentioned on this page, browse the API Reference.
Prerequisites
Before placing an outbound call you need:
- An agent that's configured for outbound. Verify it works in Preview first.
- A phone number that supports outbound, assigned to that agent. Buy or connect one under Telephony.
- Workspace credits. Bolti checks your balance before dialing and rejects the call with a payment error if the call wouldn't fit your remaining minutes.
- The destination as an E.164 number —
+followed by country code and subscriber number, no spaces or punctuation.+14155551212, not(415) 555-1212.
One-off, right now
From the dashboard
Dashboard → Assistants → (your agent) → Make Outbound Call
- Pick the From number — must be a number assigned to this agent.
- Enter the To number in E.164 format.
- Optionally fill in any variables the prompt expects.
- Click Call.
Bolti spins up a realtime call room, dials out, and connects the audio to the agent worker. The receiver's phone rings within a couple of seconds.
From the API
The outbound-call endpoint accepts the destination, the agent's phone number to dial from, and any prompt variables. The response includes a conversation_id you can use to look up the call in Logs, poll for status, or correlate with webhooks.
→ See API Reference for the exact endpoint and payload shape.
From your editor (MCP)
If you've installed the MCP server:
"Place a call from the sales agent to +14155551212."
Same path under the hood; the MCP tool just wraps the API call.
One-off, at a future time
When the customer's logic is "remind me at 3pm tomorrow", schedule the call instead of firing it immediately. Bolti stores the dial in Postgres and a singleton scheduler picks it up at the right instant.
There's a dedicated scheduled-calls endpoint that takes the destination plus a scheduled_at instant (any ISO-8601 timestamp with an offset; naïve timestamps are rejected). Optional fields cover retries, prompt variables, and idempotency.
→ See API Reference for the full schema.
Idempotency
Network blips on retry would otherwise create duplicate scheduled calls. Send an Idempotency-Key header (a UUID is fine) and the first response is cached for ~24 hours; retrying with the same key returns the original response. Reusing the same key with a different request body returns 409 Conflict so client bugs surface loudly.
Lifecycle
| Status | Meaning |
|---|---|
pending | Sitting in the queue waiting for scheduled_at. Editable / cancellable. |
in_flight | The dispatcher has claimed the row and is calling telephony. |
dispatched | The dial succeeded; a conversation_id is now attached. |
failed | All retry attempts exhausted. last_error explains why. |
cancelled | The user cancelled the row before it fired. |
Editing or cancelling is only allowed while the row is pending. Once the dispatcher has it, the call is on the wire.
Subscribe to the outcome
If your system needs to react to the call's outcome (CRM updates, notifications), don't poll — register a webhook for scheduled_call.dispatched, scheduled_call.failed, and conversation.completed. Each event is signed with HMAC-SHA256 and delivered with retries.
Caller-ID and tariff
Each outbound call uses the trunk associated with the agent phone number you picked. The receiver sees that number on their caller-ID. Costs are metered per second of conversation against your workspace credit balance — see Pricing.
Volume and pacing
For more than a handful of dials at once, don't loop the one-off endpoint. Use a bulk campaign — it adds rate limiting, retries, and a fan-out worker that respects your account's concurrency limits. The one-off endpoint will happily accept 1,000 requests, but you'll trip carrier anti-spam heuristics long before they all complete.
Common errors
| Status | Meaning |
|---|---|
400 | Malformed request — usually a bad to_number (missing +, non-E.164) or an invalid scheduled_at. |
402 | Insufficient credits. Top up under Billing. |
403 | The phone number is not assigned to this agent for outbound, or you lack workspace permission. |
404 | The agent or phone number doesn't exist in this workspace. |
409 | Idempotency key was reused with a different body. |
429 | Per-workspace concurrency cap hit. Slow down or open an enterprise conversation. |
Next steps
- Run a list or schedule: Batch Calling.
- Get notified when calls finish: Webhooks.
- Drive prompts from data: Context and Variables.
- Check call lifecycle states: Call Statuses.
- Browse the full API Reference.