Skip to content

Numere de telefon ​

10 endpoint-uri. Fiecare cale de mai jos este relativă la URL-ul de bază al API-ului și include deja prefixul /api/v1 — vezi convențiile pentru autentificare, paginare, erori și idempotență.

Endpoint
GET/telephony/phone-numbersList the tenant's phone numbers, filterable by provider, status, country or number substring, paginated
POST/telephony/phone-numbersRegister a number the tenant already controls (BYO/SIP) without any carrier purchase, returning the new row
GET/telephony/phone-numbers/{id}Fetch one phone number row with its routing, hook, recording and capability configuration
PATCH/telephony/phone-numbers/{id}Update a number's routing destination, hooks, caller id, recording and status, returning the refreshed row
DELETE/telephony/phone-numbers/{id}Soft-delete the phone number row; releasing it at the carrier is a separate explicit action
POST/telephony/phone-numbers/{id}/configurePush CallAgent's webhook URLs for this number to the carrier and report whether the config is now in sync
POST/telephony/phone-numbers/{id}/releaseRelease the number at the carrier first, then mark the row released and disable inbound and outbound
POST/telephony/phone-numbers/importImport every number a carrier account already owns, updating existing rows and marking vanished ones released
POST/telephony/phone-numbers/purchaseBuy a number at the carrier, persist it only after the carrier confirms, then push webhook config best-effort
POST/telephony/phone-numbers/searchSearch a carrier's inventory for available numbers by country, type, area code or pattern before buying

Endpoint-uri ​

List the tenant's phone numbers, filterable by provider, status, country or number substring, paginated ​

GET/telephony/phone-numbers
  • Handler-ul nu impune niciun scope — orice cheie validă îl poate apela.

Parametri de interogare

NumeTipObligatoriuNote
providerstring—
statusstring—
countrystring—
numberstring—
bash
curl -X GET "$CALLAGENT_API_URL/telephony/phone-numbers?provider=string&status=string" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Accept: application/json"
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/telephony/phone-numbers?provider=string&status=string`, {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
    Accept: 'application/json',
  },
});

if (!response.ok) {
  const { error } = await response.json();
  throw new Error(`${error.type}: ${error.message}`);
}

const { data } = await response.json();
php
<?php

$handle = curl_init(getenv('CALLAGENT_API_URL') . '/telephony/phone-numbers?provider=string&status=string');

curl_setopt_array($handle, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
        'Accept: application/json',
    ],
]);

$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);

if ($status >= 400) {
    throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}

$data = $body['data'];
python
import os, requests

response = requests.get(
    f"{os.environ['CALLAGENT_API_URL']}/telephony/phone-numbers?provider=string&status=string",
    headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
    timeout=30,
)
response.raise_for_status()
data = response.json()["data"]

Răspunsuri

StatusCorp
200data-wrapped array

Exemplu de răspuns, generat din schemă:

json
{
  "data": [
    "string"
  ],
  "meta": {
    "page": 1,
    "limit": 25,
    "total": 1,
    "pages": 1
  }
}

Register a number the tenant already controls (BYO/SIP) without any carrier purchase, returning the new row ​

POST/telephony/phone-numbers
  • Handler-ul nu impune niciun scope — orice cheie validă îl poate apela.
  • Request body keys are camelCase (e.g. friendlyName, sipTrunkId, assistantId), not the snake_case the rest of the wire format uses

Corpul cererii

CâmpTipObligatoriuNote
numberstringdamax 32 chars
friendlyNamestring | null—max 255 chars
sipTrunkIdstring | null—
assistantIdstring | null—
squadIdstring | null—
capabilitiesvoice · sms · mms · fax[] | null—
bash
curl -X POST "$CALLAGENT_API_URL/telephony/phone-numbers" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
       "number": "+40712345678",
       "friendlyName": "Support Line",
       "capabilities": [
         "voice"
       ]
     }'
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/telephony/phone-numbers`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "number": "+40712345678",
    "friendlyName": "Support Line",
    "capabilities": [
      "voice"
    ]
  }),
});

if (!response.ok) {
  const { error } = await response.json();
  throw new Error(`${error.type}: ${error.message}`);
}

const { data } = await response.json();
php
<?php

$handle = curl_init(getenv('CALLAGENT_API_URL') . '/telephony/phone-numbers');

curl_setopt_array($handle, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
        'Accept: application/json',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
    'number' => '+40712345678',
    'friendlyName' => 'Support Line',
    'capabilities' => [
        'voice',
    ],
]),
]);

$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);

if ($status >= 400) {
    throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}

$data = $body['data'];
python
import os, requests

response = requests.post(
    f"{os.environ['CALLAGENT_API_URL']}/telephony/phone-numbers",
    headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
    json={
      "number": "+40712345678",
      "friendlyName": "Support Line",
      "capabilities": [
        "voice"
      ]
    },
    timeout=30,
)
response.raise_for_status()
data = response.json()["data"]

Răspunsuri

StatusCorp
200JSON object
201data-wrapped PhoneNumber

Erori

StatusCând apare
409A non-released row for this E.164 number already exists in the organization
422Validation failed, or the number is not valid E.164

Exemplu de răspuns, generat din schemă:

json
"string"

Fetch one phone number row with its routing, hook, recording and capability configuration ​

GET/telephony/phone-numbers/{id}
  • Handler-ul nu impune niciun scope — orice cheie validă îl poate apela.

Parametri de cale

NumeTipObligatoriuNote
idstringda
bash
curl -X GET "$CALLAGENT_API_URL/telephony/phone-numbers/01JQ0000000000000000000000" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Accept: application/json"
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/telephony/phone-numbers/01JQ0000000000000000000000`, {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
    Accept: 'application/json',
  },
});

if (!response.ok) {
  const { error } = await response.json();
  throw new Error(`${error.type}: ${error.message}`);
}

const { data } = await response.json();
php
<?php

$handle = curl_init(getenv('CALLAGENT_API_URL') . '/telephony/phone-numbers/01JQ0000000000000000000000');

curl_setopt_array($handle, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
        'Accept: application/json',
    ],
]);

$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);

if ($status >= 400) {
    throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}

$data = $body['data'];
python
import os, requests

response = requests.get(
    f"{os.environ['CALLAGENT_API_URL']}/telephony/phone-numbers/01JQ0000000000000000000000",
    headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
    timeout=30,
)
response.raise_for_status()
data = response.json()["data"]

Răspunsuri

StatusCorp
200data-wrapped PhoneNumber

Erori

StatusCând apare
404No such number for this tenant

Exemplu de răspuns, generat din schemă:

json
{
  "data": {
    "id": "01JQ0000000000000000000000",
    "organization_id": "01JQ0000000000000000000000",
    "number": "+40712345678",
    "friendly_name": "Support Line",
    "provider": "twilio",
    "telephony_account_id": "01JQ0000000000000000000000",
    "provider_credential_id": "01JQ0000000000000000000000",
    "provider_number_sid": "string",
    "provider_account_sid": "string",
    "provider_metadata": {},
    "capabilities": {},
    "country": "string",
    "region": "string",
    "locality": "string",
    "number_type": "string",
    "address_requirement": "string",
    "destination_type": "assistant",
    "destination_id": "01JQ0000000000000000000000",
    "destination_value": "string",
    "fallback_destination_id": "01JQ0000000000000000000000",
    "fallback_destination_type": "assistant",
    "assistant_id": "01JQ0000000000000000000000",
    "squad_id": "01JQ0000000000000000000000",
    "hook_enabled": true,
    "hook_url": "https://example.com/hook",
    "hook_timeout_ms": 30,
    "hook_headers": {},
    "hook_fallback": "string",
    "hook_last_success_at": "2026-01-01T12:00:00+00:00",
    "hook_last_failure_at": "2026-01-01T12:00:00+00:00",
    "hook_last_error": "string",
    "outbound_enabled": true,
    "outbound_caller_id_number": "+40712345678",
    "outbound_caller_id_name": "Support Line",
    "sip_trunk_id": "01JQ0000000000000000000000",
    "caller_id_policy_id": "01JQ0000000000000000000000",
    "sms_enabled": true,
    "sms_assistant_id": "01JQ0000000000000000000000",
    "sms_webhook_url": "https://example.com/hook",
    "messaging_service_sid": "string",
    "recording_mode": "disabled",
    "recording_consent_required": true,
    "voice_webhook_url": "https://example.com/hook",
    "status_webhook_url": "https://example.com/hook",
    "webhooks_configured_at": "2026-01-01T12:00:00+00:00",
    "webhooks_in_sync": true,
    "max_concurrent_calls": 1,
    "status": "pending",
    "inbound_enabled": true,
    "imported_at": "2026-01-01T12:00:00+00:00",
    "purchased_at": "2026-01-01T12:00:00+00:00",
    "released_at": "2026-01-01T12:00:00+00:00",
    "last_inbound_at": "2026-01-01T12:00:00+00:00",
    "last_outbound_at": "2026-01-01T12:00:00+00:00",
    "monthly_cost": "string",
    "setup_cost": "string",
    "currency": "string",
    "notes": "string",
    "settings": {},
    "metadata": {},
    "created_at": "2026-01-01T12:00:00+00:00",
    "updated_at": "2026-01-01T12:00:00+00:00",
    "deleted_at": "2026-01-01T12:00:00+00:00",
    "phone_number_hook_id": "01JQ0000000000000000000000"
  }
}

Update a number's routing destination, hooks, caller id, recording and status, returning the refreshed row ​

PATCH/telephony/phone-numbers/{id}
  • Handler-ul nu impune niciun scope — orice cheie validă îl poate apela.
  • camelCase body keys (friendlyName, hookUrl, ...); hookSecret is encrypted on write and never readable back

Parametri de cale

NumeTipObligatoriuNote
idstringda

Corpul cererii

CâmpTipObligatoriuNote
friendlyNamestring | null—max 255 chars
destinationTypeassistant · squad · queue · ivr · ring_group · extension … | null—
destinationIdstring | null—max 32 chars
destinationValuestring | null—max 255 chars
assistantIdstring | null—max 32 chars
squadIdstring | null—max 32 chars
sipTrunkIdstring | null—
callerIdPolicyIdstring | null—
phoneNumberHookIdstring | null—
hookEnabledboolean | null—
hookUrlstring | null—uri. max 1024 chars
hookSecretstring | null—max 255 chars
hookTimeoutMsinteger | null—min 200. max 3000
hookFallbackstatic · reject · voicemail · null | null—
inboundEnabledboolean | null—
outboundEnabledboolean | null—
outboundCallerIdNumberstring | null—max 32 chars
outboundCallerIdNamestring | null—max 255 chars
smsEnabledboolean | null—
smsAssistantIdstring | null—max 32 chars
recordingModedisabled · mono · dual_channel · inherit | null—
recordingConsentRequiredboolean | null—
maxConcurrentCallsinteger | null—min 1
statuspending · active · suspended · released · error | null—
metadatastring[] | null—
bash
curl -X PATCH "$CALLAGENT_API_URL/telephony/phone-numbers/01JQ0000000000000000000000" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
       "friendlyName": "Support Line",
       "destinationType": "assistant",
       "phoneNumberHookId": "+40712345678",
       "hookEnabled": true,
       "hookUrl": "https://example.com/hook",
       "hookTimeoutMs": 30,
       "hookFallback": "static"
     }'
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/telephony/phone-numbers/01JQ0000000000000000000000`, {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "friendlyName": "Support Line",
    "destinationType": "assistant",
    "phoneNumberHookId": "+40712345678",
    "hookEnabled": true,
    "hookUrl": "https://example.com/hook",
    "hookTimeoutMs": 30,
    "hookFallback": "static"
  }),
});

if (!response.ok) {
  const { error } = await response.json();
  throw new Error(`${error.type}: ${error.message}`);
}

const { data } = await response.json();
php
<?php

$handle = curl_init(getenv('CALLAGENT_API_URL') . '/telephony/phone-numbers/01JQ0000000000000000000000');

curl_setopt_array($handle, [
    CURLOPT_CUSTOMREQUEST => 'PATCH',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
        'Accept: application/json',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
    'friendlyName' => 'Support Line',
    'destinationType' => 'assistant',
    'phoneNumberHookId' => '+40712345678',
    'hookEnabled' => true,
    'hookUrl' => 'https://example.com/hook',
    'hookTimeoutMs' => 30,
    'hookFallback' => 'static',
]),
]);

$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);

if ($status >= 400) {
    throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}

$data = $body['data'];
python
import os, requests

response = requests.patch(
    f"{os.environ['CALLAGENT_API_URL']}/telephony/phone-numbers/01JQ0000000000000000000000",
    headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
    json={
      "friendlyName": "Support Line",
      "destinationType": "assistant",
      "phoneNumberHookId": "+40712345678",
      "hookEnabled": True,
      "hookUrl": "https://example.com/hook",
      "hookTimeoutMs": 30,
      "hookFallback": "static"
    },
    timeout=30,
)
response.raise_for_status()
data = response.json()["data"]

Răspunsuri

StatusCorp
200data-wrapped object

Erori

StatusCând apare
404No such number for this tenant
422Validation failed, or a referenced trunk/policy/hook id does not exist

Exemplu de răspuns, generat din schemă:

json
{
  "data": {
    "id": "01JQ0000000000000000000000",
    "organization_id": "01JQ0000000000000000000000",
    "number": "+40712345678",
    "friendly_name": "Support Line",
    "provider": "twilio",
    "telephony_account_id": "01JQ0000000000000000000000",
    "provider_credential_id": "01JQ0000000000000000000000",
    "provider_number_sid": "string",
    "provider_account_sid": "string",
    "provider_metadata": {},
    "capabilities": {},
    "country": "string",
    "region": "string",
    "locality": "string",
    "number_type": "string",
    "address_requirement": "string",
    "destination_type": "assistant",
    "destination_id": "01JQ0000000000000000000000",
    "destination_value": "string",
    "fallback_destination_id": "01JQ0000000000000000000000",
    "fallback_destination_type": "assistant",
    "assistant_id": "01JQ0000000000000000000000",
    "squad_id": "01JQ0000000000000000000000",
    "hook_enabled": true,
    "hook_url": "https://example.com/hook",
    "hook_timeout_ms": 30,
    "hook_headers": {},
    "hook_fallback": "string",
    "hook_last_success_at": "2026-01-01T12:00:00+00:00",
    "hook_last_failure_at": "2026-01-01T12:00:00+00:00",
    "hook_last_error": "string",
    "outbound_enabled": true,
    "outbound_caller_id_number": "+40712345678",
    "outbound_caller_id_name": "Support Line",
    "sip_trunk_id": "01JQ0000000000000000000000",
    "caller_id_policy_id": "01JQ0000000000000000000000",
    "sms_enabled": true,
    "sms_assistant_id": "01JQ0000000000000000000000",
    "sms_webhook_url": "https://example.com/hook",
    "messaging_service_sid": "string",
    "recording_mode": "disabled",
    "recording_consent_required": true,
    "voice_webhook_url": "https://example.com/hook",
    "status_webhook_url": "https://example.com/hook",
    "webhooks_configured_at": "2026-01-01T12:00:00+00:00",
    "webhooks_in_sync": true,
    "max_concurrent_calls": 1,
    "status": "pending",
    "inbound_enabled": true,
    "imported_at": "2026-01-01T12:00:00+00:00",
    "purchased_at": "2026-01-01T12:00:00+00:00",
    "released_at": "2026-01-01T12:00:00+00:00",
    "last_inbound_at": "2026-01-01T12:00:00+00:00",
    "last_outbound_at": "2026-01-01T12:00:00+00:00",
    "monthly_cost": "string",
    "setup_cost": "string",
    "currency": "string",
    "notes": "string",
    "settings": {},
    "metadata": {},
    "created_at": "2026-01-01T12:00:00+00:00",
    "updated_at": "2026-01-01T12:00:00+00:00",
    "deleted_at": "2026-01-01T12:00:00+00:00",
    "phone_number_hook_id": "01JQ0000000000000000000000"
  }
}

Soft-delete the phone number row; releasing it at the carrier is a separate explicit action ​

DELETE/telephony/phone-numbers/{id}
  • Handler-ul nu impune niciun scope — orice cheie validă îl poate apela.
  • Acest răspuns nu este împachetat în data.

Parametri de cale

NumeTipObligatoriuNote
idstringda
bash
curl -X DELETE "$CALLAGENT_API_URL/telephony/phone-numbers/01JQ0000000000000000000000" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Accept: application/json"
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/telephony/phone-numbers/01JQ0000000000000000000000`, {
  method: 'DELETE',
  headers: {
    Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
    Accept: 'application/json',
  },
});

if (!response.ok) {
  const { error } = await response.json();
  throw new Error(`${error.type}: ${error.message}`);
}

const { data } = await response.json();
php
<?php

$handle = curl_init(getenv('CALLAGENT_API_URL') . '/telephony/phone-numbers/01JQ0000000000000000000000');

curl_setopt_array($handle, [
    CURLOPT_CUSTOMREQUEST => 'DELETE',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
        'Accept: application/json',
    ],
]);

$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);

if ($status >= 400) {
    throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}

$data = $body['data'];
python
import os, requests

response = requests.delete(
    f"{os.environ['CALLAGENT_API_URL']}/telephony/phone-numbers/01JQ0000000000000000000000",
    headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
    timeout=30,
)
response.raise_for_status()
data = response.json()["data"]

Răspunsuri

StatusCorp
204No content

Erori

StatusCând apare
404No such number for this tenant

Push CallAgent's webhook URLs for this number to the carrier and report whether the config is now in sync ​

POST/telephony/phone-numbers/{id}/configure
  • Handler-ul nu impune niciun scope — orice cheie validă îl poate apela.
  • On failure it still returns a {"data": {configured: false}} body with status 502, not the usual error envelope

Parametri de cale

NumeTipObligatoriuNote
idstringda
bash
curl -X POST "$CALLAGENT_API_URL/telephony/phone-numbers/01JQ0000000000000000000000/configure" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Accept: application/json"
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/telephony/phone-numbers/01JQ0000000000000000000000/configure`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
    Accept: 'application/json',
  },
});

if (!response.ok) {
  const { error } = await response.json();
  throw new Error(`${error.type}: ${error.message}`);
}

const { data } = await response.json();
php
<?php

$handle = curl_init(getenv('CALLAGENT_API_URL') . '/telephony/phone-numbers/01JQ0000000000000000000000/configure');

curl_setopt_array($handle, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
        'Accept: application/json',
    ],
]);

$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);

if ($status >= 400) {
    throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}

$data = $body['data'];
python
import os, requests

response = requests.post(
    f"{os.environ['CALLAGENT_API_URL']}/telephony/phone-numbers/01JQ0000000000000000000000/configure",
    headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
    timeout=30,
)
response.raise_for_status()
data = response.json()["data"]

Răspunsuri

StatusCorp
200JSON object

Erori

StatusCând apare
404No such number for this tenant
502Carrier configuration failed

Exemplu de răspuns, generat din schemă:

json
"string"

Release the number at the carrier first, then mark the row released and disable inbound and outbound ​

POST/telephony/phone-numbers/{id}/release
  • Handler-ul nu impune niciun scope — orice cheie validă îl poate apela.

Parametri de cale

NumeTipObligatoriuNote
idstringda
bash
curl -X POST "$CALLAGENT_API_URL/telephony/phone-numbers/01JQ0000000000000000000000/release" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Accept: application/json"
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/telephony/phone-numbers/01JQ0000000000000000000000/release`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
    Accept: 'application/json',
  },
});

if (!response.ok) {
  const { error } = await response.json();
  throw new Error(`${error.type}: ${error.message}`);
}

const { data } = await response.json();
php
<?php

$handle = curl_init(getenv('CALLAGENT_API_URL') . '/telephony/phone-numbers/01JQ0000000000000000000000/release');

curl_setopt_array($handle, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
        'Accept: application/json',
    ],
]);

$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);

if ($status >= 400) {
    throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}

$data = $body['data'];
python
import os, requests

response = requests.post(
    f"{os.environ['CALLAGENT_API_URL']}/telephony/phone-numbers/01JQ0000000000000000000000/release",
    headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
    timeout=30,
)
response.raise_for_status()
data = response.json()["data"]

Răspunsuri

StatusCorp
200JSON object

Erori

StatusCând apare
404No such number for this tenant
422No active credential, unknown provider, or the row has no carrier id
501The provider has no adapter or no release API
502The carrier rejected the release
504The carrier could not be reached

Exemplu de răspuns, generat din schemă:

json
{
  "data": {
    "id": "01JQ0000000000000000000000",
    "organization_id": "01JQ0000000000000000000000",
    "number": "+40712345678",
    "friendly_name": "Support Line",
    "provider": "twilio",
    "telephony_account_id": "01JQ0000000000000000000000",
    "provider_credential_id": "01JQ0000000000000000000000",
    "provider_number_sid": "string",
    "provider_account_sid": "string",
    "provider_metadata": {},
    "capabilities": {},
    "country": "string",
    "region": "string",
    "locality": "string",
    "number_type": "string",
    "address_requirement": "string",
    "destination_type": "assistant",
    "destination_id": "01JQ0000000000000000000000",
    "destination_value": "string",
    "fallback_destination_id": "01JQ0000000000000000000000",
    "fallback_destination_type": "assistant",
    "assistant_id": "01JQ0000000000000000000000",
    "squad_id": "01JQ0000000000000000000000",
    "hook_enabled": true,
    "hook_url": "https://example.com/hook",
    "hook_timeout_ms": 30,
    "hook_headers": {},
    "hook_fallback": "string",
    "hook_last_success_at": "2026-01-01T12:00:00+00:00",
    "hook_last_failure_at": "2026-01-01T12:00:00+00:00",
    "hook_last_error": "string",
    "outbound_enabled": true,
    "outbound_caller_id_number": "+40712345678",
    "outbound_caller_id_name": "Support Line",
    "sip_trunk_id": "01JQ0000000000000000000000",
    "caller_id_policy_id": "01JQ0000000000000000000000",
    "sms_enabled": true,
    "sms_assistant_id": "01JQ0000000000000000000000",
    "sms_webhook_url": "https://example.com/hook",
    "messaging_service_sid": "string",
    "recording_mode": "disabled",
    "recording_consent_required": true,
    "voice_webhook_url": "https://example.com/hook",
    "status_webhook_url": "https://example.com/hook",
    "webhooks_configured_at": "2026-01-01T12:00:00+00:00",
    "webhooks_in_sync": true,
    "max_concurrent_calls": 1,
    "status": "pending",
    "inbound_enabled": true,
    "imported_at": "2026-01-01T12:00:00+00:00",
    "purchased_at": "2026-01-01T12:00:00+00:00",
    "released_at": "2026-01-01T12:00:00+00:00",
    "last_inbound_at": "2026-01-01T12:00:00+00:00",
    "last_outbound_at": "2026-01-01T12:00:00+00:00",
    "monthly_cost": "string",
    "setup_cost": "string",
    "currency": "string",
    "notes": "string",
    "settings": {},
    "metadata": {},
    "created_at": "2026-01-01T12:00:00+00:00",
    "updated_at": "2026-01-01T12:00:00+00:00",
    "deleted_at": "2026-01-01T12:00:00+00:00",
    "phone_number_hook_id": "01JQ0000000000000000000000"
  }
}

Import every number a carrier account already owns, updating existing rows and marking vanished ones released ​

POST/telephony/phone-numbers/import
  • Handler-ul nu impune niciun scope — orice cheie validă îl poate apela.
  • Request body keys are camelCase (e.g. telephonyAccountId), not the snake_case the rest of the wire format uses

Corpul cererii

CâmpTipObligatoriuNote
providertwilio · telnyx · didww · plivo · zadarma · didlogic …da§8.1. The telephony providers CallAgent can terminate or originate through. The value is what is stored in phone_numbers.provider, sip_trunks.provider and provider_credentials.provider — keep them stable, they are persisted.
telephonyAccountIdstring | null—
bash
curl -X POST "$CALLAGENT_API_URL/telephony/phone-numbers/import" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
       "provider": "twilio"
     }'
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/telephony/phone-numbers/import`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "provider": "twilio"
  }),
});

if (!response.ok) {
  const { error } = await response.json();
  throw new Error(`${error.type}: ${error.message}`);
}

const { data } = await response.json();
php
<?php

$handle = curl_init(getenv('CALLAGENT_API_URL') . '/telephony/phone-numbers/import');

curl_setopt_array($handle, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
        'Accept: application/json',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
    'provider' => 'twilio',
]),
]);

$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);

if ($status >= 400) {
    throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}

$data = $body['data'];
python
import os, requests

response = requests.post(
    f"{os.environ['CALLAGENT_API_URL']}/telephony/phone-numbers/import",
    headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
    json={
      "provider": "twilio"
    },
    timeout=30,
)
response.raise_for_status()
data = response.json()["data"]

Răspunsuri

StatusCorp
200JSON object

Erori

StatusCând apare
422Validation failed, unknown provider, or no active credential for the provider
501The provider has no adapter or no inventory API wired up
502The carrier rejected the inventory call
504The carrier could not be reached

Exemplu de răspuns, generat din schemă:

json
{
  "data": {
    "imported": 1,
    "updated": 1,
    "missing": 1,
    "numbers": [
      "string"
    ]
  }
}

Buy a number at the carrier, persist it only after the carrier confirms, then push webhook config best-effort ​

POST/telephony/phone-numbers/purchase
  • Handler-ul nu impune niciun scope — orice cheie validă îl poate apela.
  • Request body keys are camelCase (e.g. telephonyAccountId, friendlyName), not the snake_case the rest of the wire format uses

Corpul cererii

CâmpTipObligatoriuNote
providertwilio · telnyx · didww · plivo · zadarma · didlogic …da§8.1. The telephony providers CallAgent can terminate or originate through. The value is what is stored in phone_numbers.provider, sip_trunks.provider and provider_credentials.provider — keep them stable, they are persisted.
numberstringdamax 32 chars
telephonyAccountIdstring | null—
friendlyNamestring | null—max 255 chars
bash
curl -X POST "$CALLAGENT_API_URL/telephony/phone-numbers/purchase" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
       "provider": "twilio",
       "number": "+40712345678",
       "friendlyName": "Support Line"
     }'
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/telephony/phone-numbers/purchase`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "provider": "twilio",
    "number": "+40712345678",
    "friendlyName": "Support Line"
  }),
});

if (!response.ok) {
  const { error } = await response.json();
  throw new Error(`${error.type}: ${error.message}`);
}

const { data } = await response.json();
php
<?php

$handle = curl_init(getenv('CALLAGENT_API_URL') . '/telephony/phone-numbers/purchase');

curl_setopt_array($handle, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
        'Accept: application/json',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
    'provider' => 'twilio',
    'number' => '+40712345678',
    'friendlyName' => 'Support Line',
]),
]);

$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);

if ($status >= 400) {
    throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}

$data = $body['data'];
python
import os, requests

response = requests.post(
    f"{os.environ['CALLAGENT_API_URL']}/telephony/phone-numbers/purchase",
    headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
    json={
      "provider": "twilio",
      "number": "+40712345678",
      "friendlyName": "Support Line"
    },
    timeout=30,
)
response.raise_for_status()
data = response.json()["data"]

Răspunsuri

StatusCorp
200JSON object
201data-wrapped PhoneNumber

Erori

StatusCând apare
422Validation failed, unknown provider, or no active credential for the provider
501The provider has no adapter or no programmatic purchase API
502The carrier rejected the purchase
504The carrier could not be reached

Exemplu de răspuns, generat din schemă:

json
"string"

Search a carrier's inventory for available numbers by country, type, area code or pattern before buying ​

POST/telephony/phone-numbers/search
  • Handler-ul nu impune niciun scope — orice cheie validă îl poate apela.
  • Request body keys are camelCase (e.g. areaCode), not the snake_case the rest of the wire format uses

Corpul cererii

CâmpTipObligatoriuNote
providertwilio · telnyx · didww · plivo · zadarma · didlogic …da§8.1. The telephony providers CallAgent can terminate or originate through. The value is what is stored in phone_numbers.provider, sip_trunks.provider and provider_credentials.provider — keep them stable, they are persisted.
countrystringdamax 2 chars. min 2 chars
typelocal · mobile · toll_free · national · null | null—
areaCodestring | null—max 8 chars
containsstring | null—max 32 chars
regionstring | null—max 64 chars
localitystring | null—max 64 chars
capabilitiesstring[] | null—
limitinteger | null—min 1. max 100
bash
curl -X POST "$CALLAGENT_API_URL/telephony/phone-numbers/search" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
       "provider": "twilio",
       "country": "string",
       "type": "local",
       "limit": 25
     }'
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/telephony/phone-numbers/search`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "provider": "twilio",
    "country": "string",
    "type": "local",
    "limit": 25
  }),
});

if (!response.ok) {
  const { error } = await response.json();
  throw new Error(`${error.type}: ${error.message}`);
}

const { data } = await response.json();
php
<?php

$handle = curl_init(getenv('CALLAGENT_API_URL') . '/telephony/phone-numbers/search');

curl_setopt_array($handle, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
        'Accept: application/json',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
    'provider' => 'twilio',
    'country' => 'string',
    'type' => 'local',
    'limit' => 25,
]),
]);

$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);

if ($status >= 400) {
    throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}

$data = $body['data'];
python
import os, requests

response = requests.post(
    f"{os.environ['CALLAGENT_API_URL']}/telephony/phone-numbers/search",
    headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
    json={
      "provider": "twilio",
      "country": "string",
      "type": "local",
      "limit": 25
    },
    timeout=30,
)
response.raise_for_status()
data = response.json()["data"]

Răspunsuri

StatusCorp
200JSON object

Erori

StatusCând apare
422Validation failed, unknown provider, or no active credential for the provider
501The provider has no adapter or no number-search API
502The carrier rejected the search
504The carrier could not be reached

Exemplu de răspuns, generat din schemă:

json
{
  "data": {}
}

Scrisă după cod. Ce nu este încă implementat este marcat ca atare, niciodată descris ca funcțional.