SARK V6 API
Contents
- 1 sark6api
- 2 sark6api HTTP Requests
- 2.1 Request notation
- 2.2 HTTP Status Codes
- 2.3 Agents
- 2.4 Backups
- 2.5 Class of Service
- 2.6 Custom Apps
- 2.7 Recurring Timers (Daytimers)
- 2.8 Destinations
- 2.9 Extensions
- 2.9.1 GET /extensions/{extension?}
- 2.9.2 GET /extensions/{extension}/runtime
- 2.9.3 POST /extensions/mailbox
- 2.9.4 POST /extensions/provisioned
- 2.9.5 POST /extensions/unprovisioned
- 2.9.6 POST /extensions/webrtc
- 2.9.7 PUT /extensions/{extension}
- 2.9.8 PUT /extensions/{extension}/runtime
- 2.9.9 DELETE /extensions/{extension}
- 2.10 Firewalls
- 2.11 Greetings
- 2.12 Non Recurring Timers (Holidaytimers)
- 2.13 Inbound Routes
- 2.14 IVRs
- 2.15 Logs/CDRs
- 2.16 Queues
- 2.17 Snapshots
- 2.18 Ring Groups
- 2.19 Routes
- 2.20 System Commands
- 2.21 System Globals
- 2.22 Templates
- 2.23 Tenants
- 2.24 Trunks
- 3 Asterisk AMI functions exposed by the API
sark6api
sark6api is a fairly vanilla OAS JSON API. It allows you to programmatically do (almost) anything you can do manually at the SARK V6 browser. Perhaps you have an idea for an extension to SARK, maybe you want to rewrite all or parts of the SARK browser and incorporate it into a package of your own. Perhaps you wish to integrate a click-to-call feature into your web page. Maybe you want to control a remote SARK from a management layer. All of these things are possible with the API.
sark6api requires a SARK V6 instance running on either buster, bionic or focal. This is largely due to the requirement for PHP 7.2.5 or higher, which comes as standard on these releases. Only 64 bit architectures are supported for both X86 and ARM.
- sark6api is tested with Postman 7.2 and developed on Ubuntu 18.04 LTS.
- sark6api uses the Laravel 7 API framework.
Requirements
- PHP 7.2.5 or higher
- PHP Composer
- Laravel 7
- GiT
- SARK V6.0.1-50 or higher
Before you begin
If you haven't used Postman before then now would be a good idea to familiarise yourself with it before you begin. Postman is a general purpose API testing tool which is easy to use (at least for what we want to do). It runs as an app on OSX or Windows and there is also a version for Ubuntu desktop. It makes testing and exploring API's a breeze. In my view it's essential for this kind of work.
WARNING
The initial release of sark6api works as a "trusted" peer. It has no security of its own so you must use fixed IP's and secure firewall rules to keep it safe from baddies. So, for now, that means NO dynamic IP clients (unless via VPN). We are working on an OAuth security blanket and it will be ready as soon as we can get it out the door but you can test with sark6api as-is, as long as you observe point-to-point security using the host SARK or edge firewall rules.
The sark6api usually runs at port 44300 (HTTPS).
Installation
We'll do the install as root
sudo -i
Update your existing deb packages
apt update apt upgrade
NB - this will bring your SARK V6 up to the latest release.
The API needs php-zip and composer, so lets install them
apt install php-zip composer
So far so good. Now we are going to install the sark6api code from Github. There are two versions depending upon which release of PHP you are running.
PHP V7
cd /opt git clone https://github.com/aelintra/sark6api.git cd /opt/sark6api
PHP V8/Laravel 10
cd /opt git clone https://github.com/aelintra/sark6api_L10.git cd /opt/sark6api_L10
Next we invoke composer to add the required Laravel dependencies (which aren't on the Git image) into our install directory.
composer install composer update
Laravel needs a .env file. GiT will have downloaded a file called .env.example. You can either copy or move it to .env, whichever you prefer.
cp .env.example .env
Finally for Laravel, we need to generate an encryption key. We do that with a Laravel artisan utility
php artisan key:generate
We need to set ownership on a couple of trees so that Apache can write to them. Everything else can stay as root.
chown -R www-data:www-data /opt/sark6api/public chown -R www-data:www-data /opt/sark6api/storage
We need to have Apache listen on the port we are going to use for the API. To do that we need to modify /etc/apache2/ports.conf. Ther GiT source uses 44300(HTTPS) so the ports.conf will look something like this
Listen [::]:80 <IfModule ssl_module> Listen [::]:443 Listen [::]:44300 </IfModule>
We need to define the Virtual Host to Apache. The sark6api source for apache is contained in the sark6api download so you can link it into apache like this
cd /etc/apache2/sites-available ln -s /opt/sark6api/apache2/sites-available/sarkapi.conf
Enable it and restart apache
a2ensite sarkapi apache2ctl restart
We will also need to link to the SARK database from the API tree
cd /opt/sark6api/database/ ln -s /opt/sark/db/sark.db database.sqlite
...and link our sudo requirements
cd /etc/sudoers.d ln -s /opt/sark6api/sudoers.d/sark6api
For AMI we need stronger access rules than SARK does so edit the file /etc/asterisk/sark_manager.conf. Find the definition for the SARK user and set the authorizationss to "all"
[sark] deny=0.0.0.0/0.0.0.0 permit=127.0.0.1/255.255.255.255 Authorization read=all write=all
Finally, you will need to set the regular SARK firewall to allow the API port you have chosen. You may have to set your edge firewall also.
The API is now ready to use.
sark6api HTTP Requests
sark6api uses the methods GET,POST,PUT,DELETE
- GET is used for retrieval but there are some exceptions, in particular where it is used to issue commands of some description
- POST is used to create NEW instances
- PUT is used for idempotent operations, usually updates to instance variables but also to enliven a backup or a snapshot.
- DELETE is used to remove/destroy an instance
N.B.
ALL responses will be returned as JSON arrays and strings
ALL regular POST/PUT bodies must ONLY contain raw JSON
File upload (backups, greetings and snapshots) will use a regular POST Form and body.
Request notation
An HTTP Request will take the form:-
- METHOD /{resource}/{endpoint?}/{parameter?}
Where a variable ends with a question mark (?) it means the variable is optional. e.g.
- GET /agents/{agent?}
Thus you can request either:-
- GET /agents
or:-
- GET /agents/1021
The first example above will return ALL agent endpoints, the second will return agent endpoint 1021
In the document a POST/PUT BODY will be described using regular Laravel validation array elements. e.g.
Body 'pkey' => 'required|integer|min:1000|max:9999'; 'cluster' => 'required|exists:cluster'; 'name' => 'required|alpha_dash'; 'passwd' => 'required|integer|min:1000|max:9999';
Most Laravel validators are self explanatory but you can find full information in the Laravel Documentation here:- https://laravel.com/docs/7.x/validation#available-validation-rules.
- In the POST BODY, only the REQUIRED variables are listed. i.e the minimum you need to supply to get the instance created.
- In the PUT BODY, all of the update-able variables are listed.
You can freely supply non-required variables during a POST if you wish but you MUST provide ALL of the REQUIRED variables or the Method will fail.
HTTP Status Codes
sark6api will return a standard HTTP status code with each response. For more information see here:- https://www.restapitutorial.com/httpstatuscodes.html
Additionally, when required, sark6api will return error messages in JSON format
Agents
GET /agents/{agent?}
POST /agents
- Body
- 'pkey' => 'required|integer|min:1000|max:9999';
- 'cluster' => 'required|exists:cluster';
- 'name' => 'required|alpha_dash';
- 'passwd' => 'required|integer|min:1000|max:9999';
PUT /agents/{agent}
- Body
- 'cluster' => 'exists:cluster,pkey',
- 'name' => 'alpha_dash',
- 'passwd' => 'integer',
- 'queue1' => 'exists:queue|nullable',
- 'queue2' => 'exists:queue|nullable',
- 'queue3' => 'exists:queue|nullable',
- 'queue4' => 'exists:queue|nullable',
- 'queue5' => 'exists:queue|nullable',
- 'queue6' => 'exists:queue|nullable'
DELETE /agents/{agent}
Backups
GET /backups
- return a list of available backups on the server
GET /backups/{backup}
- Download an existing backup from the server
GET /backups/new
- Request a new backup be taken and saved in the backup set
POST /backups
- Upload a local zipped backup to the backup set on the server
- Body
- 'uploadzip' => 'required|file|mimetypes:application/zip'
PUT /backups/{backup}
- Restore an existing backup from the backup set to the live system. Choose which elements of the backup set you want to restore by setting the corresponding element to true (N.B. this is JSON true - i.e. no quotes)
- Body
- 'restoredb' => 'boolean',
- 'restoreasterisk' => 'boolean',
- 'restoreusergreeting' => 'boolean',
- 'restorevmail' => 'boolean',
- 'restoreldap' => 'boolean'
DELETE /backups/{backup}
Class of Service
There are three elements to CoS.
- A rule (cosrule) which defines a particular dialplan set to be tested
- A closed instance of an egress rule (cosclose) which applies to a particular endpoint(extension)
- An open instance of an egress rule (cosopen) which applies to a particular endpoint(extension)
Class of service instances are accessed using the extension number as the key (NOT the Class of Service key)
coscloses
GET /coscloses
- returns a list of the cosrule/extension intersections from the database
GET /coscloses/{cosclose}
POST /coscloses/{cosclose}
- create a new cosclose instance
- Body
- 'IPphone_pkey' => 'exists:ipphone,pkey',
- 'COS_pkey' => 'exists:cos,pkey'
DELETE/coscloses/{cosclose}
cosopens
GET /cosopens
- returns a list of the cosrule/extension intersections from the database
GET /cosopens/{cosopen}
POST /cosopenes/{cosopen}
- create a new cosopen instance
- Body
- 'IPphone_pkey' => 'exists:ipphone,pkey',
- 'COS_pkey' => 'exists:cos,pkey'
DELETE/cosopens/{cosopen}
cosrules
GET /cosrules
- returns a list of the cosrules from the database
GET /cosrules/{cosrule}
POST /cosrules/{cosrule}
- create a new cosrule instance
- Body
- 'pkey' => 'required|alpha_dashy',
- 'dialplan' => 'required'
DELETE/cosrules/{cosrule}
Custom Apps
GET /customapps/{customapp?}
- Return a list or instance of a custom app
POST /customapps
- Create a new custom app
- Body
- 'pkey' => 'required'
- 'cluster' => 'required'
- 'desc' => 'string|nullable',
- 'extcode' => 'string|nullable',
- 'span' => 'in:Internal,External,Both,Neither',
- 'striptags' => 'in:YES,NO'
PUT /customapps/{customapp}
- update a custom app
- Body
- 'cluster' => 'exists:cluster,pkey',
- 'desc' => 'string|nullable',
- 'extcode' => 'string|nullable',
- 'span' => 'in:Internal,External,Both,Neither',
- 'striptags' => 'in:YES,NO'
DELETE /customapps/{customapp}
Recurring Timers (Daytimers)
GET /daytimer/{daytimer?}
POST /daytimers
- Create a new daytimer
- Body
- 'cluster' => 'required|exists:cluster,pkey',
- 'datemonth' => 'in:*,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31',
- 'dayofweek' => 'in:*,mon,tue,wed,thu,fri,sat,sun',
- 'desc' => 'string',
- 'month' => 'in:*,jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec',
- 'timespan' => [
- 'regex:/^\*|(2[0-3]|[01][0-9]):([0-5][0-9])\-(2[0-3]|[01][0-9]):([0-5][0-9])$/'
- ]
PUT /daytimers/{daytimer}
- update a timer
- Body
- 'cluster' => 'required|exists:cluster,pkey',
- 'datemonth' => 'in:*,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31',
- 'dayofweek' => 'in:*,mon,tue,wed,thu,fri,sat,sun',
- 'desc' => 'string',
- 'month' => 'in:*,jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec',
- 'timespan' => [
- 'regex:/^\*|(2[0-3]|[01][0-9]):([0-5][0-9])\-(2[0-3]|[01][0-9]):([0-5][0-9])$/'
- ]
DELETE /daytimers/{daytimer}
Destinations
Destinations provides a list of all currently valid destinations within the database. It has only one method.
GET /destinations
Extensions
Extensions have some extra functions to deal with multiple extension types and runtime information
GET /extensions/{extension?}
Return a list or instance of an extension
GET /extensions/{extension}/runtime
Returns runtime information about the extension from the PBX (i.e. CFIM, CFBS, ringdelay)
POST /extensions/mailbox
Create a new mailbox instance
- Body
- 'pkey' => 'required',
- 'cluster' => 'required|exists:cluster,pkey'
POST /extensions/provisioned
Create a new SARK provisioned instance
- Body
- 'pkey' => 'required',
- 'cluster' => 'required|exists:cluster,pkey'
- 'macaddr' => 'required|regex:/^[0-9a-fA-F]{12}$/'
POST /extensions/unprovisioned
Create a new uprovisioned instance
- Body
- 'pkey' => 'required',
- 'cluster' => 'required|exists:cluster,pkey'
POST /extensions/webrtc
Create a new webrtc instance
- Body
- 'pkey' => 'required',
- 'cluster' => 'required|exists:cluster,pkey'
PUT /extensions/{extension}
Update an instance
- Body
- 'active' => 'in:YES,NO',
- 'callbackto' => 'in:desk,cell',
- 'callerid' => 'integer|nullable',
- 'cellphone' => 'integer|nullable',
- 'celltwin' => 'in:ON,OFF',
- 'cluster' => 'exists:cluster,pkey',
- 'devicerec' => 'in:None,OTR,OTRR,Inbound.Outbound,Both',
- 'dvrvmail' => 'exists:ipphone,pkey|nullable',
- 'location' => 'in:local,remote',
- 'protocol' => 'in:IPV4,IPV6',
- 'provision' => 'string|nullable',
- 'provisionwith' => 'in:IP,FQDN',
- 'sndcreds' => 'in:No,Once,Always',
- 'transport' => 'in:udp,tcp,tls,wss',
- 'vmailfwd' => 'email|nullable'
PUT /extensions/{extension}/runtime
Update runtime information for an instance
- Body
- 'cfim' =>
- ['regex:/^\+?\d+$/'],
- ['nullable'],
- 'cfbs' =>
- ['regex:/^\+?\d+$/'],
- ['nullable'],
- 'ringdelay' => 'integer|nullable'
DELETE /extensions/{extension}
Firewalls
SARK uses the Shorewall firewall to protect its resources. The API operates on the entire ruleset as a simple array. GET will return the rules, POST will update the rules and validate them (using shorewall itself) and PUT will restart the firewall.
GET /firewalls/ipv4
- return the IPV4 firewall rules
POST /firewalls/ipv4
- Upload a rules array to the server and validate it.
- Body
- 'rules' => 'required'
PUT /firewalls/ipv4
- Restart the IPV4 firewall
GET /firewalls/ipv6
- return the IPV6 firewall rules
POST /firewalls/ipv6
- Upload a rules array to the server and validate it.
- Body
- 'rules' => 'required'
PUT /firewalls/ipv6
- Restart the IPV6 firewall
Greetings
GET /greetings
- Returns a list of greetings
GET /greetings/{greeting}
- Download a greeting
POST /greetings
- Upload a new greeting
- Body
- 'greeting' => 'required|file|mimes:wav,mpeg'
DELETE /greetings/{greeting}
- Delete a greeting
Non Recurring Timers (Holidaytimers)
GET /holidaytimers{holidaytimer?}
Return a list or instance of HolidayTimer. Times are stored as epoch seconds.
POST /holidaytimers
- Create a new Holidaytimer
- Body
- 'cluster' => 'exists:cluster,pkey',
- 'route' => 'string',
- 'desc' => 'string',
- 'stime' => 'digits:10|nullable',
- 'etime' => 'digits:10|nullable'
PUT /holidaytimers/{holidaytimer}
- update a timer
- Body
- 'cluster' => 'exists:cluster,pkey',
- 'route' => 'string',
- 'desc' => 'string',
- 'stime' => 'digits:10|nullable',
- 'etime' => 'digits:10|nullable'
DELETE /holidaytimers/{holidaytimer}
Inbound Routes
Inbound routes (DDI's or DiD's) control the initial ingress into the PBX core
GET /inboundroutes/{inboundroute?}
Return a list or instance of InboundRoute
POST /inboundroutes
- Create a new inboundroute
- Body
- 'pkey' => 'required'
- 'carrier' => 'required|in:DiD,CLID'
- 'cluster' => 'required|exists:cluster'
- 'trunkname' => 'required'
PUT /inboundroutes/{inboundroute}
- update an inboundroute
- Body
- 'active' => 'in:YES,NO',
- 'alertinfo' => 'string',
- 'carrier' => 'in:DiD,CLID',
- 'closeroute' => 'string',
- 'cluster' => 'exists:cluster,pkey',
- 'description' => 'alpha_num',
- 'disa' => 'in:DISA,CALLBACK|nullable',
- 'disapass' => 'alpha_num|nullable',
- 'inprefix' => 'integer|nullable',
- 'moh' => 'in:ON,OFF',
- 'openroute' => 'string',
- 'swoclip' => 'in:YES,NO',
- 'tag' => 'alpha_num|nullable',
DELETE /inboundroutes/{inboundroute}
IVRs
IVRs optionally control ACD into the PBX core
GET /ivrs/{ivr?}
Return a list or instance of Ivr
POST /ivrs
- Create a new ivr
- Body
- 'pkey' => 'required'
- 'cluster' => 'required|exists:cluster'
PUT /ivrs/{ivr}
- update an ivr
- Body
- 'alert0' => 'string|nullable',
- 'alert1' => 'string|nullable',
- 'alert2' => 'string|nullable',
- 'alert3' => 'string|nullable',
- 'alert4' => 'string|nullable',
- 'alert5' => 'string|nullable',
- 'alert6' => 'string|nullable',
- 'alert7' => 'string|nullable',
- 'alert8' => 'string|nullable',
- 'alert9' => 'string|nullable',
- 'alert10' => 'string|nullable',
- 'alert11' => 'string|nullable',
- 'description' => 'string|nullable',
- 'cluster' => 'exists:cluster,pkey',
- 'greetnum' => 'integer',
- 'listenforext' => 'in:YES,NO',
- 'option0' => 'string|nullable',
- 'option1' => 'string|nullable',
- 'option2' => 'string|nullable',
- 'option3' => 'string|nullable',
- 'option4' => 'string|nullable',
- 'option5' => 'string|nullable',
- 'option6' => 'string|nullable',
- 'option7' => 'string|nullable',
- 'option8' => 'string|nullable',
- 'option9' => 'string|nullable',
- 'option10' => 'string|nullable',
- 'option11' => 'string|nullable',
- 'tag0' => 'string|nullable',
- 'tag1' => 'string|nullable',
- 'tag2' => 'string|nullable',
- 'tag3' => 'string|nullable',
- 'tag4' => 'string|nullable',
- 'tag5' => 'string|nullable',
- 'tag6' => 'string|nullable',
- 'tag7' => 'string|nullable',
- 'tag8' => 'string|nullable',
- 'tag9' => 'string|nullable',
- 'tag10' => 'string|nullable',
- 'tag11' => 'string|nullable',
- 'timeout' => 'operator',
DELETE /ivrs/{ivr}
Logs/CDRs
Here is a placeholder for general logs. In the initial out it only has a method to retrieve CDR.
GET /logs/cdrs/{limit?}
Download the CDR log. If {limit} is specified, download the last {limit} rows
Queues
Queues optionally control ACD into the PBX core
GET /queues{queue?}
Return a list or instance of Queue
POST /queues
- Create a new queue
- Body
- 'pkey' => 'required'
- 'cluster' => 'required|exists:cluster'
PUT /queues/{queue}
- update a queue
- Body
- 'conf' => 'string',
- 'cluster' => 'exists:cluster,pkey',
- 'devicerec' => 'in:None,OTR,OTRR,Inbound',
- 'greetnum' => 'regex:/^usergreeting\d{4}$',
- 'options' => 'alpha',
DELETE /queues/{queue}
Snapshots
A snapshot is an instance of the SARK db.
GET /snapshots
- return a list of available snapshots on the server
GET /snapshots/{snapshot}
- Download an existing snapshot from the server
GET /snapshots/new
- Request a new snapshot be taken and saved in the snapshot set
POST /snapshots
- Upload a local snapshot to the snapshot set on the server
- Body
- 'uploadsnap' => 'required|file|mimetypes:application/zip'
PUT /snapshots/{backup}
- Restore an existing snapshot from the snapshot set to the live system.
DELETE /snapshots/{snapshot}
Ring Groups
GET /ringgroups/{ringgroup?}
- return a list or instance of ringgroup
POST /ringgroups/(ringroup}
- Create a new ringgroup
- Body
- 'pkey' => 'required'
- 'cluster' = 'required|exists:cluster,'
- 'outcome' = 'required;
PUT /ringgroups/{ringgroup}
- Update an existing ringgroup
- Body
- 'cluster' => 'exists:cluster,pkey',
- 'devicerec' => 'in:default,None,OTR,OTRR,Inbound.Outbound,Both',
- 'dialparamshunt' => 'alpha|nullable',
- 'dialparamsring' => 'alpha|nullable',
- 'divert' => 'integer|nullable',
- 'greeting' => [
- 'regex:/^usergreeting\d{4}$/',
- 'nullable'
- ],
- 'grouptype' => 'in:Ring,Hunt,Alias,Page',
- 'longdesc' => 'string|nullable',
- 'obeydnd' => 'in:YES,NO|nullable',
- 'out' => [
- 'regex:/^[@A-Za-z0-9-_\/\s]{2,1024}$/',
- 'nullable'
- ],
- 'outcome' => 'string',
- 'pagegroup' => 'integer',
- 'ringdelay' => 'integer',
- 'speedalert' => 'string'
DELETE /ringgroups/{ringgroup}
Routes
GET /routes/{route?}
- return a list or instance of ringgroup
POST /route
- Create a new route
- Body
- 'pkey' => 'required'
- 'cluster' = 'required|exists:cluster,'
- 'outcome' = 'required;
PUT /routes/{route}
- Update an existing route
- Body
- 'active' => 'in:YES,NO',
- 'auth' => 'in:YES,NO',
- 'cluster' => 'exists:cluster,pkey',
- 'desc' => 'alpha_dash',
- 'dialplan' => 'string',
- 'path1' => 'exists:lineio,pkey|nullable',
- 'path2' => 'exists:lineio,pkey|nullable',
- 'path3' => 'exists:lineio,pkey|nullable',
- 'path4' => 'exists:lineio,pkey|nullable',
- 'strategy' => 'in:hunt,balance'
DELETE /routes/{route}
System Commands
- System commands use the GET method
GET /syscommands/{command}
- Available Commands
- commit
- reboot
- pbxrunstate
- pbxstart
- pbxstop
System Globals
Globals are system wide variables which control PBX default behaviours. They cannot be created or deleted.
GET /sysglobals
- return a list of global settings
PUT /sysglobals
- update Global settings
- Body
- 'ABSTIMEOUT' => 'integer',
- 'ACL' => 'in:NO,YES',
- 'AGENTSTART' => 'integer',
- 'ALERT' => 'email',
- 'ALLOWHASHXFER' => 'in:enabled,disabled',
- 'BLINDBUSY' => 'integer|nullable',
- 'BOUNCEALERT' => 'integer|nullable',
- 'CALLPARKING' => 'in:NO,YES',
- 'CALLRECORD1' => 'in:None,OTR,OTRR,Inbound.Outbound,Both',
- 'CAMPONQONOFF' => 'in:OFF,ON',
- 'CAMPONQOPT' => 'string|nullable',
- 'CFWDEXTRNRULE' => 'in:enabled,disabled',
- 'CFWDPROGRESS' => 'in:enabled,disabled',
- 'CFWDANSWER' => 'in:enabled,disabled',
- 'CLUSTER' => 'in:ON,OFF',
- 'CONFTYPE' => 'in:simple,hosted',
- 'COSSTART' => 'in:ON,OFF',
- 'COUNTRYCODE' => 'alpha|size:2',
- 'EURL' => 'regex:/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/',
- 'EMERGENCY' => 'digits:3',
- 'FQDN' => 'regex:/^(?!:\/\/)(?=.{1,255}$)((.{1,63}\.){1,127}(?![0-9]*$)[a-z0-9-]+\.?)$/i',
- 'FQDNINSPECT' => 'in:NO,YES',
- 'FQDNPROV' => 'in:NO,YES',
- 'INTRINGDELAY' => 'integer',
- 'IVRKEYWAIT' => 'integer|nullable',
- 'IVRDIGITWAIT' => 'integer|nullable',
- 'LACL' => 'in:NO,YES',
- 'LDAPBASE' => 'string|nullable',
- 'LDAPOU' => 'string|nullable',
- 'LDAPUSER' => 'string|nullable',
- 'LDAPPASS' => 'string|nullable',
- 'LEASEHDTIME' => 'integer',
- 'LOCALIP' => 'ip',
- 'LOGLEVEL' => 'integer',
- 'LOGSIPDISPSIZE' => 'integer',
- 'LOGSIPNUMFILES' => 'integer',
- 'LOGSIPFILESIZE' => 'integer',
- 'LTERM' => 'in:NO,YES',
- 'MAXIN' => 'integer',
- 'MIXMONITOR' => 'in:NO,YES',
- 'MONITOROUT' => 'string',
- 'MONITORSTAGE' => 'string',
- 'MONITORTYPE' => 'in:monitor,mixmonitor',
- 'NATDEFAULT' => 'in:local,remote',
- 'OPERATOR' => 'integer',
- 'PWDLEN' => 'integer',
- 'PLAYBEEP' => 'in:YES.NO',
- 'PLAYBUSY' => 'in:YES,NO',
- 'PLAYCONGESTED' => 'in:YES,NO',
- 'PLAYTRANSFER' => 'in:YES,NO',
- 'RECFINALDEST' => 'string',
- 'RECLIMIT' => 'integer',
- 'RECQDITHER' => 'integer',
- 'RECQSEARCHLIM' => 'integer',
- 'RINGDELAY' => 'integer',
- 'SESSIONTIMOUT' => 'integer',
- 'SENDEDOMAIN' => 'in:YES,NO',
- 'SIPIAXSTART' => 'integer',
- 'SIPFLOOD' => 'in:NO,YES',
- 'SPYPASS' => 'integer',
- 'SUPEMAIL' => 'email|nullable',
- 'SYSOP' => 'integer',
- 'SYSPASS' => 'integer',
- 'TLSPORT' => 'integer',
- 'USEROTP' => 'string',
- 'USERCREATE' => 'in:NO,YES',
- 'VDELAY' => 'integer',
- 'VMAILAGE' => 'integer',
- 'VOICEINSTR' => 'in:YES,NO',
- 'VOIPMAX' => 'integer',
- 'VXT' => 'in:0,1',
- 'ZTP' => 'in:disabled,enabled'
Templates
Templates are used to create provisioning streams
GET /templates/{template?}
Return a list or instance of Template
POST /templates
- Create a new template
- Body
- 'pkey' => 'required'
- technology' => 'required|in:SIP,Descriptor,BLF Template';
PUT /templatess/{template}
- update a template
- Body
- 'blfkeyname' => 'exists:device,pkey|nullable',
- 'desc' => 'string',
- 'provision' => 'string|nullable',
- 'technology' => 'in:SIP,Descriptor,BLF Template',
DELETE //templatess/{template}
- Delete a template. Only user created templates can be deleted. System templates can not.
Tenants
Tenants are used to define classes of PBX resources. Usually, but not always, they are customers. For historical reasons, Tenants are internally referred to as clusters.
GET /tenants/{tenants?}
Return a list or instance of Tenant
POST /tenants
- Create a new tenant
- Body
- 'pkey' => 'required'
- 'description' => 'string|required'
PUT /tenants/{tenant}
- update a tenant
- Body
- 'abstimeout' => 'integer',
- 'clusterclid' => 'integer|nullable',
- 'callgroup' => 'integer|nullable',
- 'chanmax' => 'integer',
- 'description' => 'string',
- 'include' => 'string|nullable',
- 'localarea' => 'integer,nullable',
- 'localdplan' => [
- 'regex:/^\s*(_?(XZN[0-9])\.?)\s*$',
- 'nullable'
- ],
- 'masteroclo' => 'in:AUTO,CLOSED',
- 'operator' => 'integer',
- 'pickupgroup' => 'integer|nullable'
DELETE /tenants/{tenant}
- A tenant can only be deleted if it has no dependencies
Trunks
Trunks are used to define peers. Mostly you can think of them as axes of egress from the PBX (Ingress is usually defined by DDI/DiD abstractions)
GET /trunks/{trunk?}
Return a list or instance of Trunks
POST /trunks
- Create a new trunk
- Body
- 'pkey' => 'required'
- 'carrier' => 'required|in:GeneralSIP,GeneralIAX2'
- 'cluster' => 'required|exists:cluster,' . $request->cluster
- 'username' => 'required'
- 'host' => 'required'
PUT /trunks/{trunk}
- update a trunk
- Body
- 'active' => 'in:YES,NO',
- 'alertinfo' => 'string',
- 'callerid' => 'integer',
- 'callprogress' => 'in:ON,OFF',
- 'cluster' => 'exists:cluster,pkey',
- 'description' => 'alpha_num',
- 'devicerec' => 'in:None,OTR,OTRR,Inbound.Outbound,Both',
- 'disa' => 'in:DISA,CALLBACK|nullable',
- 'disapass' => 'alpha_num|nullable',
- 'host' => 'string',
- 'inprefix' => 'integer|nullable',
- 'match' => 'integer|nullable',
- 'moh' => 'in:ON,OFF',
- 'password' => 'alpha_num|nullable',
- 'peername' => 'string',
- 'register' => 'string|nullable',
- 'sipiaxpeer' => 'string',
- 'sipiaxuser' => 'string',
- 'swoclip' => 'in:YES,NO',
- 'tag' => 'alpha_num|nullable',
- 'transform' => [
- 'regex:/$(\d+?:\d+?\s*)+',
- 'nullable'
- ],
- 'trunkname' => 'alpha_num',
DELETE /trunks/{trunk}
Asterisk AMI functions exposed by the API
- sark6api gives you access to a range of functions from the Asterisk Manager Interface(AMI). This allows you to examine, and in some cases change, state information from the running PBX.
- N.B. sark6api implements blocking AMI requests. if you want to access non-blocking AMI streams then you can look at something like PAMI.
- Most of the AMI functions use GET. They return either an instance list or a single instance.
- The AMI 'Originate' bridging function uses POST
- Asterisk internal database 'DBPut' uses PUT
- Asterisk internal database 'DBDel' uses DELETE
- AMI function names are case sensitive for consistency with the Asterisk AMI documentation (of which, there is very little).
- We have not documented the returned variables so you will need to run the requests using something like Postman and decide what you want by examination.
GET
List AMI Functions
Each of these functions will return a JSON array
GET /astamis/
- Agents
- ConfbridgeList/{room-number}
- ConfbridgeListRooms
- CoreShowChannels
- DeviceStateList
- ExtensionStateList
- IAXpeers
- IAXregistry
- QueueStatus
- QueueSummary
- SIPpeers
- SIPshowregistry
- Status
- VoicemailUsersList
Instance AMI Functions
GET /astamis/
- CoreSettings
- CoreStatus
- DBget/{id}/{key}
- ExtensionState/{id}{context?}
- MailboxCount/{id}
- MailboxStatus/{id}
- QueueStatus/{id}
- QueueSummary/{id}
- Reload
- SIPshowpeer/{id}
POST /astamis/originate
- originate a new bridge
- Body
- target = 'required|integer';
- caller = 'required|numeric';
- context = 'required|alpha_dash';
- clid = 'required|numeric';
PUT /astamis/DBPut/{id}/{key}(value)
DELETE /astamis/DBdel/{id}/{key}
DELETE /astamis/Hangup/{id}/{key}
Hangup perfoms a "soft" hangup on a running channel. The actual channel can be either side of the call bridge, it doesn't matter which you choose in a regular two-party call. As an example, let's say we wish to hangup a channel called PJSIP/44107-00000155. Here's what you would send:-
https://sip.mypbx.com:44300/api/astamis/Hangup/PJSIP/44107-00000155