Skip to main content
VARTA

How do I register a SIP trunk and DID numbers so VARTA can dial and answer?

Placing a real call with "dial": true on POST /v1/calls, or answering an inbound one, needs a carrier account behind it. Trunks and numbers are that configuration: a trunk is your SIP carrier, numbers are the DIDs that carrier has given you, either as caller ID for outbound or as an inbound line bound to an agent.

Trunk credentials (auth.username / auth.password) are encrypted at rest and never returned by any read endpoint — has_credentials tells you whether a trunk has them, not what they are.

Register a trunk

POST /v1/trunks
curl -X POST "$VARTA_BASE_URL/trunks" \
  -H "Authorization: Bearer $VARTA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Exotel primary",
    "address": "sip.exotel.com",
    "numbers": ["+918041234567"],
    "auth": {"username": "...", "password": "..."}
  }'

address (the carrier's SIP hostname) is the only required field. numbers is the set of caller-ID numbers this trunk is authorised to present — required if you plan to choose a specific from when dialling. provider_trunk_id is optional: supply it to reference a trunk already registered directly with LiveKit; omit it to have address and auth sent inline on every dial instead.

{
  "id": "tk_a1",
  "name": "Exotel primary",
  "address": "sip.exotel.com",
  "numbers": ["+918041234567"],
  "provider_trunk_id": null,
  "has_credentials": true,
  "created_at": 1735600000.1
}

Like every state-changing call under /v1, this endpoint honours an Idempotency-Key header — see Idempotency.

Errors: invalid_request when address is missing, a numbers entry isn't valid E.164 (international form, for example +918041234567), or auth is present but isn't an object.

List trunks

GET /v1/trunks
curl "$VARTA_BASE_URL/trunks" \
  -H "Authorization: Bearer $VARTA_API_KEY"

Returns {"data": [...], "has_more": false, "next_cursor": null} — this endpoint does not yet paginate — with each item shaped like the POST /v1/trunks response above, oldest first.

Errors: none specific to this request.

Get a trunk

GET /v1/trunks/{trunk_id}
curl "$VARTA_BASE_URL/trunks/tk_a1" \
  -H "Authorization: Bearer $VARTA_API_KEY"

Returns the same shape as the POST /v1/trunks response above.

Errors: trunk_not_found when no trunk with that id exists for your tenant.

Delete a trunk

DELETE /v1/trunks/{trunk_id}
curl -X DELETE "$VARTA_BASE_URL/trunks/tk_a1" \
  -H "Authorization: Bearer $VARTA_API_KEY"
{ "id": "tk_a1", "deleted": true }

Errors: trunk_not_found when no trunk with that id exists for your tenant.

Register a number

POST /v1/numbers

This registers a DID you already hold with a carrier — it does not purchase or provision a new number. VARTA has no number-purchasing relationship with any carrier; buy the number from your carrier first, then tell VARTA about it here so it can be used as caller ID or bound to an agent for inbound.

curl -X POST "$VARTA_BASE_URL/numbers" \
  -H "Authorization: Bearer $VARTA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"number": "+918041234567", "trunk_id": "tk_a1", "agent_id": "ag_412", "label": "Support line"}'

number (E.164) is the only required field. trunk_id, agent_id and label are optional — set agent_id here or with the dedicated bind call below.

{
  "id": "num_c3",
  "tenant_id": "acme",
  "number": "+918041234567",
  "trunk_id": "tk_a1",
  "agent_id": "ag_412",
  "label": "Support line",
  "created_at": 1735600000.1
}

Like every state-changing call under /v1, this endpoint honours an Idempotency-Key header — see Idempotency.

Errors: invalid_request when number isn't valid E.164.

List numbers

GET /v1/numbers
curl "$VARTA_BASE_URL/numbers" \
  -H "Authorization: Bearer $VARTA_API_KEY"

Returns {"data": [...], "has_more": false, "next_cursor": null}, each item shaped like the POST /v1/numbers response above, sorted by number.

Errors: none specific to this request.

Bind a number to an agent

POST /v1/numbers/{number}/bind

Inbound calls on this number are answered by the bound agent, unless an inbound routing webhook overrides the choice.

curl -X POST "$VARTA_BASE_URL/numbers/%2B918041234567/bind" \
  -H "Authorization: Bearer $VARTA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"agent_id": "ag_412"}'

The number in the path is E.164 (+918041234567) — URL-encode the leading + as %2B. Returns the updated number record, shaped like the POST /v1/numbers response.

Like every state-changing call under /v1, this endpoint honours an Idempotency-Key header — see Idempotency.

Errors: invalid_request when agent_id is missing from the body or the number in the path isn't valid E.164, not_found when that number isn't registered.

Release a number

DELETE /v1/numbers/{number}
curl -X DELETE "$VARTA_BASE_URL/numbers/%2B918041234567" \
  -H "Authorization: Bearer $VARTA_API_KEY"
{ "number": "+918041234567", "deleted": true }

This removes VARTA's record of the number and its binding — it does not release the number back to your carrier; that's a separate step with whoever you hold it from.

Errors: invalid_request when the number in the path isn't valid E.164, not_found when it isn't registered.