Community setup guide · Customer guide
API reference
Every public CEN API endpoint, with authentication, parameters, responses, errors and examples. PBXs set up with the CEN config files only use POST /v1/dial; the other endpoints are for your own software, monitoring and custom integrations.
Basics
- Base URL
https://api.cenpbx.com. HTTPS only; responses are JSON. - Authenticate with
Authorization: Bearer cen_net_…. Owners create keys in manage.cenpbx.com → your network → API access. Keys in query strings are ignored. - Limits: 120 requests per minute per network and 600 per minute per IP. A 429 includes
Retry-Afterin seconds. - Numbers are ASCII digits only, with no spaces, hyphens or access prefix.
POST /v1/dial: who to call
What PBXs use. Returns a ready-to-dial Asterisk dial string for the PBX that answers a number.
| Form field | Value |
|---|---|
| auth | A branch key (cen_live_) or network key (cen_net_). A Bearer header also works. |
| num | 10 digits, or 7 digits (block + line) in the caller’s own area when using a branch key. |
| ani | Optional: the caller’s CEN number. |
curl -s -D - https://api.cenpbx.com/v1/dial -d "num=2143151234&ani=9163151001&auth=$CEN_KEY" HTTP/2 200 content-type: text/plain; charset=utf-8 x-cen-code: OK IAX2/from-cen:[email protected]:4569/2143151234
The body is plain text so Asterisk can use it with CURL(). A failure returns just the code, for example CEN-03, in the body and the X-CEN-Code header. It can never pass the dialplan’s dial-string check; the PBX plays the matching announcement instead.
| HTTP | X-CEN-Code | Meaning |
|---|---|---|
| 200 | OK | Body is the dial string |
| 401 | CEN-11 | Missing, wrong, expired or revoked key |
| 403 | CEN-10 | Calling branch or network is suspended, retired or has calls disabled |
| 422 | CEN-07 | Not 7 or 10 digits |
| 429 | CEN-12 | Over 120 lookups a minute; see Retry-After |
| 404 | CEN-01 … CEN-09 | The destination can’t take the call; see the table below |
GET /v1/route: directory lookup
Finds which network owns a 10-digit CEN number and where its Routing API is.
curl -s -H "Authorization: Bearer $CEN_KEY" "https://api.cenpbx.com/v1/route?number=2143151234"
{
"success": true,
"status": "route",
"destination": {
"area_code": "214",
"network_name": "Example Network",
"routing_api": "https://routing.example.net/cen/route",
"local_number": "3151234"
}
}
For CEN-hosted networks routing_api is CEN’s hosted endpoint below.
GET /v1/networks/{area}/route: CEN-hosted Routing API
The Routing API contract, operated by CEN for CEN-hosted networks. Takes the seven-digit local number.
curl -s -H "Authorization: Bearer $CEN_KEY" "https://api.cenpbx.com/v1/networks/916/route?number=3151234"
{
"success": true,
"status": "route",
"destination": { "protocol": "iax2", "block": "315", "number": "1234", "host": "pbx.d52.example.org", "port": 4569 }
}
The host is the branch’s own PBX as listed at manage.cenpbx.com. Calling it needs IAX trust agreed with that network.
Intercepts
An intercept is a normal answer (HTTP 200) meaning “don’t connect”:
{ "success": true, "status": "intercept", "reason": "maintenance", "code": "CEN-03" }
| Code | Meaning | Used when |
|---|---|---|
| CEN-01 | Unassigned exchange | No network owns the area code, or no branch owns the block. |
| CEN-02 | Exchange suspended | The destination network or branch is suspended by CEN. |
| CEN-03 | Maintenance | The destination is paused or not yet activated. |
| CEN-04 | Exchange retired | The destination network or branch is retired. |
| CEN-05 | Network unavailable | The destination network’s Routing API failed or answered incorrectly. |
| CEN-06 | Destination unreachable | The destination has no IAX password yet, or its PBX did not answer the IAX call. |
| CEN-07 | Invalid number | Not 7 or 10 digits, or 7 digits dialed without an area code where one is needed. |
| CEN-08 | Number not found | The destination network’s Routing API says the number is not in service. |
| CEN-09 | Incoming calls disabled | The destination has turned off receiving calls. |
| CEN-10 | Outgoing calls disabled | The calling branch or network is suspended, retired or has placing calls turned off. |
| CEN-11 | Authentication failure | CEN_KEY is missing, wrong, expired or revoked. |
| CEN-12 | Service temporarily unavailable | Too many lookups, or the PBX could not reach CEN. |
JSON endpoints also return a reason such as maintenance. Recordings and wording: Intercept codes.
Errors
| HTTP | Body | Fix |
|---|---|---|
| 401 | {"success":false,"error":"unauthenticated"} | Missing, wrong, expired or revoked key |
| 403 | {"success":false,"error":"origin_forbidden"} | Your network is suspended, retired or has calls disabled |
| 422 | {"success":false,"error":"invalid_number"} | Wrong digit count or non-digits |
| 429 | {"success":false,"error":"rate_limited"} | Wait Retry-After seconds |
Client examples
PHP
$ch = curl_init('https://api.cenpbx.com/v1/route?number=' . rawurlencode('2143151234'));
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 5, CURLOPT_FOLLOWLOCATION => false,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('CEN_KEY'), 'Accept: application/json'],
]);
$result = json_decode(curl_exec($ch), true);
if (($result['status'] ?? null) === 'route') {
echo $result['destination']['routing_api'];
}
Python
import json, os, urllib.request
req = urllib.request.Request('https://api.cenpbx.com/v1/route?number=2143151234',
headers={'Authorization': 'Bearer ' + os.environ['CEN_KEY'], 'Accept': 'application/json'})
with urllib.request.urlopen(req, timeout=5) as response:
result = json.load(response)
print(result['status'], result.get('code') or result['destination']['routing_api'])
Try requests in the API Explorer with your network key.
Legacy endpoints
/v1/legacy/route and /v2/route accept older cen_live_ block keys for seven-digit lookups while clients migrate. See Legacy migration.