VoIP.info Guide

Asterisk AMI device-state synchronization and listing

Use the version-gated DeviceStateChange action only for remote-device synchronization, and consume DeviceStateList as a bounded snapshot without flattening provider, hint or endpoint evidence.

Reviewed 2026-10-17Current Asterisk branch-23-generated and branch-22 AMI DeviceStateChange action, DeviceStateList action, DeviceStateChange event, DeviceStateListComplete event and DEVICE_STATE references, plus official device-state, hint and AMI-filtering documentation reviewed October 16, 2026; the write action requires Asterisk 24.1.0, 23.7.0, 22.13.0 or 20.23.0 or later within those branches and res_manager_devicestate; installed release, module, manager permissions, session mask, filters, provider ownership, entity identity, cache behavior, hint mapping and downstream consumer remain deployment specific; no PBX, node, module, manager session, state provider, hint, subscription, endpoint, packet, media stream or live call was inspected or testedAdvancedDocumentation based · not lab tested

Start with the installed action surface

The AMI DeviceStateList action has existed since Asterisk 13, but the AMI DeviceStateChange write action is documented only from 24.1.0, 23.7.0, 22.13.0 and 20.23.0. It is supplied by res_manager_devicestate. Confirm the installed branch, maintenance release, loaded module and action response before designing a writer; a client library method or current web page does not make the action available on an older PBX.

Keep read and write capability separate. A deployment may legitimately support the list transaction while not supporting the newer write action.

Use the write action only for remote state

Asterisk documents DeviceStateChange as a way to manually synchronize remote devices and explicitly says it should not set local-device state. Send the exact device name, one documented state value, the remote Asterisk EntityID, and an explicit cache decision. If the supplied EntityID equals the local system EntityID, Asterisk rejects the update.

The device need not use the Custom: prefix, but the documentation calls for caution with non-Custom devices. Do not overwrite a PJSIP, ConfBridge or other local provider simply because a remote dashboard disagrees.

Make persistence and ownership explicit

Cachable defaults to true and the action reference says that value is needed for the update to persist. Record the value sent, the remote entity that owns the observation, the receiving node, the source timestamp and a bounded expiry or reconciliation policy. Treat a non-cachable transition and a later list result as separate evidence rather than inventing durability.

Define collision behavior before two nodes can write the same logical device. Entity identity prevents the documented local-entity loop, but it is not by itself a complete conflict-resolution or freshness protocol.

Parse DeviceStateList as one transaction

Send a unique ActionID with DeviceStateList. The result is a sequence of DeviceStateChange events followed by DeviceStateListComplete; the completion carries EventList status and ListItems. Buffer rows for that transaction and publish the snapshot only after its matching completion boundary.

Do not count an unrelated live DeviceStateChange event as a snapshot row just because it arrived between the action and completion. Preserve raw message boundaries and verify how the installed release returns the transaction identifier before interleaving more than one list request on a session.

Keep device and extension observations separate

The DeviceStateChange event is raised for all device-state changes, while ExtensionStatus is limited to changes that affect dialplan hints. A hint can combine multiple devices and produces an extension state from that mapping. Therefore a device row and an extension lamp are not interchangeable records.

DEVICE_STATE() can read any provider and can write only a Custom: device from the dialplan. Use it for an explicit provider read or application-owned custom state, not to manufacture evidence about a phone registration, contact or call.

Do not promote a state label into outcome proof

UNKNOWN, NOT_INUSE, INUSE, BUSY, INVALID, UNAVAILABLE, RINGING, RINGINUSE and ONHOLD are Asterisk device-state values interpreted by the owning provider. A list row or accepted remote update does not by itself prove SIP registration, OPTIONS reachability, INVITE acceptance, queue eligibility, a BLF subscription, a rendered lamp, two-way audio or business availability.

Validate each downstream decision at its owner and keep the source state, hint aggregation, subscription delivery and final behavior independently observable. No PBX, node, module, manager session, state provider, hint, subscription, endpoint, packet, media stream or live call was inspected or tested for this guide.

Do not merge provider rows with extension aggregates

The AMI extension-state guide follows one or more device providers into a context-bound hint while retaining both evidence sets.

Match the queue member StateInterface to device-state inventory

The ring-in-use control guide keeps device status separate from permission to attempt an in-use member.

Sources & applicability

Primary references for the technical details above. Operational examples and planning checklists are VoIP.info editorial guidance.

Examples require adaptation to your topology. No live PBX or hardware testing is claimed.