Calls & campaigns
There are two ways to get an agent on the phone: place one call directly, or run an outbound campaign against many numbers at once.
Placing a single call
curl -X POST https://convostack.ai/api/phone/call \
-H "Authorization: Bearer cak_live_..." \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+15551234567",
"agentId": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
"fromPhoneNumberId": "pn_..."
}'
fromPhoneNumberId is optional — omit it to use the platform's default
caller ID. If you supply it, it must be a number your org owns (purchased
via the dashboard; see Phone numbers) and
ownership is checked the same way everywhere else in the API — a
cross-tenant id is rejected, not silently ignored.
The response includes callId, which is what you'll use to look up the call
afterward.
Reading call history
# List recent calls, optionally filtered
curl "https://convostack.ai/api/calls?agentId=a1b2c3d4-5678-90ab-cdef-1234567890ab&limit=20" \
-H "Authorization: Bearer cak_live_..."
# One call in detail
curl https://convostack.ai/api/calls/{callId} \
-H "Authorization: Bearer cak_live_..."
# Per-call analytics (latency breakdown, turn count, etc.)
curl https://convostack.ai/api/calls/{callId}/analytics \
-H "Authorization: Bearer cak_live_..."
GET /api/calls also accepts a campaignId filter, so you can pull just
the calls a specific campaign produced.
Outbound campaigns
A campaign is how you dial a list of numbers instead of one at a time — it owns pacing, retries, and pause/resume so you don't have to build that yourself.
1. Create a campaign (draft)
curl -X POST https://convostack.ai/api/outbound-campaigns \
-H "Authorization: Bearer cak_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Q3 renewal outreach",
"agentId": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
"maxAttempts": 3,
"retryDelaySeconds": 3600
}'
A campaign starts in draft — nothing dials until you explicitly start it.
2. Add targets
curl -X POST https://convostack.ai/api/outbound-campaigns/{id}/targets \
-H "Authorization: Bearer cak_live_..." \
-H "Content-Type: application/json" \
-d '{
"numbers": ["+15551234567", "+15557654321"],
"labels": ["Acme Corp", "Beta LLC"]
}'
labels are optional, positional (same order as numbers), and exist
purely so target lists read as something other than a wall of digits in the
dashboard.
3. Start it
curl -X POST https://convostack.ai/api/outbound-campaigns/{id}/start \
-H "Authorization: Bearer cak_live_..."
This is the point where real, billed calls begin. Starting is idempotent — calling it again on an already-running campaign is a no-op, not a second dialing pass.
Pausing, canceling, retrying
curl -X POST https://convostack.ai/api/outbound-campaigns/{id}/pause \
-H "Authorization: Bearer cak_live_..."
# Stops new dials; already-queued targets stay queued for when you resume
# (start again).
curl -X POST https://convostack.ai/api/outbound-campaigns/{id}/cancel \
-H "Authorization: Bearer cak_live_..."
# Cancels the campaign and every still-queued target. Not reversible —
# create a new campaign to try again.
curl -X POST https://convostack.ai/api/outbound-campaigns/{id}/retry-failed \
-H "Authorization: Bearer cak_live_..."
# Requeues everything that failed and moves the campaign back to draft so
# you can start it again.
Watching progress
curl https://convostack.ai/api/outbound-campaigns/{id}/targets?status=failed \
-H "Authorization: Bearer cak_live_..."
curl https://convostack.ai/api/outbound-campaigns/stats \
-H "Authorization: Bearer cak_live_..."
status filters targets by queued, dialing, completed, failed,
skipped (explicitly skipped, reserved for future use), or canceled
(the campaign was canceled before this target dialed).
/stats gives you the dashboard-level rollup (how many campaigns running,
how many dialed today, etc.) across your whole org.
Creating a campaign, adding targets, and starting a campaign all place real, billed calls downstream — they're throttled more tightly than the rest of the API. See Rate limits.
Credits
Every call — whether placed directly or through a campaign — draws down your org's credit balance. Check it before running anything at volume:
curl https://convostack.ai/api/credits/balance \
-H "Authorization: Bearer cak_live_..."
Credit deduction happens as calls complete, not up front when a campaign starts — a campaign with more targets than you have credits for will run until the balance is exhausted, not fail immediately at creation time.