Create Outbound Call
Initiates an outbound phone call to a single number using an AI agent. The call is placed through Ultravox which handles the Telnyx telephony integration. Only agency owners and admins can make outbound calls.
Endpoint
| Property | Value |
|---|---|
| Function Name | calls-create-outbound |
| HTTP Method | POST |
| Authentication | Supabase JWT (Bearer token) |
| Required Role | agency_owner or agency_admin |
Request
Headers
Authorization: Bearer <supabase_jwt_token>
Content-Type: application/json
Body
| Field | Type | Required | Description |
|---|---|---|---|
agent_id | string | Yes | Ultravox agent ID from agent_mappings.ultravox_agent_id |
to_number | string | Yes | Destination phone number in E.164 format (e.g., +15551234567) |
from_number | string | No | Caller ID in E.164 format. Must be an active agency phone number. Defaults to the agency's first active number. |
first_speaker | "agent" | "user" | No | Who speaks first when the call connects. Defaults to agent. |
metadata | object | No | Custom metadata object passed through to Ultravox webhooks. |
Response
Success (200)
{
"call_id": "uuid",
"ultravox_call_id": "uv-call-abc123",
"status": "initiated",
"to_number": "+15551234567",
"from_number": "+15559876543"
}
Partial Success (200)
If the call is initiated in Ultravox but the local database insert fails:
{
"call_id": null,
"ultravox_call_id": "uv-call-abc123",
"status": "initiated",
"to_number": "+15551234567",
"from_number": "+15559876543",
"warning": "Call initiated but failed to save to database"
}
Error Responses
| Status | Condition |
|---|---|
| 400 | agent_id is missing |
| 400 | to_number is missing or not in E.164 format |
| 400 | from_number is not in E.164 format or not active in the agency |
| 400 | No active phone number available (when from_number is not provided) |
| 400 | Ultravox API key not configured |
| 400 | Telnyx API key not configured |
| 401 | Missing or invalid authorization header |
| 403 | User is not associated with an agency |
| 403 | User role is not agency_owner or agency_admin |
| 404 | Agent not found or does not belong to the user's agency |
| 405 | HTTP method is not POST |
| 500 | Failed to retrieve API credentials from the database |
| 500 | Unexpected server error |
| 502 | Ultravox API returned an error when initiating the call |
Behavior
- Authenticates the user via Supabase JWT and verifies they have the
agency_owneroragency_adminrole. - Validates
agent_idandto_numberare provided, and thatto_numberis in E.164 format (+followed by 7–15 digits). - Validates the agent belongs to the user's agency via the
agent_mappingstable. - Retrieves decrypted API keys via
get_agency_credentialsRPC. Both Ultravox and Telnyx keys must be configured. - Resolves
from_number:- If provided, validates it exists in
agency_phone_numberswithis_active=trueandstatus='active'. - If omitted, selects the agency's first active phone number ordered by
created_at.
- If provided, validates it exists in
- Builds the Ultravox API payload with
medium: { telnyx: { destinationPhoneNumber } }. - Maps
first_speakerto Ultravox's enum:'agent'→FIRST_SPEAKER_AGENT,'user'→FIRST_SPEAKER_USER. - Calls the Ultravox API (
POST /api/calls) to initiate the outbound call. - Stores the call in the
callstable withsource='api',direction='outbound', resolvedfrom_numberandto_number.
Database Tables
| Table / RPC | Operation | Description |
|---|---|---|
users | Read | Fetches user profile to determine agency_id and role |
agent_mappings | Read | Validates agent_id belongs to the user's agency |
agency_phone_numbers | Read | Validates or resolves the from_number caller ID |
get_agency_credentials (RPC) | Read | Retrieves decrypted Ultravox and Telnyx API keys |
calls | Insert | Stores the outbound call record |
External APIs
| API | Method | Endpoint | Description |
|---|---|---|---|
| Ultravox | POST | /api/calls | Initiates the outbound call via Telnyx medium |
Related Functions
- Create WebRTC Call -- Create a browser-based test call instead
- Create Call Batch -- Create a batch of outbound calls for campaign processing
- Webhook Ingest -- Receives call status updates from Ultravox