For the complete documentation index, see llms.txt. This page is also available as Markdown.

API

Overview of MikoPBX APIs and integration surfaces — REST API v3, AMI/AJAM, AGI, and the legacy module REST callback — with guidance on when to use each.

MikoPBX exposes four distinct integration surfaces. They are not interchangeable: each one lives at a different layer of the stack, speaks a different protocol, and is invoked from a different place. Picking the wrong surface is the single most common mistake in module development — for example, polling the REST API in a loop to watch call state when you should be subscribing to AMI events.

This page is a decision guide. Read it first, then follow the link to the child page for the surface you need.

Throughout the developer docs we thread a single fictional module, ModuleBlackList (config class BlackListConf, main class BlackListMain, model BlackListNumbers, table m_BlackListNumbers, frontend module-black-list-index.js), so each pattern has a concrete home. For every pattern we also point to a real, working example module under Extensions/EXAMPLES/.

The four surfaces at a glance

Surface
Protocol / transport
Lives in
Use it for

HTTPS, JSON, attribute-routed

Core/src/PBXCoreREST/

Management & CRUD, external integrations, module endpoints

TCP 5038 (AMI) / HTTP (AJAM)

Core/src/Core/Asterisk/AsteriskManager.php

Real-time Asterisk events and live commands in workers

Dialplan-invoked PHP scripts

Core/src/Core/Asterisk/AGI.php, agi-bin/

Per-call, in-dialplan decision logic

Module REST callback (legacy v1/v2)

HTTPS, JSON, route-table

module *Conf.php

Older modules; simple custom endpoints

REST API v3 — management and CRUD

The modern, recommended surface for anything that reads or writes configuration, manages resources, or is consumed by an external system (a CRM, a provisioning script, a mobile app, another server).

  • Routing is auto-discovered from PHP 8.4 attributes (#[ApiResource], #[HttpMapping], #[ResourceSecurity]) by RouterProvider. You declare a resource class with attributes; no manual route table.

  • Authentication is JWT Bearer tokens (HMAC-SHA256, 15-min access + 30-day refresh) or 64-char API keys, with Resource:Action RBAC. Requests from 127.0.0.1/::1 bypass authentication.

  • URL shape is conventional REST:

    GET    /pbxcore/api/v3/{resource}           → getList
    GET    /pbxcore/api/v3/{resource}/{id}      → getRecord
    POST   /pbxcore/api/v3/{resource}           → create
    PUT    /pbxcore/api/v3/{resource}/{id}      → update
    PATCH  /pbxcore/api/v3/{resource}/{id}      → patch
    DELETE /pbxcore/api/v3/{resource}/{id}      → delete
    GET    /pbxcore/api/v3/{resource}:custom    → custom method
  • Processing is asynchronous: the php-fpm front end queues the request on Redis (api:requests) and WorkerApiCommands (3 parallel processes) executes the action and writes the result back. Every action returns a PBXApiResult:

    class PBXApiResult {
        public bool $success = false;
        public array $data;             // initialised to [] in the constructor
        public array $messages;         // ['error' => [...], 'warning' => [...]]
        public string $processor;       // set by the Processor that ran
        public string $function;        // the action name
        public ?int $httpCode = null;   // 200, 201, 400, 422, 409, 500
        public ?array $pagination = null;
        public string $reload = '';
    }

    getResult() also injects pid (the worker PID) into the wire body.

→ Full reference: REST API v3

AMI / AJAM — real-time Asterisk events and commands

The Asterisk Manager Interface (AMI) is a long-lived TCP socket to Asterisk. It is how you watch the PBX live — channel state, dial events, queue membership, hangups — and how you send immediate control commands (originate a call, hang up a channel, redirect, add/remove a queue member).

  • Transport. AMI listens on TCP — port 5038 by default, configured via PbxSettings::AMI_PORT (see Core/src/Core/Asterisk/Configs/ManagerConf.php, which generates manager.conf). The HTTP-flavoured variant AJAM is enabled by webenabled = yes in the same [general] block and is served by Asterisk's built-in HTTP server (Core/src/Core/Asterisk/Configs/HttpConf.php, bindport = PbxSettings::AJAM_PORT, URL prefix asterisk).

  • Client. Core wraps AMI in MikoPBX\Core\Asterisk\AsteriskManager. Key methods:

→ Full reference: AMI / AJAM

AGI — in-call decision logic

The Asterisk Gateway Interface runs a script from the dialplan, during a call. Asterisk hands the script the channel and call variables; the script makes a decision and tells Asterisk what to do next (continue, set a variable, play a file, hang up). This is the right place for per-call logic that must execute inside the call flow.

  • Core's AGI client is MikoPBX\Core\Asterisk\AGI (built on AGIBase). It exposes the standard AGI verbs as PHP methods:

  • Real Core AGI scripts live in Core/src/Core/Asterisk/agi-bin/ (check_redirect.php, meetme_dial.php, unpark_call.php, get_park_info.php) — these are the canonical examples of how a dialplan-invoked script is structured. A module ships its own scripts in its agi-bin/ directory and wires them into the dialplan from its config class.

→ Full reference: AGI

Legacy module REST callback (v1 / v2)

Before REST API v3, modules exposed HTTP endpoints under /pbxcore/api/... in one of two ways, both declared in the module's config class. These still work and you will encounter them in existing modules, but new modules should use REST API v3.

  • v1 — single callback. The config class implements one method that dispatches on the action name:

    See Extensions/EXAMPLES/REST-API/ModuleExampleRestAPIv1/Lib/ExampleRestAPIv1Conf.php.

  • v2 — explicit route table + controllers. The config class returns a route definition array mapping URLs to controller actions, supporting public (no-auth) routes:

    See Extensions/EXAMPLES/REST-API/ModuleExampleRestAPIv2/Lib/ExampleRestAPIv2Conf.php (routes like /pbxcore/api/module-example-rest-api-v2/{actionName}).

ARI — advanced call control (when AMI is not enough)

For programmatic media and call-control beyond what AMI/AGI offer (building channels, bridges, and stasis applications), Asterisk's REST Interface (ARI) is available. It is served over the same built-in HTTP server as AJAM — HttpConf enables the HTTP server when either AJAM or ARI is enabled — and modules can contribute to its configuration through the GENERATE_ARI_CONF hook on AsteriskConfigInterface. ARI is an advanced, specialised surface; most modules will not need it. Reach for it only when AMI events plus AGI decisions cannot express the call flow you need.

Decision summary

  • Read/write configuration, CRUD, external integrationREST API v3

  • React to live call events / send immediate commands from a workerAMI / AJAM

  • Make a decision inside an active call from the dialplanAGI

  • Advanced channel/bridge/media control → ARI

  • Maintaining an old module's HTTP endpoint → legacy v1/v2 callback (see REST API in modules)

Last updated

Was this helpful?