Skip to content

Extensii ​

8 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/contact-center/extensionsList extensions with a summary projection, filterable by type and active flag, paginated
POST/contact-center/extensionsProvisioning returns the SIP secret exactly once — this response is the only time it is ever readable
GET/contact-center/extensions/{id}Fetch one extension with its full detail projection and its SIP devices (never their secrets)
PATCH/contact-center/extensions/{id}Update an extension's identity, voicemail, forwarding and DND settings, then re-push the FreeSWITCH directory
DELETE/contact-center/extensions/{id}Soft-delete an extension and re-push the FreeSWITCH directory for its organization
POST/contact-center/extensions/{id}/devicesAdd a SIP device to an extension and return its generated secret once; it is never readable again
DELETE/contact-center/extensions/{id}/devices/{deviceId}Revoke a SIP device: deactivate it, soft-delete it, re-push the directory and flush FreeSWITCH's cache
POST/contact-center/extensions/{id}/devices/{deviceId}/rotateIssue a new SIP secret for a device, returning it once; the old secret dies on the next directory push

Endpoint-uri ​

List extensions with a summary projection, filterable by type and active flag, paginated ​

GET/contact-center/extensions
  • Handler-ul nu impune niciun scope — orice cheie validă îl poate apela.

Parametri de interogare

NumeTipObligatoriuNote
typestring—
activeboolean—default false
bash
curl -X GET "$CALLAGENT_API_URL/contact-center/extensions?type=string&active=false" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Accept: application/json"
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/contact-center/extensions?type=string&active=false`, {
  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') . '/contact-center/extensions?type=string&active=false');

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']}/contact-center/extensions?type=string&active=false",
    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": {},
  "meta": {
    "page": 1,
    "limit": 25,
    "total": 1,
    "pages": 1
  }
}

Provisioning returns the SIP secret exactly once — this response is the only time it is ever readable ​

POST/contact-center/extensions
  • Necesită extension.write.
  • extension.write is a user permission checked via Gate; API-key requests have no user, so the check is skipped

Corpul cererii

CâmpTipObligatoriuNote
extensionstring | null—max 24 chars
namestringdamax 255 chars
descriptionstring | null—max 255 chars
typeuser · operator · virtual · queue · ivr · ring_group … | null—
user_idstring | null—
voicemail_box_idstring | null—
outbound_caller_id_numberstring | null—max 32 chars
outbound_caller_id_namestring | null—max 64 chars
ring_timeout_secondsinteger | null—min 5. max 120
with_web_phoneboolean | null—
bash
curl -X POST "$CALLAGENT_API_URL/contact-center/extensions" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
       "name": "Support Line",
       "type": "user",
       "user_id": "01JQ0000000000000000000000",
       "voicemail_box_id": "01JQ0000000000000000000000",
       "outbound_caller_id_number": "+40712345678",
       "outbound_caller_id_name": "Support Line",
       "ring_timeout_seconds": 30
     }'
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/contact-center/extensions`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "name": "Support Line",
    "type": "user",
    "user_id": "01JQ0000000000000000000000",
    "voicemail_box_id": "01JQ0000000000000000000000",
    "outbound_caller_id_number": "+40712345678",
    "outbound_caller_id_name": "Support Line",
    "ring_timeout_seconds": 30
  }),
});

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') . '/contact-center/extensions');

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([
    'name' => 'Support Line',
    'type' => 'user',
    'user_id' => '01JQ0000000000000000000000',
    'voicemail_box_id' => '01JQ0000000000000000000000',
    'outbound_caller_id_number' => '+40712345678',
    'outbound_caller_id_name' => 'Support Line',
    'ring_timeout_seconds' => 30,
]),
]);

$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']}/contact-center/extensions",
    headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
    json={
      "name": "Support Line",
      "type": "user",
      "user_id": "01JQ0000000000000000000000",
      "voicemail_box_id": "01JQ0000000000000000000000",
      "outbound_caller_id_number": "+40712345678",
      "outbound_caller_id_name": "Support Line",
      "ring_timeout_seconds": 30
    },
    timeout=30,
)
response.raise_for_status()
data = response.json()["data"]

Răspunsuri

StatusCorp
200JSON object

Erori

StatusCând apare
403Session user lacks the extension.write permission
409The requested extension number is already in use, including soft-deleted rows
422Validation failed, or a referenced user/voicemail box does not exist

Fetch one extension with its full detail projection and its SIP devices (never their secrets) ​

GET/contact-center/extensions/{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/contact-center/extensions/01JQ0000000000000000000000" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Accept: application/json"
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/contact-center/extensions/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') . '/contact-center/extensions/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']}/contact-center/extensions/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 object

Erori

StatusCând apare
404No such extension for this tenant

Exemplu de răspuns, generat din schemă:

json
{
  "data": {}
}

Update an extension's identity, voicemail, forwarding and DND settings, then re-push the FreeSWITCH directory ​

PATCH/contact-center/extensions/{id}
  • Necesită extension.write.
  • extension.write is a user permission checked via Gate; API-key requests have no user, so the check is skipped

Parametri de cale

NumeTipObligatoriuNote
idstringda

Corpul cererii

CâmpTipObligatoriuNote
namestring—max 255 chars
descriptionstring | null—max 255 chars
user_idstring | null—
voicemail_box_idstring | null—
voicemail_enabledboolean | null—
outbound_caller_id_numberstring | null—max 32 chars
outbound_caller_id_namestring | null—max 64 chars
ring_timeout_secondsinteger | null—min 5. max 120
do_not_disturbboolean | null—
call_waitingboolean | null—
forward_always_enabledboolean | null—
forward_always_destinationstring | null—max 128 chars
is_activeboolean | null—
bash
curl -X PATCH "$CALLAGENT_API_URL/contact-center/extensions/01JQ0000000000000000000000" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
       "name": "Support Line",
       "user_id": "01JQ0000000000000000000000",
       "voicemail_box_id": "01JQ0000000000000000000000",
       "voicemail_enabled": true,
       "outbound_caller_id_number": "+40712345678",
       "outbound_caller_id_name": "Support Line",
       "ring_timeout_seconds": 30
     }'
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/contact-center/extensions/01JQ0000000000000000000000`, {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "name": "Support Line",
    "user_id": "01JQ0000000000000000000000",
    "voicemail_box_id": "01JQ0000000000000000000000",
    "voicemail_enabled": true,
    "outbound_caller_id_number": "+40712345678",
    "outbound_caller_id_name": "Support Line",
    "ring_timeout_seconds": 30
  }),
});

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') . '/contact-center/extensions/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([
    'name' => 'Support Line',
    'user_id' => '01JQ0000000000000000000000',
    'voicemail_box_id' => '01JQ0000000000000000000000',
    'voicemail_enabled' => true,
    'outbound_caller_id_number' => '+40712345678',
    'outbound_caller_id_name' => 'Support Line',
    'ring_timeout_seconds' => 30,
]),
]);

$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']}/contact-center/extensions/01JQ0000000000000000000000",
    headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
    json={
      "name": "Support Line",
      "user_id": "01JQ0000000000000000000000",
      "voicemail_box_id": "01JQ0000000000000000000000",
      "voicemail_enabled": True,
      "outbound_caller_id_number": "+40712345678",
      "outbound_caller_id_name": "Support Line",
      "ring_timeout_seconds": 30
    },
    timeout=30,
)
response.raise_for_status()
data = response.json()["data"]

Răspunsuri

StatusCorp
200JSON object

Erori

StatusCând apare
403Session user lacks the extension.write permission
404No such extension for this tenant
422Validation failed, or a referenced user/voicemail box does not exist

Soft-delete an extension and re-push the FreeSWITCH directory for its organization ​

DELETE/contact-center/extensions/{id}
  • Necesită extension.write.
  • Acest răspuns nu este împachetat în data.
  • extension.write is a user permission checked via Gate; API-key requests have no user, so the check is skipped

Parametri de cale

NumeTipObligatoriuNote
idstringda
bash
curl -X DELETE "$CALLAGENT_API_URL/contact-center/extensions/01JQ0000000000000000000000" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Accept: application/json"
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/contact-center/extensions/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') . '/contact-center/extensions/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']}/contact-center/extensions/01JQ0000000000000000000000",
    headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
    timeout=30,
)
response.raise_for_status()
data = response.json()["data"]

Răspunsuri

StatusCorp
200Bare JSON object, not data-wrapped

Erori

StatusCând apare
403Session user lacks the extension.write permission
404No such extension for this tenant

Add a SIP device to an extension and return its generated secret once; it is never readable again ​

POST/contact-center/extensions/{id}/devices
  • Necesită extension.write.
  • Writes a sip_device.provisioned audit entry and re-pushes the FreeSWITCH directory. extension.write is a Gate permission that API-key requests skip (no user)

Parametri de cale

NumeTipObligatoriuNote
idstringda

Corpul cererii

CâmpTipObligatoriuNote
namestring | null—max 255 chars
device_typewebrtc · softphone · desk_phone · mobile · ata · null | null—
mac_addressstring | null—max 32 chars
vendorstring | null—max 48 chars
modelstring | null—max 48 chars
bash
curl -X POST "$CALLAGENT_API_URL/contact-center/extensions/01JQ0000000000000000000000/devices" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
       "name": "Support Line",
       "device_type": "webrtc"
     }'
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/contact-center/extensions/01JQ0000000000000000000000/devices`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "name": "Support Line",
    "device_type": "webrtc"
  }),
});

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') . '/contact-center/extensions/01JQ0000000000000000000000/devices');

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([
    'name' => 'Support Line',
    'device_type' => 'webrtc',
]),
]);

$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']}/contact-center/extensions/01JQ0000000000000000000000/devices",
    headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
    json={
      "name": "Support Line",
      "device_type": "webrtc"
    },
    timeout=30,
)
response.raise_for_status()
data = response.json()["data"]

Răspunsuri

StatusCorp
200JSON object

Erori

StatusCând apare
403Session user lacks the extension.write permission
404No such extension for this tenant
422Validation failed

Revoke a SIP device: deactivate it, soft-delete it, re-push the directory and flush FreeSWITCH's cache ​

DELETE/contact-center/extensions/{id}/devices/{deviceId}
  • Necesită extension.write.
  • Acest răspuns nu este împachetat în data.
  • extension.write is a user permission checked via Gate; API-key requests have no user, so the check is skipped

Parametri de cale

NumeTipObligatoriuNote
idstringda
deviceIdstringda
bash
curl -X DELETE "$CALLAGENT_API_URL/contact-center/extensions/01JQ0000000000000000000000/devices/01JQ0000000000000000000000" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Accept: application/json"
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/contact-center/extensions/01JQ0000000000000000000000/devices/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') . '/contact-center/extensions/01JQ0000000000000000000000/devices/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']}/contact-center/extensions/01JQ0000000000000000000000/devices/01JQ0000000000000000000000",
    headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
    timeout=30,
)
response.raise_for_status()
data = response.json()["data"]

Răspunsuri

StatusCorp
200Bare JSON object, not data-wrapped

Erori

StatusCând apare
403Session user lacks the extension.write permission
404No such device on this extension

Issue a new SIP secret for a device, returning it once; the old secret dies on the next directory push ​

POST/contact-center/extensions/{id}/devices/{deviceId}/rotate
  • Necesită extension.write.
  • Marks the device unregistered and writes a sip_device.secret_rotated audit entry. extension.write is a Gate permission that API-key requests skip (no user)

Parametri de cale

NumeTipObligatoriuNote
idstringda
deviceIdstringda
bash
curl -X POST "$CALLAGENT_API_URL/contact-center/extensions/01JQ0000000000000000000000/devices/01JQ0000000000000000000000/rotate" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Accept: application/json"
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/contact-center/extensions/01JQ0000000000000000000000/devices/01JQ0000000000000000000000/rotate`, {
  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') . '/contact-center/extensions/01JQ0000000000000000000000/devices/01JQ0000000000000000000000/rotate');

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']}/contact-center/extensions/01JQ0000000000000000000000/devices/01JQ0000000000000000000000/rotate",
    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
403Session user lacks the extension.write permission
404No such device on this extension

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