Developers

API: trigger outbound calls

Place calls from your own systems.

What the trigger API does

The trigger API places a real outbound call with one of your published agents. You send a JSON body, the agent resolves its phone numbers and prompt variables from it, and the platform hands the call to your carrier. This is how a CRM, a job queue or a backend workflow starts a conversation without anyone opening the console.

It is a dispatch API, not a call-control API. You start the call, and the result comes back later through the post-call webhook.

Before you start

  • The agent must be published and its status must be Active. A draft cannot be triggered, and a paused agent will refuse the call.
  • The agent's Call direction must be outgoing. An incoming-only agent cannot be dispatched this way.
  • The from-number must be imported into the workspace under a carrier that supports outbound dialling. Import numbers under Phone Numbers. A SIP-only number cannot place outbound calls.
  • The workspace needs a positive balance and enough headroom under its limits. See Limits & Quotas.

Endpoint

POST https://api.voicesquad.ai/v1/agents/{agent_uuid}/trigger

agent_uuid is the agent's identifier. The console's Copy API URL action on an outgoing agent gives you this exact URL. Rather than assembling the URL by hand, copy it: on the Agents list, the row menu for an outgoing agent has Copy API URL, and inside the agent editor the Conversation Trigger accordion has an Outbound API section with a Copy cURL helper that gives you a ready to run request for this agent.

Authentication

The endpoint uses HTTP Basic authentication with your workspace API credentials. The auth ID is the username and the auth token is the password.

Authorization: Basic base64(YOUR_AUTH_ID:YOUR_AUTH_TOKEN)

Find the pair in the console under Settings, then General, in the API Credentialssection. There is one active pair per workspace, created with the workspace. An admin can rotate it, and rotation revokes the previous pair immediately, so deploy the new values before you rotate.

Heads upTreat the auth token like a password. Keep it in your server-side secret store, never in browser code or a mobile app, since anyone holding it can place billable calls from your workspace.

The request body

The body is free-form JSON, and a form-encoded body is accepted too. Every key in it becomes a call variable, usable anywhere the agent accepts variables as {{key}}: the universal prompt, the welcome message, the human transfer destination, the end call instructions, and the outbound number templates.

That last one is how the call gets its numbers. In the agent's Conversation Trigger accordion, Outgoing call to and Outgoing call from are each either a literal number in E.164 form or a variable such as {{to_number}}. Whatever template is configured is resolved against the body of your request. So if the agent is configured to call {{to_number}}, your body must carry a to_number key.

Payload schema validation

The agent's payload schema, defined in the editor's payload editor, is validated before anything is dispatched. Each entry has a key, a type, a required flag, a description and an example. The rules are:

  • A key marked required must be present and must not be empty.
  • A key typed as a number must parse as a number.
  • A key typed as a boolean accepts a real boolean, or the strings true, false, 0 and 1.
  • Keys that are not in the schema are allowed through and still become variables. The schema is a floor, not a whitelist.

If validation fails, nothing is dialled and you get a single error listing every violation at once, so you can fix them in one pass rather than one request at a time.

Example request

curl -X POST \
  "https://api.voicesquad.ai/v1/agents/efa64971-0000-0000-0000-000000000000/trigger" \
  -u "YOUR_AUTH_ID:YOUR_AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "to_number": "+14155551234",
    "customer_name": "Alex Mercer",
    "invoice_id": "INV-20481",
    "amount_due": 149.5,
    "is_repeat_customer": true
  }'

Here the agent is configured to dial {{to_number}}, and its prompt can greet the caller by {{customer_name}} and quote {{invoice_id}} without any of that being hardcoded into the agent.

The success response

Every response is wrapped in the same envelope, with the useful part under data.

{
  "status_code": 200,
  "error_code": null,
  "message": "OK",
  "api_id": "3f2a91c4-0000-0000-0000-000000000000",
  "data": {
    "session_uuid": "9c15b8de-0000-0000-0000-000000000000",
    "carrier_call_id": "CA00000000000000000000000000000000",
    "carrier": "twilio",
    "status": "dispatched"
  }
}
  • session_uuid identifies the call session. It is the same call you will see in Conversations, and the same id the post-call webhook reports.
  • carrier_call_id and carrier identify the call at your telephony provider.
  • status is dispatched.
Heads upDispatched means handed to the carrier, not answered. A 200 tells you the call was accepted and placed, nothing about whether a person picked up, whether it hit voicemail, or how the conversation went. Those answers arrive on the webhook.

Errors

Errors use the same five envelope keys, with error_code filled in and message explaining the specific failure. Branch on error_code, not on the message text.

HTTPerror_codeWhat it means
404AGENT_NOT_FOUNDNo published version of this agent exists, or the UUID is wrong. A never-published draft looks like this.
401TRIGGER_CREDENTIALS_NOT_CONFIGUREDThe workspace has no API credentials to authenticate against. Create them under Settings, General.
401TRIGGER_CREDENTIALS_INVALIDThe auth ID or auth token does not match. Most often a rotated pair still in use somewhere.
409AGENT_NOT_ACTIVEThe agent exists and is published but is not Active. A paused agent returns this until you resume it.
409AGENT_NOT_OUTBOUNDThe agent is configured for incoming calls only, so it cannot be dispatched outbound.
422TRIGGER_PAYLOAD_INVALIDThe body failed payload schema validation. The message lists every violation, joined by semicolons.
400TRIGGER_MISSING_TONo destination number could be resolved. Usually the agent dials a variable your body did not include.
400FROM_NUMBER_NOT_IMPORTEDThe resolved from-number is not imported into this workspace under a carrier that can dial out.
402INSUFFICIENT_BALANCEThe workspace balance cannot cover the call. Recharge under Billing.
429CONCURRENCY_LIMITThe workspace already has its maximum number of calls in flight. Retry shortly.
429DAILY_LIMITThe daily call limit has been reached. It resets at midnight in the workspace timezone.
429DAILY_SPEND_CAPThe daily spend cap has been reached. It resets at midnight in the workspace timezone.
502OUTBOUND_DISPATCH_FAILEDThe carrier refused or failed to accept the call. Safe to retry.
422VALIDATION_ERRORThe request itself was malformed, for example invalid JSON.

Throttling

Your workspace safety caps are the throughput levers you control. The three that turn into a 429 are Max concurrent calls, Daily call limit and Daily spend cap, all configured under Settings, Limits & Quotas. The two daily caps reset at midnight in the workspace timezone.

Build for this rather than against it. If you are dialling a list, treat CONCURRENCY_LIMIT as a signal to slow down and retry with backoff, and treat DAILY_LIMIT and DAILY_SPEND_CAP as a signal to stop for the day, since retrying before the reset will only fail again.

Response envelope and correlation

Every JSON response, success or failure, has the same five keys: status_code, error_code, message, api_id and data. The api_id is a correlation id for the request. If you send an X-Api-Id header, it is echoed back in both the body and the X-Api-Id response header. If you do not, one is generated for you.

Log it. When you need help with a specific request, the api_id is what identifies it.

What happens next

  1. Your request is validated, the call is dispatched to the carrier, and you get dispatched back immediately.
  2. A call session is created. It appears in Conversations and you can watch it live.
  3. When the carrier reports the call answered, audio is bridged into the agent and the conversation runs.
  4. On hangup, the call is finalised: duration, cost and usage are rolled up, then the post-call evaluation runs.
  5. Once evaluation completes, the post-call webhook fires with the transcript, summary and extracted variables.
NoteThere is no endpoint to poll a call's status or fetch its transcript with API credentials. The post-call webhook is the programmatic channel for results, and the console shows everything else. Configure the webhook before you put the trigger API into production.

Inbound agents

Incoming agents are not started from application code. Each has its own voice webhook URL, which you paste into the number's configuration at your carrier. When someone dials that number, the carrier calls the URL, and the platform answers with the instructions that bridge the caller into the agent.

You never call that URL yourself, and it does not take an API credential. Its only client is your telephony provider. Everything else about an incoming agent, including its knowledge, its tools and its transcripts, works exactly as it does for an outgoing one.