OpenAPI: Difference between revisions
No edit summary |
No edit summary |
||
| Line 10: | Line 10: | ||
Both global and tenant-level keys are supported. | Both global and tenant-level keys are supported. | ||
The implemented API object is <code>extension</code>. It provides endpoints for listing extensions | The implemented API object is <code>extension</code>. It provides endpoints for listing, retrieving, creating, modifying, and deleting extensions. | ||
== OpenAPI Specification == | == OpenAPI Specification == | ||
| Line 336: | Line 336: | ||
} | } | ||
</pre> | </pre> | ||
== Create Extension == | |||
This endpoint creates one extension. A full API key is required. Read-only API keys are rejected. | |||
The request is checked against the installed license before the extension is created. | |||
=== Endpoint === | |||
<pre> | |||
POST openapi.php/extensions | |||
</pre> | |||
Alternative compatibility format: | |||
<pre> | |||
POST openapi.php?object=extension&action=add | |||
POST openapi.php?object=extension&action=create | |||
</pre> | |||
=== Parameters === | |||
{| class="wikitable" | |||
! Name | |||
! Required | |||
! Description | |||
|- | |||
| <code>key</code> | |||
| Yes, unless using header authentication | |||
| Full API key | |||
|- | |||
| <code>tenant</code> | |||
| Yes | |||
| Tenant code or tenant name | |||
|} | |||
=== Request Body === | |||
The body is JSON. The API accepts the extension table fields used by the web page, such as <code>ex_number</code>, <code>ex_name</code>, <code>ex_tech</code>, and the technology table fields for <code>sipfriends</code>, <code>ps_endpoints</code>, <code>ps_aors</code>, <code>ps_auths</code>, <code>ce_customextensions</code>, and <code>ve_virtualextensions</code>. | |||
Short aliases are also accepted: | |||
{| class="wikitable" | |||
! Alias | |||
! Field | |||
|- | |||
| <code>number</code> | |||
| <code>ex_number</code> | |||
|- | |||
| <code>name</code> | |||
| <code>ex_name</code> | |||
|- | |||
| <code>tech</code> | |||
| <code>ex_tech</code> | |||
|- | |||
| <code>password</code> | |||
| SIP <code>secret</code> or PJSIP auth <code>password</code> | |||
|- | |||
| <code>username</code> | |||
| Technology username | |||
|- | |||
| <code>sipusername</code> | |||
| Technology username, matching the web page field | |||
|- | |||
| <code>mailbox</code> | |||
| <code>ex_mailbox</code> and PJSIP <code>mailboxes</code> | |||
|} | |||
Supported technologies are <code>SIP</code>, <code>PJSIP</code>, <code>CUSTOM</code>, and <code>VIRTUAL</code>. If <code>tech</code> is omitted, <code>PJSIP</code> is used. | |||
=== Example Request === | |||
<pre> | |||
curl \ | |||
-X POST \ | |||
-H "Content-Type: application/json" \ | |||
-H "X-API-Key: APIKEY" \ | |||
-d '{"number":"100","name":"Reception","tech":"PJSIP","password":"secret-password"}' \ | |||
"https://pbx.example.com/openapi.php/extensions?tenant=TENANTCODE" | |||
</pre> | |||
Nested technology fields can also be supplied: | |||
<pre> | |||
{ | |||
"ex_number": "100", | |||
"ex_name": "Reception", | |||
"ex_tech": "PJSIP", | |||
"ps_aors": { | |||
"max_contacts": 99 | |||
}, | |||
"ps_endpoints": { | |||
"allow": "alaw:20;ulaw:20" | |||
}, | |||
"ps_auths": { | |||
"password": "secret-password" | |||
} | |||
} | |||
</pre> | |||
=== Example Response === | |||
The response is the same detailed extension object returned by the get endpoint, with HTTP status <code>201</code>. | |||
== Modify Extension == | |||
This endpoint modifies an existing extension. A full API key is required. Read-only API keys are rejected. | |||
The extension can be selected by internal ID or extension number. Use either <code>id</code> or <code>number</code>, not both. | |||
=== Endpoints === | |||
<pre> | |||
PUT openapi.php/extension?id=EXTENSION_ID | |||
PATCH openapi.php/extension?id=EXTENSION_ID | |||
PATCH openapi.php/extensions/EXTENSION_ID | |||
</pre> | |||
Alternative compatibility format: | |||
<pre> | |||
PUT openapi.php?object=extension&action=update&objectid=EXTENSION_ID | |||
PATCH openapi.php?object=extension&action=modify&objectid=EXTENSION_ID | |||
</pre> | |||
=== Request Body === | |||
The body is JSON and can contain the same table fields accepted by the create endpoint. Only fields included in the body are updated. | |||
Changing the extension technology is not supported. To change technology, delete and recreate the extension. | |||
=== Example Request === | |||
<pre> | |||
curl \ | |||
-X PATCH \ | |||
-H "Content-Type: application/json" \ | |||
-H "X-API-Key: APIKEY" \ | |||
-d '{"ex_name":"Reception Desk","ex_callgroup":"1,2","ex_pickupgroup":"1,2"}' \ | |||
"https://pbx.example.com/openapi.php/extension?id=101&tenant=TENANTCODE" | |||
</pre> | |||
== Delete Extension == | |||
This endpoint deletes an extension and its related technology rows. A full API key is required. Read-only API keys are rejected. | |||
=== Endpoints === | |||
<pre> | |||
DELETE openapi.php/extension?id=EXTENSION_ID | |||
DELETE openapi.php/extensions/EXTENSION_ID | |||
</pre> | |||
Alternative compatibility format: | |||
<pre> | |||
DELETE openapi.php?object=extension&action=delete&objectid=EXTENSION_ID | |||
</pre> | |||
=== Example Request === | |||
<pre> | |||
curl \ | |||
-X DELETE \ | |||
-H "X-API-Key: APIKEY" \ | |||
"https://pbx.example.com/openapi.php/extension?id=101&tenant=TENANTCODE" | |||
</pre> | |||
=== Example Response === | |||
<pre> | |||
{ | |||
"deleted": true, | |||
"id": 101, | |||
"number": "100" | |||
} | |||
</pre> | |||
== Change Logging == | |||
Create, modify, and delete operations write a process log entry and a user activity log entry using the OpenAPI user label. | |||
=== Additional Error Responses === | === Additional Error Responses === | ||
| Line 433: | Line 614: | ||
=== Method Not Allowed === | === Method Not Allowed === | ||
Supported methods are <code>GET</code>, <code>POST</code>, <code>PUT</code>, <code>PATCH</code>, and <code>DELETE</code>. | |||
<pre> | <pre> | ||
| Line 439: | Line 620: | ||
"error": { | "error": { | ||
"code": "method_not_allowed", | "code": "method_not_allowed", | ||
"message": " | "message": "Supported methods are GET, POST, PUT, PATCH and DELETE." | ||
} | } | ||
} | } | ||
| Line 446: | Line 627: | ||
== Notes == | == Notes == | ||
* Read-only API keys are allowed for | * Read-only API keys are allowed for list and get endpoints. | ||
* A full API key is required for create, modify, and delete endpoints. | |||
* The endpoint does not create a web session. | * The endpoint does not create a web session. | ||
* Responses are always JSON. | * Responses are always JSON. | ||
* CORS is enabled with <code>Access-Control-Allow-Origin: *</code>. | * CORS is enabled with <code>Access-Control-Allow-Origin: *</code>. | ||
* <code>OPTIONS</code> requests return HTTP <code>204</code> for browser preflight support. | * <code>OPTIONS</code> requests return HTTP <code>204</code> for browser preflight support. | ||
Revision as of 08:44, 25 May 2026
Overview
openapi.php is the JSON API endpoint based on the OpenAPI specification.
The API uses the existing API keys:
- Full API key:
APIKEY - Read-only API key:
READONLYAPIKEY
Both global and tenant-level keys are supported.
The implemented API object is extension. It provides endpoints for listing, retrieving, creating, modifying, and deleting extensions.
OpenAPI Specification
The OpenAPI specification is available from:
openapi.php openapi.php?spec=1 openapi.php/openapi.json openapi.php/swagger.json
The response is an OpenAPI 3.0.3 JSON document.
Authentication
The API key can be provided in any of these ways.
Query Parameter
openapi.php/extensions?tenant=TENANTCODE&key=APIKEY
Header
X-API-Key: APIKEY
Bearer Token
Authorization: Bearer APIKEY
API Key Scope
Tenant API Key
When using a tenant-level API key, the tenant parameter is required.
openapi.php/extensions?tenant=TENANTCODE&key=TENANT_API_KEY
Global API Key
When using a global API key, tenant is optional.
If tenant is provided, only that tenant's extensions are returned.
If tenant is omitted, extensions from all tenants are returned.
openapi.php/extensions?key=GLOBAL_API_KEY
List Extensions
Endpoint
GET openapi.php/extensions
Alternative compatibility format:
openapi.php?object=extension&action=list
Parameters
| Name | Required | Description |
|---|---|---|
key
|
Yes, unless using header authentication | Full or read-only API key |
tenant
|
Required for tenant keys | Tenant code or tenant name |
Example Request
curl "https://pbx.example.com/openapi.php/extensions?tenant=TENANTCODE&key=APIKEY"
Using header authentication:
curl \ -H "X-API-Key: APIKEY" \ "https://pbx.example.com/openapi.php/extensions?tenant=TENANTCODE"
Using bearer authentication:
curl \ -H "Authorization: Bearer APIKEY" \ "https://pbx.example.com/openapi.php/extensions?tenant=TENANTCODE"
Example Response
[
{
"id": 101,
"number": "100",
"name": "Reception",
"tech": "PJSIP"
},
{
"id": 102,
"number": "101",
"name": "Office",
"tech": "SIP"
}
]
Response Fields
| Field | Type | Description |
|---|---|---|
id
|
integer | Extension internal ID |
number
|
string | Extension number |
name
|
string | Extension display name |
tech
|
string | Extension technology, for example SIP, PJSIP, VIRTUAL, or CUSTOM
|
Get Extension Information
This endpoint returns detailed information for one extension.
The extension can be selected by internal extension ID or by extension number.
When using the global full API key, the response also includes the extension password when a password exists for the extension technology.
Tenant API keys and read-only API keys do not return the extension password.
Endpoints
Get an extension by ID:
GET openapi.php/extension?id=EXTENSION_ID
Alternative path format:
GET openapi.php/extensions/EXTENSION_ID
Get an extension by number:
GET openapi.php/extension?number=EXTENSION_NUMBER
Alternative path format:
GET openapi.php/extensions/number/EXTENSION_NUMBER
Alternative compatibility format:
openapi.php?object=extension&action=info&id=EXTENSION_ID openapi.php?object=extension&action=info&number=EXTENSION_NUMBER
Parameters
| Name | Required | Description |
|---|---|---|
key
|
Yes, unless using header authentication | Full or read-only API key |
tenant
|
Required for tenant keys | Tenant code or tenant name |
id
|
Required if number is not provided
|
Extension internal ID |
number
|
Required if id is not provided
|
Extension number |
Use either id or number, not both.
When using a global API key without the tenant parameter, selecting by extension number can match more than one tenant. In that case the request returns an error and the request should be repeated using the tenant parameter or the extension ID.
Example Requests
Get by ID:
curl "https://pbx.example.com/openapi.php/extension?id=101&tenant=TENANTCODE&key=APIKEY"
Get by number:
curl "https://pbx.example.com/openapi.php/extension?number=100&tenant=TENANTCODE&key=APIKEY"
Using header authentication:
curl \ -H "X-API-Key: APIKEY" \ "https://pbx.example.com/openapi.php/extension?number=100&tenant=TENANTCODE"
Example Response
The response includes all fields from the extension table, the normalized fields id, number, name, and tech, the current state when available, the technology username, technology-specific details, and related records.
Related records are returned in the related object. Depending on the extension configuration, this can include state information, registrations, PJSIP contacts, call groups, pickup groups, destinations, queue membership, allowed queue membership, user profile, routing profiles, client rate, caller ID regex, music on hold, parking lot, conditions, media files, and associated phones.
The me_data binary field from media files is not returned in this response.
{
"ex_id": "101",
"ex_te_id": "1",
"ex_name": "Reception",
"ex_number": "100",
"ex_tech": "PJSIP",
"ex_tech_id": "55",
"tenant_code": "TENANTCODE",
"tenant_name": "Tenant Name",
"id": 101,
"number": "100",
"name": "Reception",
"tech": "PJSIP",
"username": "100",
"state": "NOT_INUSE",
"st_state": "NOT_INUSE",
"tech_details": {
"endpoint": {
"id": "100",
"tech_id": "55",
"te_id": "1"
},
"aor": {
"id": "100",
"max_contacts": "99"
},
"auth": {
"id": "100",
"username": "100"
}
},
"related": {
"state": {
"st_extension": "100",
"st_state": "NOT_INUSE"
},
"callgroups": [],
"pickupgroups": [],
"destinations": [],
"referenced_by_destinations": [],
"queue_members": [],
"allowed_queue_members": [],
"userprofile": {
"up_id": "3",
"up_name": "Basic user panel"
},
"routing_profile": {
"rp_id": "1",
"rp_name": "Default"
},
"sms_routing_profile": false,
"client_rate": false,
"callerid_regex": false,
"callerid_regex_rules": [],
"music_on_hold": false,
"parkinglot": false,
"conditions": [],
"mediafiles": [],
"phones": []
}
}
When the global full API key is used, the response can also include:
{
"password": "extension_password"
}
Create Extension
This endpoint creates one extension. A full API key is required. Read-only API keys are rejected.
The request is checked against the installed license before the extension is created.
Endpoint
POST openapi.php/extensions
Alternative compatibility format:
POST openapi.php?object=extension&action=add POST openapi.php?object=extension&action=create
Parameters
| Name | Required | Description |
|---|---|---|
key
|
Yes, unless using header authentication | Full API key |
tenant
|
Yes | Tenant code or tenant name |
Request Body
The body is JSON. The API accepts the extension table fields used by the web page, such as ex_number, ex_name, ex_tech, and the technology table fields for sipfriends, ps_endpoints, ps_aors, ps_auths, ce_customextensions, and ve_virtualextensions.
Short aliases are also accepted:
| Alias | Field |
|---|---|
number
|
ex_number
|
name
|
ex_name
|
tech
|
ex_tech
|
password
|
SIP secret or PJSIP auth password
|
username
|
Technology username |
sipusername
|
Technology username, matching the web page field |
mailbox
|
ex_mailbox and PJSIP mailboxes
|
Supported technologies are SIP, PJSIP, CUSTOM, and VIRTUAL. If tech is omitted, PJSIP is used.
Example Request
curl \
-X POST \
-H "Content-Type: application/json" \
-H "X-API-Key: APIKEY" \
-d '{"number":"100","name":"Reception","tech":"PJSIP","password":"secret-password"}' \
"https://pbx.example.com/openapi.php/extensions?tenant=TENANTCODE"
Nested technology fields can also be supplied:
{
"ex_number": "100",
"ex_name": "Reception",
"ex_tech": "PJSIP",
"ps_aors": {
"max_contacts": 99
},
"ps_endpoints": {
"allow": "alaw:20;ulaw:20"
},
"ps_auths": {
"password": "secret-password"
}
}
Example Response
The response is the same detailed extension object returned by the get endpoint, with HTTP status 201.
Modify Extension
This endpoint modifies an existing extension. A full API key is required. Read-only API keys are rejected.
The extension can be selected by internal ID or extension number. Use either id or number, not both.
Endpoints
PUT openapi.php/extension?id=EXTENSION_ID PATCH openapi.php/extension?id=EXTENSION_ID PATCH openapi.php/extensions/EXTENSION_ID
Alternative compatibility format:
PUT openapi.php?object=extension&action=update&objectid=EXTENSION_ID PATCH openapi.php?object=extension&action=modify&objectid=EXTENSION_ID
Request Body
The body is JSON and can contain the same table fields accepted by the create endpoint. Only fields included in the body are updated.
Changing the extension technology is not supported. To change technology, delete and recreate the extension.
Example Request
curl \
-X PATCH \
-H "Content-Type: application/json" \
-H "X-API-Key: APIKEY" \
-d '{"ex_name":"Reception Desk","ex_callgroup":"1,2","ex_pickupgroup":"1,2"}' \
"https://pbx.example.com/openapi.php/extension?id=101&tenant=TENANTCODE"
Delete Extension
This endpoint deletes an extension and its related technology rows. A full API key is required. Read-only API keys are rejected.
Endpoints
DELETE openapi.php/extension?id=EXTENSION_ID DELETE openapi.php/extensions/EXTENSION_ID
Alternative compatibility format:
DELETE openapi.php?object=extension&action=delete&objectid=EXTENSION_ID
Example Request
curl \ -X DELETE \ -H "X-API-Key: APIKEY" \ "https://pbx.example.com/openapi.php/extension?id=101&tenant=TENANTCODE"
Example Response
{
"deleted": true,
"id": 101,
"number": "100"
}
Change Logging
Create, modify, and delete operations write a process log entry and a user activity log entry using the OpenAPI user label.
Additional Error Responses
Missing Identifier
{
"error": {
"code": "missing_identifier",
"message": "Provide an extension id or number."
}
}
Invalid Identifier
{
"error": {
"code": "invalid_identifier",
"message": "Use either id or number, not both."
}
}
Extension Not Found
{
"error": {
"code": "extension_not_found",
"message": "Extension not found."
}
}
Multiple Extensions Found
{
"error": {
"code": "multiple_extensions_found",
"message": "Multiple extensions match the requested number. Use the tenant parameter or the extension id."
}
}
Error Responses
Errors are returned as JSON.
Missing API Key
{
"error": {
"code": "missing_api_key",
"message": "Missing API key."
}
}
Invalid API Key
{
"error": {
"code": "invalid_api_key",
"message": "Invalid API key."
}
}
Tenant Not Found
{
"error": {
"code": "tenant_not_found",
"message": "Tenant not found."
}
}
Endpoint Not Found
{
"error": {
"code": "not_found",
"message": "Endpoint not found."
}
}
Method Not Allowed
Supported methods are GET, POST, PUT, PATCH, and DELETE.
{
"error": {
"code": "method_not_allowed",
"message": "Supported methods are GET, POST, PUT, PATCH and DELETE."
}
}
Notes
- Read-only API keys are allowed for list and get endpoints.
- A full API key is required for create, modify, and delete endpoints.
- The endpoint does not create a web session.
- Responses are always JSON.
- CORS is enabled with
Access-Control-Allow-Origin: *. OPTIONSrequests return HTTP204for browser preflight support.