Phone numbers API
Search, buy, assign, and manage phone numbers, plus the regulatory compliance flow. See Phone numbers for concepts.
These endpoints are organization-scoped. With a dashboard JWT pass X-Org-Id; with an API key the org is carried by the key. Every response uses the standard { "success": true, "data": { … } } envelope (conventions). Mutations (purchase, assign, release, compliance) require the developer, admin, or owner role.
Numbers
| Method | Path | Purpose |
|---|---|---|
GET | /api/voice/numbers/providers | Configured carriers + their capabilities, and the default provider |
GET | /api/voice/numbers/integration | A provider's default integration (?provider=) |
GET | /api/voice/numbers/search | Search available numbers to buy |
POST | /api/voice/numbers/purchase | Purchase + persist a number |
GET | /api/voice/numbers | List your numbers ({ numbers, total }) |
GET | /api/voice/numbers/{id} | Number details |
GET | /api/voice/numbers/connection-status | Live carrier-side routing check for every number |
DELETE | /api/voice/numbers/{id} | Release a number |
POST | /api/voice/numbers/{id}/assign-agent | Attach an agent (answers inbound, used as caller ID) |
DELETE | /api/voice/numbers/{id}/agent | Detach the agent |
POST | /api/voice/numbers/{id}/relink-integration | Re-point the number's routing at the platform |
DELETE | /api/voice/numbers/{id}/integration | Detach the integration (carrier routing) |
POST | /api/voice/numbers/{id}/compliance | Link a compliance application to a number |
GET | /api/voice/numbers/renewal-risk | Per-number renewal state and whether the wallet covers what is coming due |
GET | /api/voice/numbers/reclaimable | Recently released numbers the carrier may still be holding |
POST | /api/voice/numbers/{id}/reclaim | Ask for a released number back |
Search
curl "https://api.telenow.ai/api/voice/numbers/search?country=US&type=local&limit=20" \
-H "x-api-key: vai_live_…"
Query parameters: country (required, ISO 3166-1 alpha-2), provider (omit for the default), pattern, type (local / mobile / tollfree / national), region, services, limit, offset. The response carries the resolved provider and a numbers array with region, number_type, monthly_rent, setup_price (USD strings), and capabilities.
Purchase
curl -X POST https://api.telenow.ai/api/voice/numbers/purchase \
-H "x-api-key: vai_live_…" -H "Content-Type: application/json" \
-d '{
"provider": "plivo",
"number": "+14155550142",
"complianceApplicationId": "…",
"extras": { "numberType": "local", "country": "US" }
}'
| Field | Required | Notes |
|---|---|---|
number | Yes | The E.164 number returned by /search. |
provider | — | Omit to use the default provider. |
complianceApplicationId | For regulated buys | A local accepted application's id; the carrier rejects regulated purchases without it. |
integrationId | — | Override the default provider integration bound on purchase. |
extras | — | Provider-specific extras forwarded to the carrier (e.g. Twilio needs numberType + country to price/regulate correctly). |
Returns 201 Created with { number, integrationExternalId, providerStatus, complianceLinked }. Purchasing spends from your wallet, so a suspended or empty prepaid account returns an error (see Billing & usage).
Assign / unassign an agent
curl -X POST https://api.telenow.ai/api/voice/numbers/{id}/assign-agent \
-H "x-api-key: vai_live_…" -H "Content-Type: application/json" \
-d '{ "agentId": "agent-uuid" }'
The body field is agentId (camelCase). The agent must belong to the same org (403 otherwise; 404 if the agent doesn't exist).
assign-agent returns 409 Conflict when a team member already receives inbound calls on the number — inbound is exclusive (see Phone numbers and Team & workplace). The mirror case (allocating the number to a member for inbound while an agent is bound) is rejected the same way from the member-update endpoint. Detach with DELETE …/{id}/agent.
Connection status
curl "https://api.telenow.ai/api/voice/numbers/connection-status" -H "x-api-key: vai_live_…"
Makes live calls to the carrier API to check whether each owned number is actually routed to the platform's application. Returns { numbers: [{ id, e164, ourAppId, liveAppId, matches }], answerUrl }, where matches is true (routed to us), false (routed elsewhere / nowhere), or null (unknown). For a BYOC number that isn't routed yet, set its carrier Answer URL to the returned answerUrl. Because it hits the carrier, call this on demand, not in a tight loop.
Released numbers
A purchased number that goes unpaid is released back to the carrier (see Phone numbers → Getting a released number back). Both carriers hold a released number for the original account for a short time — Plivo about 5 days, Twilio about 10 — and GET …/reclaimable lists the ones still inside that window with their reclaimDeadlineAt. Numbers you released yourself are not listed: if one is still free, /search sells it again.
curl -X POST https://api.telenow.ai/api/voice/numbers/{id}/reclaim -H "x-api-key: vai_live_…"
{id} is the released row's id from /reclaimable. The call does everything the platform can do by itself and answers 200 with one of two status values:
status | Meaning |
|---|---|
restored | The carrier sold the number back. It is a fresh purchase — charged to credits at today's price — and number is the new active row (a new id). restore says how much of its old wiring came back: agentRestored, defaultOutboundRestored, campaignsRelinked, and notes for anything that could not be put back (for example, an agent deleted since). |
requested | The carrier would not sell it back automatically (a reserved number is not in either carrier's searchable inventory), so the request has been filed with Telenow support, who repurchase it from the carrier console before deadline and restore it to your account. alreadyRequested: true means an earlier call had already filed it. |
Refusals happen before the carrier is asked: 403 when the wallet does not cover the last known price (the message states the shortfall — the number was released for non-payment, so it is not recovered into a wallet that cannot keep it), and 400 when there is nothing to recover — the hold has ended, you released the number yourself, or it lives on your own carrier account (BYOC) or trunk.
Compliance
Some destinations require documentation before a number can carry traffic. See Compliance for the end-to-end walkthrough.
| Method | Path | Purpose |
|---|---|---|
GET | /api/voice/numbers/compliance/requirements | Required documents for a provider/country/type/end-user |
POST | /api/voice/numbers/compliance | Submit a compliance application |
GET | /api/voice/numbers/compliance | List your applications ({ applications, total }) |
GET | /api/voice/numbers/compliance/{id} | Application detail (refreshes from the carrier) |
DELETE | /api/voice/numbers/compliance/{id} | Withdraw an application |
POST | /api/voice/numbers/{id}/compliance | Link an application to a number |
…/compliance/requirements requires country, type, and endUserType query params (and an optional provider). Query it first to learn exactly which documents the carrier needs, submit them with POST …/compliance, wait for the application to reach accepted, then link it to your number.
curl -X POST https://api.telenow.ai/api/voice/numbers/{id}/compliance \
-H "x-api-key: vai_live_…" -H "Content-Type: application/json" \
-d '{ "complianceApplicationId": "application-uuid" }'
The link body field is complianceApplicationId (camelCase).
Carriers (BYOC) & SIP trunks
To use your own carrier account, manage credentials under /api/orgs/{orgId}/carriers; for your own SIP infrastructure, manage trunks and DIDs under /api/orgs/{orgId}/trunks. Both are documented in the Carriers & trunks API. The dashboard equivalents live under Developers → Carriers and Developers → SIP trunks (Telephony providers, SIP trunking).