OpenAPI: Difference between revisions

From MiRTA PBX documentation
Jump to navigation Jump to search
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, retrieving, creating, modifying, and deleting extensions.
The implemented API objects are <code>extension</code>, <code>voicemail</code>, <code>condition</code>, <code>huntlist</code>, <code>did</code>, and <code>queue</code>. They provide endpoints for listing, retrieving, creating, modifying, and deleting configuration records.


== OpenAPI Specification ==
== OpenAPI Specification ==
Line 61: Line 61:
When using a global API key, <code>tenant</code> is optional.
When using a global API key, <code>tenant</code> is optional.


If <code>tenant</code> is provided, only that tenant's extensions are returned.
If <code>tenant</code> is provided, only that tenant's records are returned.


If <code>tenant</code> is omitted, extensions from all tenants are returned.
If <code>tenant</code> is omitted, records from all tenants are returned for list and get requests.


<pre>
<pre>
Line 512: Line 512:
   "number": "100"
   "number": "100"
}
}
</pre>
== Additional Configuration Objects ==
The following objects use the same authentication and HTTP behavior as extensions.
{| class="wikitable"
! Object
! List Endpoint
! Single Endpoint
! ID Field
! Main Table
|-
| <code>voicemail</code>
| <code>GET openapi.php/voicemails</code>
| <code>openapi.php/voicemail?id=ID</code>
| <code>uniqueid</code>
| <code>voicemail</code>
|-
| <code>condition</code>
| <code>GET openapi.php/conditions</code>
| <code>openapi.php/condition?id=ID</code>
| <code>co_id</code>
| <code>co_conditions</code>
|-
| <code>huntlist</code>
| <code>GET openapi.php/huntlists</code>
| <code>openapi.php/huntlist?id=ID</code>
| <code>hu_id</code>
| <code>hu_huntlists</code>
|-
| <code>did</code>
| <code>GET openapi.php/dids</code>
| <code>openapi.php/did?id=ID</code>
| <code>di_id</code>
| <code>di_dids</code>
|-
| <code>queue</code>
| <code>GET openapi.php/queues</code>
| <code>openapi.php/queue?id=ID</code>
| <code>qu_id</code>
| <code>qu_queues</code>
|}
=== Generic Endpoints ===
Use the plural path for list and create operations:
<pre>
GET openapi.php/voicemails
POST openapi.php/voicemails
GET openapi.php/conditions
POST openapi.php/conditions
GET openapi.php/huntlists
POST openapi.php/huntlists
GET openapi.php/dids
POST openapi.php/dids
GET openapi.php/queues
POST openapi.php/queues
</pre>
Use either the singular endpoint with an <code>id</code> parameter or the plural path with the ID:
<pre>
GET openapi.php/voicemail?id=ID
PATCH openapi.php/voicemail?id=ID
DELETE openapi.php/voicemail?id=ID
GET openapi.php/voicemails/ID
PATCH openapi.php/voicemails/ID
DELETE openapi.php/voicemails/ID
</pre>
The same pattern applies to <code>condition</code>, <code>huntlist</code>, <code>did</code>, and <code>queue</code>.
Alternative compatibility format:
<pre>
openapi.php?object=voicemail&action=list
openapi.php?object=voicemail&action=info&id=ID
openapi.php?object=voicemail&action=create
openapi.php?object=voicemail&action=modify&id=ID
openapi.php?object=voicemail&action=delete&id=ID
</pre>
=== Generic Request Body ===
The body is JSON. Fields can be supplied using the database column names used by the web pages.
Short aliases are supported where they are unambiguous:
{| class="wikitable"
! Object
! Alias
! Field
|-
| <code>voicemail</code>
| <code>number</code>
| <code>mailbox</code>
|-
| <code>voicemail</code>
| <code>name</code>
| <code>fullname</code>
|-
| <code>condition</code>
| <code>name</code>
| <code>co_name</code>
|-
| <code>condition</code>
| <code>type</code>
| <code>co_type</code>
|-
| <code>huntlist</code>
| <code>name</code>
| <code>hu_name</code>
|-
| <code>huntlist</code>
| <code>number</code>
| <code>hu_number</code>
|-
| <code>did</code>
| <code>number</code>
| <code>di_number</code>
|-
| <code>queue</code>
| <code>name</code>
| <code>qu_name</code>
|}
=== Destinations ===
Objects that use destinations accept a <code>destinations</code> object. Each destination item can be either a string in <code>TYPE-ID</code> format or an object with <code>type</code> and <code>id</code>.
<pre>
{
  "di_number": "390212345678",
  "di_comment": "Main number",
  "destinations": {
    "DID": ["EXT-101"],
    "DID-UNCONDITIONAL": [
      { "type": "VOICEMAIL", "id": 10 }
    ]
  }
}
</pre>
Supported destination keys:
{| class="wikitable"
! Object
! Destination Keys
|-
| <code>voicemail</code>
| <code>VOICEMAIL-OPERATOR</code>, <code>VOICEMAIL-FOLLOW</code>, <code>VOICEMAIL-BROADCAST</code>
|-
| <code>condition</code>
| <code>CONDITION</code>, <code>NOTCONDITION</code>, and <code>CONDITION1</code> through <code>CONDITION20</code>
|-
| <code>huntlist</code>
| <code>HUNTLIST</code>, <code>HUNTLIST-TIMEOUT</code>
|-
| <code>did</code>
| <code>DID</code>, <code>DID-UNCONDITIONAL</code>, <code>DID-SMS</code>, <code>DID-FAXSUCCESS</code>
|-
| <code>queue</code>
| <code>QUEUE-FULL</code>, <code>QUEUE-TIMEOUT</code>, <code>QUEUE-EXITKEY</code>, <code>QUEUE-ONCALLBACK</code>, <code>QUEUE-NOBODYHOME</code>, <code>QUEUE-NOFREEMEMBER</code>, <code>QUEUE-PERIODICANNOUNCE</code>, <code>QUEUE-BEFORERINGING</code>, <code>QUEUE-ONAUTOPAUSE</code>, <code>QUEUE-ONABANDONEDCALL</code>
|}
=== Related Records ===
Get responses include a <code>related</code> object when the object has related configuration.
For conditions, <code>related.extended_infos</code> contains rows from <code>ce_conditions_extended</code>. Create and modify requests can replace these rows by sending <code>extended_infos</code>.
For queues, <code>related.realtime</code> contains the realtime <code>queue</code> row. Create and modify requests can send realtime queue fields either at the top level or nested under <code>queue</code> or <code>realtime</code>. Queue members can be replaced by sending <code>members</code>, <code>queue_member</code>, or <code>queue_members</code>. Allowed queue members can be replaced by sending <code>allowed_members</code>, <code>aq_allowed_queue_member</code>, or <code>allowed_queue_members</code>.
For hunt lists, create and modify requests update the matching follow-me records used by the dialplan.
=== Examples ===
Create a voicemail:
<pre>
curl \
  -X POST \
  -H "Content-Type: application/json" \
  -H "X-API-Key: APIKEY" \
  -d '{"mailbox":"200","fullname":"Sales","password":"1234","email":"sales@example.com"}' \
  "https://pbx.example.com/openapi.php/voicemails?tenant=TENANTCODE"
</pre>
Modify a DID destination:
<pre>
curl \
  -X PATCH \
  -H "Content-Type: application/json" \
  -H "X-API-Key: APIKEY" \
  -d '{"destinations":{"DID":["EXT-101"]}}' \
  "https://pbx.example.com/openapi.php/did?id=25&tenant=TENANTCODE"
</pre>
Create a queue with realtime fields:
<pre>
curl \
  -X POST \
  -H "Content-Type: application/json" \
  -H "X-API-Key: APIKEY" \
  -d '{"qu_name":"Support","qu_number":"700","queue":{"strategy":"ringall","timeout":20},"members":[{"membername":"100","interface":"Local/AG-000-NF-101@fromotherpbx/n","state_interface":"Custom:100","member_device":"100","penalty":0,"paused":0}]}' \
  "https://pbx.example.com/openapi.php/queues?tenant=TENANTCODE"
</pre>
</pre>


== Change Logging ==
== Change Logging ==


Create, modify, and delete operations write a process log entry and a user activity log entry using the OpenAPI user label.
Create, modify, and delete operations write a process log entry and a user activity log entry using the OpenAPI user label. Related destination, condition, queue member, and queue realtime changes are also logged where applicable.


=== Additional Error Responses ===
=== Additional Error Responses ===

Revision as of 10:17, 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 objects are extension, voicemail, condition, huntlist, did, and queue. They provide endpoints for listing, retrieving, creating, modifying, and deleting configuration records.

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
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 records are returned.

If tenant is omitted, records from all tenants are returned for list and get requests.

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"
}

Additional Configuration Objects

The following objects use the same authentication and HTTP behavior as extensions.

Object List Endpoint Single Endpoint ID Field Main Table
voicemail GET openapi.php/voicemails openapi.php/voicemail?id=ID uniqueid voicemail
condition GET openapi.php/conditions openapi.php/condition?id=ID co_id co_conditions
huntlist GET openapi.php/huntlists openapi.php/huntlist?id=ID hu_id hu_huntlists
did GET openapi.php/dids openapi.php/did?id=ID di_id di_dids
queue GET openapi.php/queues openapi.php/queue?id=ID qu_id qu_queues

Generic Endpoints

Use the plural path for list and create operations:

GET openapi.php/voicemails
POST openapi.php/voicemails
GET openapi.php/conditions
POST openapi.php/conditions
GET openapi.php/huntlists
POST openapi.php/huntlists
GET openapi.php/dids
POST openapi.php/dids
GET openapi.php/queues
POST openapi.php/queues

Use either the singular endpoint with an id parameter or the plural path with the ID:

GET openapi.php/voicemail?id=ID
PATCH openapi.php/voicemail?id=ID
DELETE openapi.php/voicemail?id=ID

GET openapi.php/voicemails/ID
PATCH openapi.php/voicemails/ID
DELETE openapi.php/voicemails/ID

The same pattern applies to condition, huntlist, did, and queue.

Alternative compatibility format:

openapi.php?object=voicemail&action=list
openapi.php?object=voicemail&action=info&id=ID
openapi.php?object=voicemail&action=create
openapi.php?object=voicemail&action=modify&id=ID
openapi.php?object=voicemail&action=delete&id=ID

Generic Request Body

The body is JSON. Fields can be supplied using the database column names used by the web pages.

Short aliases are supported where they are unambiguous:

Object Alias Field
voicemail number mailbox
voicemail name fullname
condition name co_name
condition type co_type
huntlist name hu_name
huntlist number hu_number
did number di_number
queue name qu_name

Destinations

Objects that use destinations accept a destinations object. Each destination item can be either a string in TYPE-ID format or an object with type and id.

{
  "di_number": "390212345678",
  "di_comment": "Main number",
  "destinations": {
    "DID": ["EXT-101"],
    "DID-UNCONDITIONAL": [
      { "type": "VOICEMAIL", "id": 10 }
    ]
  }
}

Supported destination keys:

Object Destination Keys
voicemail VOICEMAIL-OPERATOR, VOICEMAIL-FOLLOW, VOICEMAIL-BROADCAST
condition CONDITION, NOTCONDITION, and CONDITION1 through CONDITION20
huntlist HUNTLIST, HUNTLIST-TIMEOUT
did DID, DID-UNCONDITIONAL, DID-SMS, DID-FAXSUCCESS
queue QUEUE-FULL, QUEUE-TIMEOUT, QUEUE-EXITKEY, QUEUE-ONCALLBACK, QUEUE-NOBODYHOME, QUEUE-NOFREEMEMBER, QUEUE-PERIODICANNOUNCE, QUEUE-BEFORERINGING, QUEUE-ONAUTOPAUSE, QUEUE-ONABANDONEDCALL

Get responses include a related object when the object has related configuration.

For conditions, related.extended_infos contains rows from ce_conditions_extended. Create and modify requests can replace these rows by sending extended_infos.

For queues, related.realtime contains the realtime queue row. Create and modify requests can send realtime queue fields either at the top level or nested under queue or realtime. Queue members can be replaced by sending members, queue_member, or queue_members. Allowed queue members can be replaced by sending allowed_members, aq_allowed_queue_member, or allowed_queue_members.

For hunt lists, create and modify requests update the matching follow-me records used by the dialplan.

Examples

Create a voicemail:

curl \
  -X POST \
  -H "Content-Type: application/json" \
  -H "X-API-Key: APIKEY" \
  -d '{"mailbox":"200","fullname":"Sales","password":"1234","email":"sales@example.com"}' \
  "https://pbx.example.com/openapi.php/voicemails?tenant=TENANTCODE"

Modify a DID destination:

curl \
  -X PATCH \
  -H "Content-Type: application/json" \
  -H "X-API-Key: APIKEY" \
  -d '{"destinations":{"DID":["EXT-101"]}}' \
  "https://pbx.example.com/openapi.php/did?id=25&tenant=TENANTCODE"

Create a queue with realtime fields:

curl \
  -X POST \
  -H "Content-Type: application/json" \
  -H "X-API-Key: APIKEY" \
  -d '{"qu_name":"Support","qu_number":"700","queue":{"strategy":"ringall","timeout":20},"members":[{"membername":"100","interface":"Local/AG-000-NF-101@fromotherpbx/n","state_interface":"Custom:100","member_device":"100","penalty":0,"paused":0}]}' \
  "https://pbx.example.com/openapi.php/queues?tenant=TENANTCODE"

Change Logging

Create, modify, and delete operations write a process log entry and a user activity log entry using the OpenAPI user label. Related destination, condition, queue member, and queue realtime changes are also logged where applicable.

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: *.
  • OPTIONS requests return HTTP 204 for browser preflight support.