Skip to main content
POST
/
v1
/
calls
/
outbound
Create outbound call
curl --request POST \
  --url https://api.nixflex.com/v1/calls/outbound

Documentation Index

Fetch the complete documentation index at: https://docs.nixflex.com/llms.txt

Use this file to discover all available pages before exploring further.

Triggers Nixflex to call a phone number. The agent dials, waits for pickup, runs voicemail detection, and starts the conversation when a human answers.

Request

curl -X POST https://api.nixflex.com/v1/calls/outbound \
  -H "Authorization: Bearer KEY_ID:KEY_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "agent_125207e452f8714a",
    "to_number": "+447386172392",
    "from_number": "+447446466847",
    "dynamic_vars": {
      "patient_name": "Sarah",
      "appointment_time": "Tuesday at 2pm"
    },
    "metadata": {
      "internal_lead_id": "lead_abc123"
    }
  }'

Body parameters

FieldTypeRequiredNotes
agent_idstringYesAgent that will handle this call
to_numberstringYesRecipient in E.164 format (+44...)
from_numberstringYesYour imported Twilio number to call from
dynamic_varsobjectNoKey-value pairs injected into the agent’s prompt
voicemail_messagestringNoOverride agent default; what to leave if voicemail
voicemail_actionenumNohangup (default), leave_message, ignore
metadataobjectNoFree-form data echoed in webhook + call record
campaign_idstringNoLink this call to a batch campaign

Dynamic variables

Variables in dynamic_vars are interpolated into the system prompt. In your prompt, reference them with curly braces:
You are calling {patient_name} about their appointment on {appointment_time}.
The engine replaces {patient_name} with "Sarah" before sending to Claude. If a variable referenced in the prompt isn’t in dynamic_vars, it’s left as-is (Claude will see the literal {patient_name}).
For most outbound calls, you don’t need dynamic_vars — history-aware outbound automatically gives Claude the recipient’s past call summaries, so it already knows context.

Response

201 Created:
{
  "call_id": "CA1234567890",
  "status": "queued",
  "agent_id": "agent_125207e452f8714a",
  "to_number": "+447386172392",
  "from_number": "+447446466847"
}
The response returns immediately. Twilio dials within ~5 seconds. The actual call lifecycle (ringing → connected → ended) happens asynchronously — you’ll get a webhook when the call ends.

Validation order

The engine validates in this exact order:
  1. agent_id and to_number are present
  2. to_number is E.164 format (e.g. +447386172392, not 07386172392)
  3. Agent belongs to your API key
  4. Agent has at least one phone number attached, OR from_number is provided
  5. Twilio credentials exist on the agent’s phone number record
If any check fails, you get a 400 with the specific code.

Errors

CodeHTTPCause
invalid_phone_format400to_number or from_number not E.164
agent_not_owned403Agent doesn’t belong to your API key
agent_no_phone400Agent has no phone number attached
from_number_not_owned403from_number not in your account
outbound_failed502Twilio rejected the dial (see details.twilio_error)
concurrent_call_limit429Too many calls in flight; back off and retry

What happens next

After you trigger the call:
  1. Twilio dials the to_number
  2. Voicemail detection runs in parallel (AMD + Deepgram patterns)
  3. If voicemail is detected, the engine acts per voicemail_action and ends the call
  4. If a human answers, the agent starts the conversation
  5. Call ends naturally or via [END_CALL] / timeout
  6. Recording is saved, post-call analysis runs
  7. Webhook fires to your webhook_url
See Outbound calls for the full conceptual overview.