zoxaAI
Homepage
API ReferenceTelephony Configs & Numbers

Create a telephony configuration

POST /api/v1/organizations/telephony-configs — save a provider account (credentials) so its numbers can be managed and dialed.

POST /api/v1/organizations/telephony-configs

Creates a telephony configuration from a set of provider credentials. Returns the new config_id you'll use to add phone numbers and route calls.

Config vs inline credentials

Saving a config is optional for outbound — POST /call can take credentials inline per call. A config is what you want when you're managing numbers, inbound routing, or campaigns, and don't want to resend credentials each time.

Request body

FieldTypeRequiredDescription
namestring (1–64)✓Unique label within the org.
is_default_outboundbool—Make this the default config for outbound. Defaults to false.
configobject✓Provider-specific credentials, discriminated by provider.

config is a discriminated union on provider. Any from_numbers inside config are ignored — numbers are managed via the phone-number endpoints.

config shape by provider

{ "provider": "twilio", "account_sid": "AC...", "auth_token": "..." }
{ "provider": "vobiz", "auth_id": "MA_...", "auth_token": "...", "application_id": "3037850026..." }

application_id is optional and only used for inbound routing.

{
  "provider": "smartflo",
  "auth_token": "<lifetime REST API token>",
  "click_to_call_api_key": "<outbound only — omit for inbound-only>"
}

auth_token powers number listing, validation, and CDR/cost. click_to_call_api_key is only needed to place outbound calls. See Tata Smartflo setup.

{
  "provider": "plivo",
  "auth_id": "MA...",
  "auth_token": "...",
  "application_id": "optional — auto-created when omitted",
  "from_numbers": ["+1..."]
}
{
  "provider": "vonage",
  "api_key": "...",
  "api_secret": "...",
  "application_id": "...",
  "private_key": "-----BEGIN PRIVATE KEY-----\n...",
  "from_numbers": ["+1..."]
}

private_key is the application's key used for JWT generation.

{
  "provider": "telnyx",
  "api_key": "KEY...",
  "connection_id": "optional — auto-created when omitted",
  "webhook_public_key": "optional — enables webhook signature verification",
  "from_numbers": ["+1..."]
}
{
  "provider": "cloudonix",
  "bearer_token": "...",
  "domain_id": "...",
  "application_name": "optional — auto-created when omitted",
  "from_numbers": ["+972..."]
}
{
  "provider": "ari",
  "ari_endpoint": "http://your-asterisk-host:8088",
  "app_name": "zoxa",
  "app_password": "...",
  "ws_client_name": "optional",
  "from_numbers": ["+1..."]
}

Self-hosted Asterisk over ARI — the endpoint must be reachable from the zoxaAI server.

Response

200 OK with the config detail (credentials masked):

{
  "id": 7,
  "name": "Twilio – US",
  "provider": "twilio",
  "is_default_outbound": true,
  "credentials": { "account_sid": "****************def0", "auth_token": "****" },
  "voice_bot_wss_url": null,
  "created_at": "2026-07-09T10:00:00Z",
  "updated_at": "2026-07-09T10:00:00Z"
}

For Smartflo, voice_bot_wss_url is populated — see Get a configuration.

Examples

curl -X POST https://dashboard.zoxa.ai/api/v1/organizations/telephony-configs \
  -H "X-API-Key: zsk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Twilio – US",
    "is_default_outbound": true,
    "config": { "provider": "twilio", "account_sid": "AC...", "auth_token": "..." }
  }'
import httpx
r = httpx.post(
    "https://dashboard.zoxa.ai/api/v1/organizations/telephony-configs",
    headers={"X-API-Key": "zsk_..."},
    json={
        "name": "Twilio – US",
        "is_default_outbound": True,
        "config": {"provider": "twilio", "account_sid": "AC...", "auth_token": "..."},
    },
)
config_id = r.json()["id"]

Errors

StatusdetailWhen
400"No organization selected"Key has no org context.
409"A telephony configuration named '…' already exists…"Name collides within the org.
422array of field errorsProvider credentials failed schema validation.

On this page