Guide
Place outbound calls
1. Publish the agent
Only a published agent places calls. A draft answers 422 agent_not_published.
curl -X POST "https://api.voximate.no/public/v1/agents/7c3f1e90-5a44-4b21-9c07-2ed5b8f41a66/publish" \
-H "Authorization: Bearer $VOXIMATE_API_KEY"2. Give it a number
The agent calls from one of your phone numbers, so the person called sees a number they can ring back. List your numbers, then assign one to the agent. A number answered by the agent also routes inbound calls to it.
curl "https://api.voximate.no/public/v1/phone-numbers" \
-H "Authorization: Bearer $VOXIMATE_API_KEY"
curl -X PATCH "https://api.voximate.no/public/v1/phone-numbers/b8f2a1c4-3d5e-4f60-8a71-92b3c4d5e6f7" \
-H "Authorization: Bearer $VOXIMATE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"agent_id": "7c3f1e90-5a44-4b21-9c07-2ed5b8f41a66"}'3. Start the call
to— the number to ring, E.164 (+4712345678).from— optional when the agent has exactly one number. With several, say which; with none, the API answers422 agent_has_no_number.metadata— up to 20 string values of your own, returned on the call and in every webhook about it. Use it to find your record again.ring_timeout_seconds— how long to let it ring, 10 to 120. Default 30.first_message— optional: what the agent says first on this call, up to 500 characters. See What the agent says first.
curl -X POST "https://api.voximate.no/public/v1/calls" \
-H "Authorization: Bearer $VOXIMATE_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"agent_id": "7c3f1e90-5a44-4b21-9c07-2ed5b8f41a66",
"to": "+4712345678",
"first_message": "Hei, dette er Nordvik Tannklinikk. Jeg ringer om timen din i morgen.",
"metadata": { "crm_contact_id": "48213" },
"ring_timeout_seconds": 30
}'What the agent says first
The agent knows it placed the call. It says who it is and why it is calling, instead of answering as if the person had rung it, and when the call ends it thanks them for the conversation rather than for calling. Its first line is, in this order:
first_messageon this request, when you send one. Use it for what is different about each call, such as which appointment you are calling about. An empty string makes the agent wait for the person to speak first.- The agent’s
outbound_first_message, its greeting for calls it makes. Set it withPATCH /agents/{agent_id}or under the agent’s greeting in the dashboard. - Otherwise its
first_message, the greeting it uses when someone rings it. If that one is written for people who ring in (“thanks for calling”), set anoutbound_first_messagetoo.
4. Follow the call
The answer is 202 with the call in status queued. From there it moves to ringing, in_progress and finally completed — or no_answer, busy or failed. Subscribe to call.started, call.completed and call.failed rather than polling; see Get call results.
Calling a list
There is a limit of 10 outbound calls a minute and 500 a day per workspace by default. Send calls one by one with a pause, honour 429, and derive each Idempotency-Key from your own ids:
// Call a list of contacts, one at a time, staying inside the call limits.
const contacts = [
{ id: '48213', phone: '+4712345678' },
{ id: '48214', phone: '+4712345679' },
];
for (const contact of contacts) {
const res = await fetch('https://api.voximate.no/public/v1/calls', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.VOXIMATE_API_KEY}`,
'Content-Type': 'application/json',
// Derived from your data: a restarted job cannot call anyone twice.
'Idempotency-Key': `reminder-2026-10-14-${contact.id}`,
},
body: JSON.stringify({
agent_id: '7c3f1e90-5a44-4b21-9c07-2ed5b8f41a66',
to: contact.phone,
metadata: { crm_contact_id: contact.id, campaign: 'reminder-2026-10-14' },
}),
});
if (res.status === 429) {
const wait = Number(res.headers.get('Retry-After') ?? 60);
await new Promise((r) => setTimeout(r, wait * 1000));
continue; // in real code, put the contact back on the queue
}
const call = await res.json();
if (!res.ok) {
console.error(contact.id, call.error.code, call.error.message);
continue;
}
console.log(contact.id, '→ call', call.id);
await new Promise((r) => setTimeout(r, 6_000)); // 10 calls a minute
}For large campaigns with contact lists, retries and a do-not-call list built in, use Batch Calls in the dashboard.
Rules and responsibilities
- Norwegian emergency numbers —
110,112and113— are always refused. - Sales calls to consumers in Norway: check the number against Reservasjonsregisteret before you call. That check, and the right to call, are your responsibility.
- Tell people they are speaking with an AI agent when the law or your industry requires it — put it in the agent’s greeting.
- Answered calls count towards your plan’s minutes, like any other call.
Every request rings a real phone