Provision Telephony
Performs full end-to-end telephony provisioning for an agency. Creates a Telnyx Call Control Application, an Outbound Voice Profile, stores the resource IDs in the database, imports the Telnyx configuration into Ultravox, and marks the agency as telephony-configured.
Endpoint
| Property | Value |
|---|---|
| Function Name | provision-telephony |
| HTTP Method | POST |
| Authentication | Supabase JWT (Bearer token) |
| Required Role | agency_owner |
Request
Headers
Authorization: Bearer <supabase_jwt_token>
Content-Type: application/json
Body
| Field | Type | Required | Description |
|---|---|---|---|
force | boolean | No | If true, re-provisions even if telephony is already configured. Defaults to false. |
Response
Success (200)
{
"success": true,
"completed_steps": [
{
"success": true,
"step": "create_telnyx_application",
"data": {
"application_id": "uuid-string",
"application_name": "Virsyn - Agency Name"
}
},
{
"success": true,
"step": "create_outbound_profile",
"data": {
"outbound_profile_id": "uuid-string",
"profile_name": "Virsyn Outbound - Agency Name"
}
},
{
"success": true,
"step": "store_resource_ids",
"data": {
"telnyx_application_id": "uuid-string",
"telnyx_outbound_profile_id": "uuid-string"
}
},
{
"success": true,
"step": "import_to_ultravox",
"data": {
"telnyx_configured": true
}
},
{
"success": true,
"step": "mark_configured",
"data": {
"telephony_configured": true
}
}
],
"provisioned": {
"telnyx_application_id": "uuid-string",
"telnyx_outbound_profile_id": "uuid-string",
"webhook_url": "https://<supabase-url>/functions/v1/telnyx-webhook/<agency_id>/<webhook_secret>"
},
"capabilities": {
"can_manage_agents": true,
"can_manage_phone_numbers": true,
"can_run_campaigns": true
},
"next_steps": [
"Create your first AI agent",
"Purchase phone numbers",
"Assign numbers to agents for inbound calls"
]
}
Error Responses
| Status | Condition |
|---|---|
| 400 | Ultravox API key not configured (missing field lists missing keys) |
| 400 | Telnyx credentials not configured (missing field lists missing keys) |
| 400 | Telephony already provisioned (includes existing IDs and hint to use force: true) |
| 401 | Missing or invalid authorization header |
| 403 | User is not an agency user or is not an agency_owner |
| 404 | Agency record not found |
| 405 | HTTP method is not POST |
| 500 | Failed to retrieve agency credentials |
| 500 | Partial failure at any provisioning step (includes completed_steps, failed_at, and partial_data) |
Behavior
- Authenticates the user via Supabase JWT and verifies they have the
agency_ownerrole - Retrieves agency credentials using the
get_agency_credentialsRPC function - Validates that
ultravox_api_key,telnyx_api_key, andtelnyx_public_keyare all present - Checks if telephony is already provisioned (both
telnyx_application_idandtelnyx_outbound_profile_idexist); skips unlessforce: trueis sent - Step 1: Creates a Telnyx Call Control Application via
POST https://api.telnyx.com/v2/call_control_applicationswith SHAKEN/STIR enabled, 100-channel inbound/outbound limits, RFC 2833 DTMF, and a 30-second first command timeout - Step 2: Creates a Telnyx Outbound Voice Profile via
POST https://api.telnyx.com/v2/outbound_voice_profileswith conversational traffic type, global service plan, 100 concurrent call limit, and whitelisted destinations (US, CA, GB, AU, NZ, IE). Then associates the profile with the application viaPATCHon the application - Step 3: Stores the Telnyx Application ID and Outbound Profile ID in the database via the
update_telnyx_provisioningRPC function - Step 4: Imports the Telnyx credentials into Ultravox via
PATCH https://api.ultravox.ai/api/accounts/me/telephony_configwith the API key, public key, and application SID - Step 5: Marks telephony as configured via the
mark_telephony_configuredRPC function - On partial failure, returns the completed steps and indicates where provisioning failed, along with any partial resource IDs that were created
Database Tables Read/Written
| Table | Operation | Purpose |
|---|---|---|
users | Read | Verify user role and agency membership |
agencies | Read | Get agency name and webhook secret |
agencies | Write | Store application ID on partial failure |
RPC Functions Called
| Function | Purpose |
|---|---|
get_agency_credentials | Retrieve decrypted API keys for the agency |
update_telnyx_provisioning | Store Telnyx application and outbound profile IDs |
mark_telephony_configured | Set the telephony configured flag on the agency |
External APIs Called
| API | Method | Endpoint | Purpose |
|---|---|---|---|
| Telnyx | POST | /v2/call_control_applications | Create Call Control Application |
| Telnyx | POST | /v2/outbound_voice_profiles | Create Outbound Voice Profile |
| Telnyx | PATCH | /v2/call_control_applications/{id} | Associate outbound profile with application |
| Ultravox | PATCH | /api/accounts/me/telephony_config | Import Telnyx credentials into Ultravox |
Related Functions
- Import Telnyx to Ultravox -- Retry or re-sync just the Ultravox import step
- Verify Telephony Config -- Check sync status between Virsyn DB and Ultravox
- Store Telnyx Credentials -- Store Telnyx API keys before provisioning
- Save Ultravox Integration -- Store Ultravox API key before provisioning