Version-gate the action and identify its exact input
PJSIPQualify is documented since Asterisk 12.0.0 and accepts an Endpoint, not an AoR name, contact URI or channel. Confirm the installed branch, loaded res_pjsip capability, manager action inventory and write authorization before designing automation around the current reference.
An endpoint can reference one or more AoRs, and an AoR can own more than one contact. Preserve the endpoint-to-AoR-to-contact relationships before the action so later per-contact results are not collapsed into one endpoint label.
Separate action acceptance from the OPTIONS transaction
The AMI response establishes whether Asterisk accepted or rejected the manager request. It does not prove that DNS resolved, an OPTIONS request left the intended socket, the remote contact replied, or a stored status changed. Use a unique ActionID for the request, but do not invent an action-to-event correlation when the emitted contact event does not carry that identifier.
Record node, manager identity, timestamp and exact endpoint. Then correlate the resulting work by bounded time, AoR, contact URI and a fresh completed contact snapshot.
Read ContactStatus as a change event, not a completion event
ContactStatus is raised when a contact state changes and identifies the URI, status, AoR, endpoint name and last qualify RTT. Its documented states include Unknown, Unreachable, Reachable, Unqualified, Removed and Updated.
The event is not documented as the terminal response to PJSIPQualify, and it has no list-completion boundary. No event can mean the status did not change, the event was filtered, observation started late or the manager session failed; it is not sufficient proof that no qualify occurred.
Take a completed snapshot before interpreting one contact
PJSIPShowContacts emits one ContactList event for each current contact and then ContactListComplete. Preserve the initial response, every row and the terminal event before comparing counts or status. The snapshot contains contact URI, AoR, endpoint, qualify policy, status and round-trip fields.
The inbound-registration status action is narrower: it emits ContactStatusDetail records for dynamic inbound-registration contacts and then its own completion event. Do not use that narrower inventory as proof that static contacts or every endpoint contact are absent.
Keep qualification policy and network outcome distinct
qualify_frequency controls periodic qualification and zero disables that schedule; qualify_timeout includes DNS lookup time. outbound_proxy, stored Path, the contact URI, transport and DNS can therefore change where an OPTIONS request goes or why it times out.
Current documentation version-gates qualify_2xx_only to 20.12.0, 21.7.0 and 22.2.0. A non-2xx SIP response, timeout and transport failure are different observations, and the installed policy determines whether a response class counts as reachable.
Verify reachability without promoting it to service proof
For an authorized test, retain the pre-action completed snapshot, exact endpoint relationships, action response, relevant contact event, post-action completed snapshot and one redacted SIP transaction. Compare URI, route, response, policy, status and RTT on the same node and contact.
Reachable means the qualification policy accepted a contact response; it does not prove REGISTER freshness, inbound routing, dialplan behavior, ringing, answer, media, device display or emergency-service operation. No PBX, contact, OPTIONS exchange, packet, media stream or call was inspected or tested.
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.