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-numbersRegisters 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
| Field | Type | Required | Description |
|---|---|---|---|
address | string | ✓ | The DID. E.164 (+14155550100) or a SIP URI. Bare digits need country_code. |
country_code | string (ISO-2) | — | Required when address is bare digits (e.g. "US", "IN"). |
label | string (≤64) | — | Friendly name. |
inbound_agent_uuid | string | — | Route inbound calls to this saved agent — its public uuid (not the numeric id). |
is_active | bool | — | Defaults to true. |
is_default_caller_id | bool | — | Use as the default outbound caller ID. Defaults to false. |
extra_metadata | object | — | 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
| Status | detail | When |
|---|---|---|
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.
Related
List available (provider) numbers
GET /api/v1/organizations/telephony-configs/{config_id}/available-numbers — the voice numbers the provider account owns, using the config's saved credentials.
Update a phone number
PUT /api/v1/organizations/telephony-configs/{config_id}/phone-numbers/{phone_number_id} — swap or clear the inbound agent, toggle active, re-sync the provider.