API reference

Phone numbers

Search, buy, import, list and release numbers, and link them to agents for inbound calls.

Phone numbers serve as caller IDs for outbound calls and as entry points for inbound calls. You can buy a number through the platform, or import one you already own at a provider. Linking a number to an agent makes that agent answer calls to it. Numbers attached to a SIP trunk are managed on the SIP trunks page instead.

All routes need Authorization: Bearer <key>. Changing anything here needs the admin role; reading needs viewer.

Limitation: Search and purchase run against a built-in stand-in provider unless the operator sets TELEPHONY_MODE=live. The stand-in returns a fixed set of made-up numbers and its purchases always succeed, which is useful for testing and nothing else. In live mode, search and purchase work with Twilio and Plivo and need that provider's credentials, either stored through Providers or configured by the operator.

OperationMethod and path
Search available numbersGET /phone-numbers/search
Buy a numberPOST /phone-numbers/buy
Import a number you ownPOST /phone-numbers/import
List numbersGET /phone-numbers/all
Release a numberDELETE /phone-numbers/{phone_number_id}
Link a number to an agentPOST /inbound/setup
Unlink a numberPOST /inbound/unlink

Operations

Search available numbers

GET /phone-numbers/search

Lists numbers that can be bought in a country.

Auth: API key or session token. Role: viewer and up.

ParameterInTypeRequiredDescription
countryquerystringyesUS or IN (case-insensitive).
patternquerystringnoDigits the number should contain.
providerquerystringnotwilio, plivo or vobiz. Default: twilio for US, plivo for IN.

Request

bash
curl "https://api.sevennadi.si/phone-numbers/search?country=IN&pattern=80" \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"

Response 200 OK

json
[
  {
    "region": "KA",
    "friendly_name": "+91805550142",
    "locality": "Bengaluru",
    "phone_number": "+91805550142",
    "provider": "plivo",
    "price": 6.0,
    "price_minor_units": 600,
    "currency": "INR"
  }
]

price is the monthly price in major units. price_minor_units is the same amount in hundredths, and currency is the billing currency of the deployment (from its price book). Use those two to show a price.

Errors

StatusMessage
400country must be US or IN
400provider must be one of twilio, plivo, vobiz
400No <provider> credentials: add <KEY> and <KEY> via POST /providers (live mode only)

Buy a number

POST /phone-numbers/buy

Buys a number and adds it to the account. The first month's rental is charged to the wallet at once and appears in the billing ledger as a number rental.

Auth: API key or session token. Role: admin and up.

This route accepts an Idempotency-Key header; see Idempotency. Use it, because a blind retry could otherwise fail with "already in use" after the first attempt succeeded.

ParameterInTypeRequiredDescription
countrybodystringyesUS or IN.
phone_numberbodystringyesA number from the search result.
providerbodystringnoAs for search.

Request

bash
curl -X POST https://api.sevennadi.si/phone-numbers/buy \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: buy-blr-2026-10-13" \
  -d '{"country": "IN", "phone_number": "+91805550142"}'

Response 200 OK

json
{
  "id": "6d2c9b1a-3e4f-4a5b-8c7d-9e0f1a2b3c4d",
  "agent_id": null,
  "platform_owned": true,
  "deleted": false,
  "renewal": true,
  "payment_uuid": "b7a6c5d4-e3f2-4a1b-9c8d-7e6f5a4b3c2d",
  "phone_number": "+91805550142",
  "price": 600,
  "price_minor_units": 600,
  "currency": "INR",
  "telephony_provider": "plivo",
  "telephony_sid": "MOCK3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b",
  "created_at": "2026-10-13T07:50:00+00:00",
  "updated_at": "2026-10-13T07:50:00+00:00"
}

price in this response is in minor units (hundredths), unlike the search result and the list. price_minor_units and currency say the same thing explicitly, here and in the other two responses. platform_owned is true for a number rented through the platform.

Errors

StatusMessage
400country (US or IN) and phone_number are required
400This phone number is already in use
400Insufficient wallet balance to buy this number
400provider must be one of twilio, plivo, vobiz
403Your role (member) can't change phone numbers. It needs admin access; ask an owner or admin of the workspace.

Import a number you own

POST /phone-numbers/import

Registers a number you already hold at a provider, so it can be used as a caller ID and linked to an agent. Nothing is bought and nothing is charged. This route is not part of the core OpenAPI document. See Exotel and Twilio and Plivo for the provider side of the setup.

Auth: API key or session token. Role: admin and up.

ParameterInTypeRequiredDescription
phone_numberbodystringyesE.164.
telephony_providerbodystringyesexotel, twilio or plivo.
namebodystringnoA label.
countrybodystringnoCountry code, for your reference.

Request

bash
curl -X POST https://api.sevennadi.si/phone-numbers/import \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef" \
  -H "Content-Type: application/json" \
  -d '{"phone_number": "+918045550100", "telephony_provider": "exotel", "name": "Support line"}'

Response 201 Created

A number object as in List numbers, with "rented": false and "price": "$0.0".

Errors

StatusMessage
400phone_number must be in E.164 format, e.g. +918012345678
400telephony_provider must be exotel, twilio or plivo
400This phone number is already registered

List numbers

GET /phone-numbers/all

Returns the account's numbers, oldest first. Numbers that belong to a SIP trunk are not included.

Auth: API key or session token. Role: viewer and up.

ParameterInTypeRequiredDescription
include_parentquerybooleannotrue: a sub-account also gets its parent account's numbers. Default: false (the list is unchanged).

Request

bash
curl https://api.sevennadi.si/phone-numbers/all \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"

Response 200 OK

json
[
  {
    "id": "6d2c9b1a3e4f4a5b8c7d9e0f1a2b3c4d",
    "humanized_created_at": "3 days ago",
    "created_at": "2026-10-10T07:50:00Z",
    "humanized_updated_at": "3 days ago",
    "updated_at": "2026-10-10T07:50:00Z",
    "renewal_at": "9th Nov, 2026",
    "phone_number": "+91805550142",
    "agent_id": "f412f2b1-3493-4458-bcf2-8676cc798edd",
    "price": "$6.0",
    "price_minor_units": 600,
    "currency": "INR",
    "telephony_provider": "plivo",
    "rented": true
  }
]

price in the list is a fixed text format kept for compatibility: a dollar sign and the amount in major units, whatever the billing currency is. Read the amount from price_minor_units and the currency from currency.

The id here is 32 hexadecimal characters without hyphens. Both forms of the id are accepted wherever a phone_number_id is expected. agent_id is null when the number is not linked.

With include_parent=true, the parent account's numbers come with "from_parent": true and agent_id null. A sub-account can use them as the caller ID (from_phone_number), but cannot release them or link them to an agent.

Release a number

DELETE /phone-numbers/{phone_number_id}

Removes a number from the account. A number bought through the platform is also released at the provider. An imported number is only removed here; it stays yours at the provider.

Auth: API key or session token. Role: admin and up.

ParameterInTypeRequiredDescription
phone_number_idpathstringyesThe number's id.

Request

bash
curl -X DELETE https://api.sevennadi.si/phone-numbers/6d2c9b1a3e4f4a5b8c7d9e0f1a2b3c4d \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"

Response 200 OK

json
{"message": "The phone number has been removed from your account", "state": "deleted"}

Errors

StatusMessage
404Phone number not found

POST /inbound/setup

Makes an agent answer calls to one of your numbers. The response contains the URL the telephony provider must request when a call arrives. See Inbound calls and numbers.

Auth: API key or session token. Role: admin and up.

ParameterInTypeRequiredDescription
agent_idbodystring (UUID)yesThe agent that answers.
phone_number_idbodystringyesThe number's id.
allow_multiplebodybooleannoSet to true to move a number that is already linked to another agent. Default false.
ivr_configbodyobjectnoStored with the number as sent.

Request

bash
curl -X POST https://api.sevennadi.si/inbound/setup \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef" \
  -H "Content-Type: application/json" \
  -d '{"agent_id": "f412f2b1-3493-4458-bcf2-8676cc798edd", "phone_number_id": "6d2c9b1a3e4f4a5b8c7d9e0f1a2b3c4d"}'

Response 200 OK

json
{
  "url": "https://api.sevennadi.si/inbound_call?agent_id=f412f2b1-3493-4458-bcf2-8676cc798edd",
  "phone_number": "+91805550142",
  "id": "6d2c9b1a3e4f4a5b8c7d9e0f1a2b3c4d"
}

An inbound call is accepted only when the dialed number is linked to the agent named in the URL. If the agent's first task has task_config.disallow_unknown_numbers set, callers outside task_config.whitelist_phone_numbers are refused.

Errors

StatusMessage
400agent_id and phone_number_id are required
400This number is already linked to another agent; set allow_multiple to link it anyway
404Agent not found
404Phone number not found

POST /inbound/unlink

Removes the link between a number and its agent. Calls to the number are no longer answered by an agent.

Auth: API key or session token. Role: admin and up.

ParameterInTypeRequiredDescription
phone_number_idbodystringyesThe number's id.

Request

bash
curl -X POST https://api.sevennadi.si/inbound/unlink \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef" \
  -H "Content-Type: application/json" \
  -d '{"phone_number_id": "6d2c9b1a3e4f4a5b8c7d9e0f1a2b3c4d"}'

Response 200 OK

json
{
  "url": "https://api.sevennadi.si/inbound_call?agent_id=f412f2b1-3493-4458-bcf2-8676cc798edd",
  "phone_number": "+91805550142",
  "id": "6d2c9b1a3e4f4a5b8c7d9e0f1a2b3c4d"
}

url is the inbound URL that was in use, or null if the number was not linked.

Errors

StatusMessage
400phone_number_id is required
404Phone number not found