Reference

Triggering calls

One campaign, created once, holding the agent and the number. After that a call is a single request with a phone number in it.

The setup

An API campaign is a configuration template rather than a list of people to ring. You make one, and then trigger against it whenever something in your own system says a call should happen, an order shipping, an appointment tomorrow, a form submitted.

  1. Create the campaign

    Once, with type: "api". It carries the default agent and the number calls are placed from.

    curl -X POST https://vocalis.io/api/v1/campaigns \
    -H "Authorization: Bearer $VOCALIS_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
    "name": "Order confirmations",
    "type": "api",
    "agentId": "your-agent-uuid",
    "provisionedPhoneNumberId": "your-phone-uuid"
    }'
  2. Trigger a call

    The smallest version needs only a number.

    curl -X POST https://vocalis.io/api/v1/campaigns/CAMPAIGN_ID/trigger \
    -H "Authorization: Bearer $VOCALIS_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{ "phoneNumber": "+14155551234" }'

Saying something specific

The agent is the same each time; what it knows does not have to be. Variables fill the placeholders in its prompt, promptAppend adds a line for this call alone, and metadata comes back untouched in the webhook, which is how the result finds its way to the right record in your system. Three metadata keys are reserved, isGroupedCall, additionalCallIds and groupedProviderCount, and a request that sends one is rejected with a 400.

trigger.js
const response = await fetch(
`https://vocalis.io/api/v1/campaigns/${campaignId}/trigger`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.VOCALIS_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
phoneNumber: '+14155551234',
calleeName: 'John Doe',
promptAppend: 'Order #123 shipped today via UPS.',
variables: {
customerName: 'John',
orderNumber: '123',
trackingNumber: '1Z999AA10123456784',
},
metadata: { orderId: '123', source: 'shopify' },
callbackUrl: 'https://myapp.com/webhooks/call-complete',
}),
},
);
const { data } = await response.json();
console.log('Call queued:', data.callId);

For a call that has nothing to do with the campaign's agent, send a systemPrompt and it replaces the prompt entirely.

curl -X POST https://vocalis.io/api/v1/campaigns/CAMPAIGN_ID/trigger \
-H "Authorization: Bearer $VOCALIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+14155551234",
"systemPrompt": "You are a friendly appointment reminder. Remind the patient of their appointment tomorrow at 2pm with Dr. Smith.",
"callbackUrl": "https://myapp.com/webhooks/call-complete"
}'
systemPrompt and agentId cannot both be sent. One replaces the prompt; the other swaps the whole agent.

Afterwards

callbackUrl
One POST to your endpoint when the call ends. See webhooks.The recommended shape for anything in production.
GET /api/v1/calls/{callId}
Polling, if you must. The status walks through those in order.queued → initiated → ringing → in_progress → completed
Daily runs
Everything triggered on the same UTC day is grouped into one campaign run, so fifty calls across a day read as one run of fifty rather than fifty runs of one.

The endpoint's full reference (every parameter and every response ) is on the campaigns page.