zoxaAI
Homepage
API ReferenceTelephony Configs & Numbers

Add a phone number

POST /api/v1/organizations/telephony-configs/{config_id}/phone-numbers — register a DID under a config and optionally attach an inbound agent.

POST /api/v1/organizations/telephony-configs/{config_id}/phone-numbers

Registers a phone number under a configuration. If you attach an inbound agent (inbound_agent_uuid), zoxaAI also syncs the provider — registering the inbound webhook so calls to this DID reach the agent automatically.

Request body

FieldTypeRequiredDescription
addressstring✓The DID. E.164 (+14155550100) or a SIP URI. Bare digits need country_code.
country_codestring (ISO-2)—Required when address is bare digits (e.g. "US", "IN").
labelstring (≤64)—Friendly name.
inbound_agent_uuidstring—Route inbound calls to this saved agent — its public uuid (not the numeric id).
is_activebool—Defaults to true.
is_default_caller_idbool—Use as the default outbound caller ID. Defaults to false.
extra_metadataobject—Arbitrary JSON you attach.

inbound_agent_uuid is the agent's public UUID

Attach an agent by its uuid (from POST /agents / GET /agents) — the same UUID you'd pass to POST /call. Passing the numeric id here fails validation. See the ID map.

Response

200 OK — the created number. The response echoes the inbound agent as both its internal inbound_agent_id (int) and its inbound_agent_uuid (string) — you send only the UUID; the numeric id is returned for reference. When you attached an inbound agent, a provider_sync object reports whether the provider-side webhook update succeeded:

{
  "id": 88,
  "telephony_configuration_id": 7,
  "address": "+14155550100",
  "address_normalized": "+14155550100",
  "address_type": "pstn",
  "inbound_agent_id": 42,
  "inbound_agent_uuid": "550e8400-e29b-41d4-a716-446655440000",
  "inbound_agent_name": "Support agent",
  "is_active": true,
  "is_default_caller_id": false,
  "extra_metadata": {},
  "created_at": "2026-07-09T10:00:00Z",
  "updated_at": "2026-07-09T10:00:00Z",
  "provider_sync": { "ok": true, "message": null }
}

provider_sync.ok=false is a warning, not a failure

The number is saved even if the provider-side webhook sync fails. ok: false means "row written, but the provider wasn't updated" — retry with update-number once the provider issue is resolved.

Example: add a number and route inbound to a saved agent

curl -X POST https://dashboard.zoxa.ai/api/v1/organizations/telephony-configs/7/phone-numbers \
  -H "X-API-Key: zsk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "address": "+14155550100",
    "country_code": "US",
    "label": "Main line",
    "inbound_agent_uuid": "550e8400-e29b-41d4-a716-446655440000"
  }'
import httpx
r = httpx.post(
    "https://dashboard.zoxa.ai/api/v1/organizations/telephony-configs/7/phone-numbers",
    headers={"X-API-Key": "zsk_..."},
    json={"address": "+14155550100", "country_code": "US", "inbound_agent_uuid": "550e8400-e29b-41d4-a716-446655440000"},
)
phone_number_id = r.json()["id"]

Errors

StatusdetailWhen
400"PSTN addresses without a leading '+' need a country_code…"Bare-digit address with no country_code.
404"Telephony configuration not found"config_id not in your org.
404"Agent not found"inbound_agent_uuid doesn't resolve in your org.
409"This phone number is already added in this organization."The number is already on one of this organization's configs.

Same number in several organizations

The same provider account and number can be added to any number of organizations; uniqueness is only checked inside one organization. Outbound calls and the dialer work from every organization. A number can only ring one place, so inbound calls go to the organization that most recently assigned an inbound agent or workflow to it.

On this page