Choose the interface by who owns call state
AMI is an asynchronous management interface: clients send actions and receive responses and events about Asterisk state. AGI hands one dialplan channel to an external program and is generally synchronous, so the channel waits while an AGI command completes. ARI exposes channels, bridges, endpoints and media primitives through REST, publishes their state as JSON events over WebSocket and uses the Stasis dialplan application to hand a channel to an external application.
A wallboard, a dialplan lookup and a custom communications application therefore have different ownership models. Do not select an interface because all three can influence a call. Write down whether Asterisk's dialplan, one external request or the external application owns the next state transition, timeout and recovery path.
Treat AMI actions, responses and events as separate evidence
An accepted AMI action is not the same result as the later channel, bridge or far-end outcome. Correlate the action's own identifier with the relevant response and subsequent events, while retaining Asterisk channel identifiers and linked call identifiers for their documented scopes. The AMI documentation also warns that headers are local to a particular Action, Event or Response; a field name should not be given one cross-message meaning without its event or action contract.
Give each integration its own manager user and only the required read and write classes. Event filtering reduces the data delivered to that user; it does not grant or remove action authority. The current documentation recommends advanced name- and header-targeted filters over legacy full-payload regular expressions. Verify the exact case-sensitive event names and include/exclude order against the running system before relying on a filtered stream.
Bound AGI execution and dependency failure
AGI is entered from the dialplan and generally blocks the channel while commands complete. A successful external lookup does not prove that the following dialplan destination ran, and a channel hangup can invalidate later work. Bound DNS, database and HTTP waits; define the dialplan result for timeout, malformed data, process failure and caller hangup; and avoid sending secrets or untrusted call data through shell commands.
FastAGI moves the program across a network connection but does not remove the synchronous call-path dependency. Record the selected endpoint, connection timeout, request budget and local fallback. AsyncAGI and third-party libraries are separate choices whose exact behavior must be checked against the installed Asterisk branch and library release rather than inferred from the general AGI overview.
Design ARI as a three-part control path
ARI combines HTTP requests, an event WebSocket and the Stasis dialplan application. A REST response, receipt of the related event and the real channel or bridge outcome are distinct evidence states. By default ARI cannot manipulate an arbitrary channel outside its safe handoff; record which dialplan entries invoke Stasis and what happens when no controlling application is connected.
On reconnect, reconcile the application's retained state with the current Asterisk resources before issuing new commands. Define ownership for duplicate or late events, an application restart, a lost WebSocket, a request whose result arrives after timeout and channels still in Stasis when the controller disappears. Keep an ordinary dialplan fallback or bounded failure destination instead of leaving callers in an application-owned state indefinitely.
Register the Stasis owner before handing over a channel
An ARI REST request, an event WebSocket and the Stasis() dialplan handoff are separate parts of one control path. The Stasis application diagnosis proves the exact app name and WebSocket owner before changing dialplan or application logic. It also keeps the historical client-initiated event socket separate from version-gated outbound WebSockets and treats STASISSTATUS, StasisStart, the first control action and StasisEnd as different evidence.
Expose the smallest protected surface
AMI uses the TCP manager service when enabled, while ARI depends on Asterisk's HTTP server plus ARI users. Keep listeners on restricted management paths, use encrypted transports and certificate validation where configured, rotate separate application credentials and test both a permitted and a denied operation. The Asterisk ARI guide explicitly advises against connecting a production web page directly to ARI; place an application service between the browser and Asterisk for authorization, tenant boundaries, logging and version control.
Capture only the event and call interval needed for acceptance. Test one authorized call through answer, hold, transfer and hangup, then stop or disconnect the integration and prove the documented fallback. No listener, credential, application, channel, bridge, event sequence, call or media path is represented as tested here.
Do not make the ARI event socket carry application media
ARI can create or control a chan_websocket channel, but its event/control connection and the media connection remain independent. The media WebSocket guide maps the per-call socket, binary media, text control events and queue flow control without treating ARI registration as media evidence.
Choose call files only for a simple filesystem queue
Call files provide a flat-file originate path with filesystem scheduling and limited archived status. AMI and ARI provide different control, event and authorization surfaces. Choose the interface whose acknowledgement and result model matches the application instead of treating all originate methods as interchangeable.
Use AMI Originate for bounded dialplan-directed initiation
AMI Originate fits an external manager that starts a channel and hands it to a controlled dialplan or application while observing events. It does not turn AMI into an ARI-style media and bridge application surface, and its immediate response does not prove the final call outcome.
Use ARI origination when the application owns live channel state
ARI channel origination can start a channel directly or allocate it before dialing, then hand an answered app-directed channel to Stasis. That is a different control model from AMI Originate: require the exact Stasis application's event connection before treating ARI as the channel owner.
Use External Media only after ARI owns the channel state
ARI External Media creates another Stasis-controlled channel and normally requires explicit bridge membership. The ARI event connection remains the control path; RTP, AudioSocket or WebSocket carries application media and must not be confused with that event socket.
Use ARI when the application owns bridge membership
An ARI bridge makes the Stasis application responsible for bridge type, member IDs, event correlation and cleanup. That is a different control boundary from observing bridge events through AMI or running dialplan behavior through AGI.
Use the Playback resource when ARI owns prompt state
ARI exposes channel and bridge media as an asynchronous Playback resource with its own ID, events and control operations. Preserve that ownership boundary rather than treating an AMI event, AGI command or ARI response as interchangeable evidence.
Handle ARI DTMF as channel events and operations
ARI DTMF handling keeps incoming ChannelDtmfReceived events separate from outbound digit injection, source transport, bridge decoding and application input state.
Treat ARI variables as scoped state, not universal metadata
ARI channel-variable handling distinguishes one channel's values and functions from global variables, inherited child state, configured Channel JSON fields and reportable updates.
Treat ARI device states as application-owned resources
ARI device-state handling distinguishes a provider's state from an ARI-controlled resource, its explicit subscription and the later hint, NOTIFY, routing or display outcome.
Use AGI for a bounded dialplan-owned step
Local AGI and FastAGI are generally synchronous dialplan boundaries, EAGI adds incoming audio on file descriptor 3, and AsyncAGI queues commands through AMI. Choose one execution model explicitly, bound every external dependency and preserve hangup behavior; do not mistake a launched process or connected socket for the final call outcome.
Do not merge AMI and ARI talking event names
The TALK_DETECT guide maps AMI ChannelTalkingStart or Stop to ARI ChannelTalkingStarted or Finished while preserving each interface and channel identity.
Treat an intercepted hold event as a control request
The HOLD_INTERCEPT workflow maps AMI Hold and Unhold and ARI ChannelHold and ChannelUnhold to the initiating channel without claiming the peer was held.
Authorize registration-control actions narrowly
The PJSIP runtime-control guide ties one ActionID and object name to the AMI response, Registry event and fresh detail listing without defaulting to *all.
Keep dialplan and external originate contracts distinct
The dialplan Originate guide contrasts channel-owned ORIGINATE_STATUS with the different acknowledgement, identifier and event models of AMI and ARI.
Use AMI bridge actions with stable channel and bridge identities
The AMI bridge-control guide covers Bridge, BridgeList, BridgeInfo, BridgeKick and their event evidence.
Select the AMI transfer action by ownership contract
The AMI transfer-control guide distinguishes explicit channel relocation, bridge-relative blind transfer and transferer-relative attended transfer.
Model CancelAtxfer as a bounded manager action
The AMI cancel-and-recovery guide targets the transferer and preserves the underlying abort-feature dependency.
Correlate LocalOptimizeAway beyond its response
The AMI Local optimization guide follows Begin and End by operation ID and then rebuilds bridge topology.
Choose and correlate the correct AMI channel snapshot
The AMI channel snapshots guide compares CoreShowChannels, CoreShowChannelMap and Status.
Operate AMI event masks and filters per connection
The AMI event-delivery guide covers Login, Events, Filter and HTTP WaitEvent without merging them with ARI WebSockets.
Keep UserEvent producers and consumers distinct
The AMI UserEvent guide distinguishes the AMI action, dialplan application, AMI event and relevant Stasis delivery.
Keep AMI device-state writes and ARI-owned resources distinct
The AMI device-state guide separates a remote-node AMI update, a bounded AMI list and an ARI-controlled device-state resource.
Model presence reads and event scopes separately
The AMI presence-state guide distinguishes a direct query, a completed list, all-provider changes and hint-scoped changes.
Bound extension-state snapshots by completion
The AMI extension-state guide separates a direct manager query, the completed list transaction and unsolicited hint changes.
Bound AMI dialplan writes by exact key
The AMI runtime dialplan guide preserves Context, Extension, caller-ID match, Priority, Application, data and Replace intent.
Treat UpdateConfig as privileged file change
The AMI configuration-file guide preserves the source, destination and every indexed operation instead of reducing a response to success or failure.
Treat module lifecycle actions as privileged changes
The AMI module-control guide bounds ModuleCheck, ModuleLoad and Reload by target syntax, action scope and operational risk.
Treat AMI discovery as user-scoped evidence
The AMI command-inventory guide uses ListCommands, administrator CLI inventory, release support and authorization as separate checks.
Define the AMI session before control work
The AMI session-authentication guide records the exact Login field set, event mask and current-session Logoff boundary.
Use narrow AMI actions for core metadata
The AMI core-evidence guide preserves target, session, ActionID and raw response boundaries for two read-only core queries.
Choose the queue action that matches the question
QueueSummary and QueueStatus have different detail and filter boundaries; the queue-snapshot guide preserves both.
Treat mailbox reads as action-specific snapshots
The AMI mailbox-query guide separates count fields, waiting-state interpretation, detailed summaries and external MWI actions.
Treat voicemail-user actions as backend-owned evidence
The AMI voicemail-user guide records the different module ownership and contracts of the list and status actions.
Choose the MWI state owner before changing it
The AMI MWI control guide distinguishes voicemail-backend refresh, external-MWI state and remote mailbox synchronization.
Keep ConfBridge list transactions complete
The AMI ConfBridge snapshot guide correlates every room or participant list row with its ActionID and documented completion event.
Keep ConfBridge controls narrowly scoped
The AMI ConfBridge control guide separates manager acceptance, runtime state and caller outcome.
Treat ConfBridge events as asynchronous evidence
The AMI ConfBridge lifecycle guide preserves bridge and channel identities, filters, receipt gaps and later snapshots.
Treat AMI recording controls as privileged channel actions
The AMI MixMonitor guide bounds start, directional mute and scoped stop by exact channel identity and later artifact evidence.
Treat parking as a channel-scoped AMI workflow
The AMI parking guide correlates the exact live channel with documented snapshot and lifecycle boundaries.
Treat queue-member mutations as scoped AMI transactions
The AMI queue-member control guide keeps action response, AGENT-class event and later queue snapshot distinct.
Treat queue reload, rule inspection and reset as separate AMI transactions
The AMI queue reload and reset guide preserves exact request scope, raw framing and later postconditions.
Keep queue caller controls bound to a live channel
The AMI queue caller-control guide records action response, later snapshot and asynchronous lifecycle separately.
Scope one ring-in-use change to an exact queue member
The queue-member ring-in-use guide preserves the request, change event, later snapshot and state evidence without inventing event correlation.
Scope one QueueLog write to a named evidence contract
The AMI QueueLog guide preserves every request field without inventing validation or storage acknowledgement.
Treat external variable access as evaluated application input
The AMI Getvar and Setvar guide preserves function safeguards, manager authority and channel scope.
Treat AMI AstDB operations as stateful application inputs
The AMI AstDB guide constrains manager authority, namespace, concurrency and recovery.
Treat PJSIP registration lists as bounded AMI transactions
The AMI inbound-registration guide requires the correct row and completion event for each list action.
Treat PJSIP endpoint inventories as bounded AMI transactions
The AMI endpoint inventory guide preserves each action, row family, ActionID and completion event.
Sources & applicability
Primary references for the technical details above. Operational examples and planning checklists are VoIP.info editorial guidance.
- Asterisk AMI overview ↗
- Asterisk Manager TCP/IP API ↗
- Asterisk AMI event filtering ↗
- Asterisk ARI architecture and recommended practices ↗
- Asterisk ARI configuration ↗
- Asterisk AGI overview ↗
- Asterisk 23 Stasis application reference ↗
- Asterisk ARI outbound WebSockets ↗
- Asterisk current res_ari configuration reference ↗
- Asterisk WebSocket channel driver ↗
- Asterisk 22 chan_websocket module configuration ↗
- Asterisk WebSocket client configuration ↗
- Asterisk 22 Dial application WebSocket parameters ↗
- Official Asterisk ARI and media WebSocket examples ↗
- Official Asterisk release archive ↗
- Asterisk call-file documentation ↗
- Official Asterisk sample.call ↗
- Asterisk outgoing spool source ↗
- Asterisk module-loading troubleshooting ↗
- Asterisk main configuration reference ↗
- Asterisk call-file and Local-channel example ↗
- Asterisk 23 AMI Originate action ↗
- Asterisk 23 OriginateResponse event ↗
- Asterisk AMI v2 specification ↗
- Asterisk network security guidance ↗
- Asterisk 23 ARI Channels REST API ↗
- Asterisk introduction to ARI and channels ↗
- Asterisk ARI channel-state operations ↗
- Asterisk ARI bridge operations ↗
- Asterisk ARI basic mixing bridges ↗
- Asterisk External Media and ARI ↗
- Asterisk AudioSocket protocol ↗
- Asterisk ARI Bridges REST API ↗
- Asterisk bridges in a Stasis application ↗
- Asterisk ARI holding bridges ↗
- Asterisk ARI data models ↗
- Asterisk ARI recording API ↗
- Asterisk ARI simple media playback ↗
- Asterisk ARI playback operations ↗
- Asterisk ARI Playbacks REST API ↗
- Asterisk ARI Sounds REST API ↗
- Asterisk ARI DTMF handling ↗
- Asterisk 23 AGI application reference ↗
- Asterisk 23 EAGI application reference ↗
- Asterisk 23 AGI command index ↗
- Asterisk 23 AGI VERBOSE command ↗
- Asterisk AsyncAGI AMI action ↗
- Asterisk 23 AsyncAGIStart event ↗
- Asterisk 23 AsyncAGIExec event ↗
- Asterisk 23 ASYNCAGI BREAK command ↗
- Asterisk deprecated DeadAGI application reference ↗
- Asterisk 22 TALK_DETECT function ↗
- Asterisk 22 DENOISE function ↗
- Asterisk 22 AMI ChannelTalkingStart event ↗
- Asterisk 22 AMI ChannelTalkingStop event ↗
- Asterisk 22 ARI data models ↗
- Asterisk HOLD_INTERCEPT function ↗
- Asterisk AMI Hold event ↗
- Asterisk AMI Unhold event ↗
- Asterisk PJSIP_MOH_PASSTHROUGH function ↗
- Asterisk PJSIPRegister AMI action ↗
- Asterisk PJSIPUnregister AMI action ↗
- Asterisk PJSIPShowRegistrationsOutbound AMI action ↗
- Asterisk OutboundRegistrationDetail AMI event ↗
- Asterisk Registry AMI event ↗
- Asterisk res_pjsip_outbound_registration configuration reference ↗
- Asterisk outbound-registration configuration guide ↗
- Asterisk 23 Originate application ↗
- Asterisk 22 Originate application ↗
- Asterisk pre-dial handlers ↗
- Asterisk 23 Dial application ↗
- Asterisk 23 AMI Bridge action ↗
- Asterisk 22 AMI Bridge action ↗
- Asterisk 23 AMI BridgeList action ↗
- Asterisk 23 AMI BridgeInfo action ↗
- Asterisk 23 AMI BridgeKick action ↗
- Asterisk 22 AMI BridgeKick action ↗
- Asterisk 23 AMI BridgeCreate event ↗
- Asterisk 23 AMI BridgeEnter event ↗
- Asterisk 23 AMI BridgeLeave event ↗
- Asterisk 23 AMI BridgeInfoChannel event ↗
- Asterisk 23 AMI BridgeInfoComplete event ↗
- Asterisk 23 AMI Redirect action ↗
- Asterisk 22 AMI Redirect action ↗
- Asterisk 23 AMI BlindTransfer action ↗
- Asterisk 22 AMI BlindTransfer action ↗
- Asterisk 23 AMI Atxfer action ↗
- Asterisk 22 AMI Atxfer action ↗
- Asterisk 23 AMI BlindTransfer event ↗
- Asterisk 23 AMI AttendedTransfer event ↗
- Asterisk 23 AMI CancelAtxfer action ↗
- Asterisk 22 AMI CancelAtxfer action ↗
- Asterisk 23 attended-transfer feature configuration ↗
- Asterisk 22 attended-transfer feature configuration ↗
- Asterisk feature-code call transfers ↗
- Asterisk 23 AMI LocalOptimizeAway action ↗
- Asterisk 22 AMI LocalOptimizeAway action ↗
- Asterisk 23 AMI LocalOptimizationBegin event ↗
- Asterisk 23 AMI LocalOptimizationEnd event ↗
- Asterisk 23 AMI LocalBridge event ↗
- Asterisk Local channel optimization ↗
- Asterisk Local channel modifiers ↗
- Asterisk 23 AMI CoreShowChannelMap action ↗
- Asterisk 22 AMI CoreShowChannelMap action ↗
- Asterisk 23 AMI CoreShowChannelMapComplete event ↗
- Asterisk 22 AMI CoreShowChannelMapComplete event ↗
- Asterisk 23 AMI CoreShowChannels action ↗
- Asterisk 23 AMI CoreShowChannel event ↗
- Asterisk 23 AMI CoreShowChannelsComplete event ↗
- Asterisk 23 AMI Status action ↗
- Asterisk 23 AMI Status event ↗
- Asterisk 23 AMI StatusComplete event ↗
- Asterisk 23 AMI Newchannel event ↗
- Asterisk 23 AMI Rename event ↗
- Asterisk 23 AMI Events action ↗
- Asterisk 22 AMI Events action ↗
- Asterisk 23 AMI Filter action ↗
- Asterisk 22 AMI Filter action ↗
- Asterisk 23 AMI WaitEvent action ↗
- Asterisk 22 AMI WaitEvent action ↗
- Asterisk 23 AMI Login action ↗
- Asterisk 23 AMI Ping action ↗
- Asterisk 23 AMI UserEvent action ↗
- Asterisk 22 AMI UserEvent action ↗
- Asterisk 23 AMI UserEvent event ↗
- Asterisk 22 AMI UserEvent event ↗
- Asterisk 23 UserEvent dialplan application ↗
- Asterisk 22 UserEvent dialplan application ↗
- Asterisk AMI command syntax ↗
- Asterisk 23 AMI DeviceStateChange action ↗
- Asterisk 22 AMI DeviceStateChange action ↗
- Asterisk 23 AMI DeviceStateList action ↗
- Asterisk 22 AMI DeviceStateList action ↗
- Asterisk 23 AMI DeviceStateChange event ↗
- Asterisk 22 AMI DeviceStateChange event ↗
- Asterisk 23 AMI DeviceStateListComplete event ↗
- Asterisk 22 AMI DeviceStateListComplete event ↗
- Asterisk 23 DEVICE_STATE function ↗
- Asterisk 22 DEVICE_STATE function ↗
- Asterisk device state fundamentals ↗
- Asterisk extension state and hints ↗
- Asterisk 23 AMI PresenceState action ↗
- Asterisk 22 AMI PresenceState action ↗
- Asterisk 23 AMI PresenceStateList action ↗
- Asterisk 22 AMI PresenceStateList action ↗
- Asterisk 23 AMI PresenceStateChange event ↗
- Asterisk 22 AMI PresenceStateChange event ↗
- Asterisk 23 AMI PresenceStatus event ↗
- Asterisk 22 AMI PresenceStatus event ↗
- Asterisk 23 AMI PresenceStateListComplete event ↗
- Asterisk 22 AMI PresenceStateListComplete event ↗
- Asterisk 23 PRESENCE_STATE function ↗
- Asterisk 22 PRESENCE_STATE function ↗
- Asterisk presence-state fundamentals ↗
- Asterisk state query and manipulation ↗
- Asterisk 23 AMI ExtensionState action ↗
- Asterisk 22 AMI ExtensionState action ↗
- Asterisk 23 AMI ExtensionStateList action ↗
- Asterisk 22 AMI ExtensionStateList action ↗
- Asterisk 23 AMI ExtensionStatus event ↗
- Asterisk 22 AMI ExtensionStatus event ↗
- Asterisk 23 AMI ExtensionStateListComplete event ↗
- Asterisk 22 AMI ExtensionStateListComplete event ↗
- Asterisk 23 EXTENSION_STATE function ↗
- Asterisk 22 EXTENSION_STATE function ↗
- Asterisk 23 HINT function ↗
- Asterisk 22 HINT function ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- Asterisk 23 AMI Getvar action ↗
- Asterisk 23 AMI Setvar action ↗
- Asterisk 23 AMI VarSet event ↗
- Asterisk channel-variable setting and substitution ↗
- Asterisk channel-variable inheritance ↗
- Asterisk global-variable basics ↗
- Asterisk 23 SHARED dialplan function ↗
- Asterisk external-protocol dialplan-function safeguards ↗
- Asterisk 23 AMI DBGet action ↗
- Asterisk 23 AMI DBGetTree action ↗
- Asterisk 23 AMI DBPut action ↗
- Asterisk 23 AMI DBDel action ↗
- Asterisk 23 AMI DBDelTree action ↗
- Asterisk internal database overview ↗
- Asterisk SQLite3 AstDB back end ↗
- Asterisk 23 PJSIPShowRegistrationsInbound action ↗
- Asterisk 22 PJSIPShowRegistrationsInbound action ↗
- Asterisk 23 PJSIPShowRegistrationInboundContactStatuses action ↗
- Asterisk 22 PJSIPShowRegistrationInboundContactStatuses action ↗
- Asterisk 23 PJSIPShowContacts action ↗
- Asterisk 23 InboundRegistrationDetail event ↗
- Asterisk 23 ContactStatusDetail event ↗
- Asterisk PJSIP configuration sections and relationships ↗
- Asterisk 23 PJSIPShowEndpoints action ↗
- Asterisk 23 PJSIPShowEndpoint action ↗
- Asterisk 23 EndpointList event ↗
- Asterisk 23 EndpointListComplete event ↗
- Asterisk 23 EndpointDetail event ↗
- Asterisk 23 EndpointDetailComplete event ↗
- Asterisk 23 res_pjsip configuration reference ↗
Examples require adaptation to your topology. No live PBX or hardware testing is claimed.