View Categories

API Reference – VoxPria SIP Trunks

10 min read

Complete API documentation for managing SIP trunks and phone numbers programmatically. Automate your voice infrastructure with VoxPria’s RESTful API.

Authentication #

All API requests require authentication using an API key in the Authorization header.

Getting Your API Key #

  1. Log into VoxPria dashboard
  2. Navigate to SettingsAPI Keys
  3. Click Generate New Key
  4. Copy and store securely
  5. Use in Authorization header

Authentication Format #

`bash

Authorization: Bearer YOUR_API_KEY

`

Example Request #

`bash

curl -X GET https://api.voxpria.com/v1/sip/trunks \

-H “Authorization: Bearer vox_sk_test_abc123xyz789”

`

Base URL #

`

https://api.voxpria.com/v1

`

All endpoints are relative to this base URL.

SIP Trunks #

List SIP Trunks #

Retrieve all SIP trunks in your account.

Endpoint: GET /sip/trunks
Response:
`json

{

“data”: [

{

“id”: “trunk_abc123”,

“name”: “My ElevenLabs Trunk”,

“provider”: “elevenlabs”,

“status”: “active”,

“created_at”: “2024-01-15T10:30:00Z”,

“phone_numbers_count”: 5

}

],

“pagination”: {

“page”: 1,

“per_page”: 20,

“total”: 3

}

}

`
Query Parameters:

  • page (integer) – Page number (default: 1)
  • per_page (integer) – Results per page (default: 20, max: 100)
  • provider (string) – Filter by provider type

Example:
`bash

curl -X GET “https://api.voxpria.com/v1/sip/trunks?provider=elevenlabs” \

-H “Authorization: Bearer YOUR_API_KEY”

`

Create SIP Trunk #

Create a new SIP trunk connection.

Endpoint: POST /sip/trunks
Request Body:
ElevenLabs Trunk:
`json

{

“name”: “Production ElevenLabs”,

“provider”: “elevenlabs”,

“credentials”: {

“username”: “your_elevenlabs_username”,

“password”: “your_elevenlabs_password”

},

“config”: {

“server”: “sip.rtc.elevenlabs.io”,

“port”: 5061,

“transport”: “tls”

}

}

`
OpenAI Trunk:
`json

{

“name”: “Production OpenAI”,

“provider”: “openai”,

“credentials”: {

“project_id”: “proj_abc123”,

“api_key”: “sk-proj-xyz789”,

“webhook_secret”: “whsec_def456”

}

}

`
Generic Trunk:
`json

{

“name”: “Custom SIP Provider”,

“provider”: “generic”,

“credentials”: {

“username”: “sip_username”,

“password”: “sip_password”

},

“config”: {

“server”: “sip.example.com”,

“port”: 5060,

“transport”: “tcp”

}

}

`
Response:
`json

{

“id”: “trunk_abc123”,

“name”: “Production ElevenLabs”,

“provider”: “elevenlabs”,

“status”: “active”,

“created_at”: “2024-01-15T10:30:00Z”

}

`
Status Codes:

  • 201 Created – Trunk created successfully
  • 400 Bad Request – Invalid parameters
  • 401 Unauthorized – Invalid API key
  • 409 Conflict – Trunk name already exists

Get SIP Trunk #

Retrieve details for a specific trunk.

Endpoint: GET /sip/trunks/{trunk_id}
Response:
`json

{

“id”: “trunk_abc123”,

“name”: “Production ElevenLabs”,

“provider”: “elevenlabs”,

“status”: “active”,

“config”: {

“server”: “sip.rtc.elevenlabs.io”,

“port”: 5061,

“transport”: “tls”

},

“phone_numbers”: [

{

“id”: “phone_def456”,

“number”: “+12125551234”,

“status”: “active”

}

],

“created_at”: “2024-01-15T10:30:00Z”,

“updated_at”: “2024-01-20T14:20:00Z”

}

`
Note: Credentials are not returned for security.

Update SIP Trunk #

Update trunk configuration or credentials.

Endpoint: PATCH /sip/trunks/{trunk_id}
Request Body:
`json

{

“name”: “Updated Trunk Name”,

“credentials”: {

“password”: “new_password”

},

“config”: {

“transport”: “tls”

}

}

`
Response:
`json

{

“id”: “trunk_abc123”,

“name”: “Updated Trunk Name”,

“provider”: “elevenlabs”,

“status”: “active”,

“updated_at”: “2024-01-20T15:00:00Z”

}

`
Note: After updating credentials, re-provision affected phone numbers.

Delete SIP Trunk #

Delete a trunk and remove all associated phone numbers.

Endpoint: DELETE /sip/trunks/{trunk_id}
Response:
`json

{

“success”: true,

“message”: “Trunk deleted successfully”

}

`
Status Codes:

  • 200 OK – Trunk deleted
  • 404 Not Found – Trunk doesn’t exist
  • 409 Conflict – Trunk has active phone numbers (remove first)

Provision Trunk (OpenAI) #

Provision an OpenAI trunk at project level.

Endpoint: POST /sip/trunks/{trunk_id}/provision
Response:
`json

{

“success”: true,

“status”: “provisioned”,

“provisioned_at”: “2024-01-20T16:00:00Z”

}

`
Note: Only required for OpenAI trunks. Provisions entire project.

Phone Numbers #

List Phone Numbers #

Retrieve all phone numbers in your account.

Endpoint: GET /phone-numbers
Response:
`json

{

“data”: [

{

“id”: “phone_abc123”,

“number”: “+12125551234”,

“trunk_id”: “trunk_def456”,

“engine”: “elevenlabs”,

“status”: “active”,

“agent_id”: “agent_ghi789”,

“capabilities”: {

“inbound”: true,

“outbound”: true,

“campaigns”: true

},

“created_at”: “2024-01-15T10:30:00Z”

}

],

“pagination”: {

“page”: 1,

“per_page”: 20,

“total”: 15

}

}

`
Query Parameters:

  • page (integer) – Page number
  • per_page (integer) – Results per page
  • trunk_id (string) – Filter by trunk
  • status (string) – Filter by status: active, inactive, provisioning
  • engine (string) – Filter by engine: elevenlabs, openai

Import Phone Number #

Add a phone number to VoxPria.

Endpoint: POST /phone-numbers/import
Request Body:
`json

{

“phone_number”: “+12125551234”,

“trunk_id”: “trunk_abc123”,

“engine”: “elevenlabs”,

“agent_id”: “agent_def456”,

“config”: {

“first_message”: “Hello! How can I help you today?”,

“max_duration”: 3600,

“language”: “en-US”

}

}

`
Response:
`json

{

“id”: “phone_abc123”,

“number”: “+12125551234”,

“trunk_id”: “trunk_def456”,

“engine”: “elevenlabs”,

“status”: “provisioning”,

“agent_id”: “agent_ghi789”,

“created_at”: “2024-01-20T10:00:00Z”

}

`
Status Codes:

  • 201 Created – Number imported successfully
  • 400 Bad Request – Invalid phone number format
  • 409 Conflict – Number already exists
  • 429 Too Many Requests – Rate limit exceeded (10/minute)

Rate Limiting:

  • Maximum 10 imports per minute per user
  • HTTP 429 returned when exceeded
  • Wait 60 seconds before retrying

Get Phone Number #

Retrieve details for a specific phone number.

Endpoint: GET /phone-numbers/{phone_id}
Response:
`json

{

“id”: “phone_abc123”,

“number”: “+12125551234”,

“trunk_id”: “trunk_def456”,

“trunk_name”: “My ElevenLabs Trunk”,

“engine”: “elevenlabs”,

“status”: “active”,

“agent_id”: “agent_ghi789”,

“agent_name”: “Customer Support Agent”,

“config”: {

“first_message”: “Hello! How can I help you today?”,

“max_duration”: 3600,

“language”: “en-US”

},

“capabilities”: {

“inbound”: true,

“outbound”: true,

“campaigns”: true,

“recordings”: true

},

“stats”: {

“total_calls”: 127,

“total_minutes”: 423.5,

“last_call_at”: “2024-01-20T14:30:00Z”

},

“created_at”: “2024-01-15T10:30:00Z”,

“updated_at”: “2024-01-20T14:30:00Z”

}

`

Update Phone Number #

Update phone number configuration.

Endpoint: PATCH /phone-numbers/{phone_id}
Request Body:
`json

{

“agent_id”: “agent_new789”,

“config”: {

“first_message”: “Updated greeting message”,

“max_duration”: 1800

}

}

`
Response:
`json

{

“id”: “phone_abc123”,

“number”: “+12125551234”,

“status”: “active”,

“agent_id”: “agent_new789”,

“updated_at”: “2024-01-20T16:00:00Z”

}

`

Delete Phone Number #

Remove a phone number from VoxPria.

Endpoint: DELETE /phone-numbers/{phone_id}
Response:
`json

{

“success”: true,

“message”: “Phone number deleted successfully”

}

`
Note: This removes the number from VoxPria but doesn’t cancel with provider.

Provision Phone Number #

Provision a phone number (ElevenLabs only).

Endpoint: POST /phone-numbers/{phone_id}/provision
Response:
`json

{

“success”: true,

“status”: “active”,

“provisioned_at”: “2024-01-20T16:30:00Z”

}

`
Note: Required after importing ElevenLabs numbers. OpenAI uses project-level provisioning.

Bulk Operations #

Re-provision All Numbers (Trunk) #

Re-provision all numbers on a trunk after credential updates.

Endpoint: POST /sip/trunks/{trunk_id}/reprovision-all
Response:
`json

{

“success”: true,

“total_numbers”: 5,

“provisioned”: 5,

“failed”: 0

}

`

Bulk Import Numbers #

Import multiple numbers at once.

Endpoint: POST /phone-numbers/bulk-import
Request Body:
`json

{

“trunk_id”: “trunk_abc123”,

“engine”: “elevenlabs”,

“numbers”: [

{

“phone_number”: “+12125551234”,

“agent_id”: “agent_def456”

},

{

“phone_number”: “+12125555678”,

“agent_id”: “agent_def456”

}

]

}

`
Response:
`json

{

“success”: true,

“imported”: 2,

“failed”: 0,

“results”: [

{

“phone_number”: “+12125551234”,

“status”: “success”,

“id”: “phone_abc123”

},

{

“phone_number”: “+12125555678”,

“status”: “success”,

“id”: “phone_abc124”

}

]

}

`
Rate Limiting:

  • Subject to standard import rate limits
  • Failed imports don’t count toward limit
  • Respects 10 imports per minute

Call Logs #

List Call Logs #

Retrieve call history for your phone numbers.

Endpoint: GET /calls
Response:
`json

{

“data”: [

{

“id”: “call_abc123”,

“phone_number”: “+12125551234”,

“direction”: “inbound”,

“from”: “+13035559876”,

“to”: “+12125551234”,

“agent_id”: “agent_def456”,

“status”: “completed”,

“duration”: 127,

“started_at”: “2024-01-20T14:00:00Z”,

“ended_at”: “2024-01-20T14:02:07Z”,

“recording_url”: “https://recordings.voxpria.com/abc123.mp3”,

“transcript_available”: true

}

],

“pagination”: {

“page”: 1,

“per_page”: 20,

“total”: 342

}

}

`
Query Parameters:

  • page (integer) – Page number
  • per_page (integer) – Results per page
  • phone_number (string) – Filter by phone number
  • direction (string) – Filter: inbound, outbound
  • status (string) – Filter: completed, failed, no-answer
  • start_date (string) – ISO 8601 date (e.g., 2024-01-15)
  • end_date (string) – ISO 8601 date

Example:
`bash

curl -X GET “https://api.voxpria.com/v1/calls?phone_number=%2B12125551234&start_date=2024-01-15” \

-H “Authorization: Bearer YOUR_API_KEY”

`

Get Call Details #

Retrieve detailed information about a specific call.

Endpoint: GET /calls/{call_id}
Response:
`json

{

“id”: “call_abc123”,

“phone_number”: “+12125551234”,

“direction”: “inbound”,

“from”: “+13035559876”,

“to”: “+12125551234”,

“agent_id”: “agent_def456”,

“agent_name”: “Customer Support Agent”,

“status”: “completed”,

“duration”: 127,

“started_at”: “2024-01-20T14:00:00Z”,

“ended_at”: “2024-01-20T14:02:07Z”,

“recording_url”: “https://recordings.voxpria.com/abc123.mp3”,

“transcript”: {

“segments”: [

{

“speaker”: “agent”,

“text”: “Hello! How can I help you today?”,

“timestamp”: “2024-01-20T14:00:02Z”

},

{

“speaker”: “caller”,

“text”: “I need help with my account.”,

“timestamp”: “2024-01-20T14:00:05Z”

}

]

},

“metadata”: {

“caller_location”: “Denver, CO”,

“call_quality”: “excellent”

}

}

`

Webhooks #

Configure webhooks to receive real-time notifications.

Webhook Events #

Available event types:

  • call.started – Call initiated
  • call.ended – Call completed
  • call.failed – Call failed to connect
  • number.provisioned – Number successfully provisioned
  • trunk.updated – Trunk configuration changed

Webhook Payload #

Example call.ended webhook:

`json

{

“event”: “call.ended”,

“timestamp”: “2024-01-20T14:02:07Z”,

“data”: {

“call_id”: “call_abc123”,

“phone_number”: “+12125551234”,

“direction”: “inbound”,

“status”: “completed”,

“duration”: 127,

“recording_url”: “https://recordings.voxpria.com/abc123.mp3”

}

}

`

Configure Webhook #

Endpoint: POST /webhooks
Request Body:
`json

{

“url”: “https://your-app.com/webhooks/voxpria”,

“events”: [“call.started”, “call.ended”],

“secret”: “your_webhook_secret”

}

`
Response:
`json

{

“id”: “webhook_abc123”,

“url”: “https://your-app.com/webhooks/voxpria”,

“events”: [“call.started”, “call.ended”],

“status”: “active”,

“created_at”: “2024-01-20T10:00:00Z”

}

`

Verify Webhook Signatures #

Webhooks include X-VoxPria-Signature header for verification.

Example Verification (Node.js):
`javascript

const crypto = require(‘crypto’);

function verifyWebhook(payload, signature, secret) {

const hmac = crypto.createHmac(‘sha256’, secret);

const digest = hmac.update(JSON.stringify(payload)).digest(‘hex’);

return crypto.timingSafeEqual(

Buffer.from(signature),

Buffer.from(digest)

);

}

`

Error Handling #

Error Response Format #

`json

{

“error”: {

“code”: “invalid_phone_number”,

“message”: “Phone number must be in E.164 format”,

“details”: {

“field”: “phone_number”,

“provided”: “2125551234”

}

}

}

`

Common Error Codes #

400 Bad Request:

  • invalid_phone_number – Phone number format incorrect
  • invalid_credentials – SIP credentials invalid
  • missing_required_field – Required field not provided

401 Unauthorized:

  • invalid_api_key – API key invalid or expired
  • api_key_missing – No API key provided

403 Forbidden:

  • insufficient_permissions – API key lacks required permissions
  • feature_not_enabled – SIP features not available on plan

404 Not Found:

  • trunk_not_found – Trunk ID doesn’t exist
  • phone_not_found – Phone number doesn’t exist

409 Conflict:

  • trunk_name_exists – Trunk name already in use
  • phone_number_exists – Number already imported

429 Too Many Requests:

  • rate_limit_exceeded – Too many requests, slow down
  • import_limit_exceeded – Phone import rate limit hit

500 Internal Server Error:

  • server_error – Internal server issue
  • provisioning_failed – Provider provisioning failed

Rate Limits #

Current Limits #

| Endpoint | Limit | Window |
|———-|——-|——–|
| Phone Import | 10 requests | 1 minute |
| General API | 1000 requests | 1 hour |
| Webhooks | 100 deliveries | 1 minute |

Rate Limit Headers #

`

X-RateLimit-Limit: 10

X-RateLimit-Remaining: 7

X-RateLimit-Reset: 1234567890

`

Handling Rate Limits #

When you receive HTTP 429:

  1. Read X-RateLimit-Reset header
  2. Wait until reset timestamp
  3. Retry request
  4. Implement exponential backoff

Example:
`javascript

async function importWithRetry(phoneNumber, maxRetries = 3) {

for (let i = 0; i < maxRetries; i++) {

try {

return await importPhoneNumber(phoneNumber);

} catch (error) {

if (error.status === 429) {

const resetTime = error.headers[‘x-ratelimit-reset’];

const waitTime = resetTime – Date.now() / 1000;

await sleep(waitTime * 1000);

continue;

}

throw error;

}

}

}

`

SDK Examples #

Node.js #

`javascript

const VoxPria = require(‘@voxpria/sdk’);

const client = new VoxPria({

apiKey: ‘vox_sk_test_abc123’

});

// Create trunk

const trunk = await client.trunks.create({

name: ‘My ElevenLabs Trunk’,

provider: ‘elevenlabs’,

credentials: {

username: ‘username’,

password: ‘password’

}

});

// Import number

const phone = await client.phoneNumbers.import({

phoneNumber: ‘+12125551234’,

trunkId: trunk.id,

engine: ‘elevenlabs’,

agentId: ‘agent_abc123’

});

// Provision number

await client.phoneNumbers.provision(phone.id);

// List calls

const calls = await client.calls.list({

phoneNumber: ‘+12125551234’,

startDate: ‘2024-01-15’

});

`

Python #

`python

from voxpria import VoxPria

client = VoxPria(api_key=’vox_sk_test_abc123′)

Create trunk #

trunk = client.trunks.create(

name=’My ElevenLabs Trunk’,

provider=’elevenlabs’,

credentials={

‘username’: ‘username’,

‘password’: ‘password’

}

)

Import number #

phone = client.phone_numbers.import_number(

phone_number=’+12125551234′,

trunk_id=trunk.id,

engine=’elevenlabs’,

agent_id=’agent_abc123′

)

Provision number #

client.phone_numbers.provision(phone.id)

List calls #

calls = client.calls.list(

phone_number=’+12125551234′,

start_date=’2024-01-15′

)

`

Testing #

Sandbox Environment #

Test API integration without affecting production:

`

Base URL: https://api.sandbox.voxpria.com/v1

`

Use test API keys:

`

vox_sk_test_abc123xyz789

`

Test Credentials #

Sandbox includes test SIP credentials:

  • Username: test_user
  • Password: test_pass
  • Server: sip.test.voxpria.com

Test Phone Numbers #

Use these numbers for testing:

  • +15555551234 – Always succeeds
  • +15555551235 – Always fails provisioning
  • +15555551236 – Simulates slow provisioning

Best Practices #

API Keys #

  • Use separate keys for development and production
  • Rotate keys regularly
  • Never commit keys to version control
  • Use environment variables

Error Handling #

  • Implement retry logic with exponential backoff
  • Log errors for debugging
  • Handle rate limits gracefully
  • Validate data before API calls

Performance #

  • Cache trunk and phone number data
  • Use pagination for large result sets
  • Batch operations when possible
  • Monitor API response times

Security #

  • Use HTTPS for all requests
  • Verify webhook signatures
  • Implement IP allowlisting if available
  • Monitor API usage for anomalies

Support #

  • API Documentation: https://voxpria.com/api
  • Status Page: https://status.voxpria.com
  • Support Email: support@voxpria.com
  • Community Forum: https://community.voxpria.com

For urgent API issues, contact support with:

  • Request ID (from error response)
  • Timestamp of request
  • Expected vs actual behavior
  • Sample code that reproduces issue
Go to Top