ASAP
APIEngine's ASAP integration is a REST bridge to the APCO Automated Secure Alarm Protocol (ASAP-to-PSAP) message broker. It pulls work from SBN-side queues (address verifications, new alarms, chats) and posts ASAP 3.3 XML to the central broker over mTLS, and accepts inbound ASAP messages (broker -> APIEngine) on a single receive endpoint for processing back into SBN. The endpoints, settings and log entries are the same in v95 and v96 and later; the version differences table lists the exceptions.
Setup
App_Data\apiengine.settings -> ASAP block:
Field | Purpose |
|---|---|
| Base URL of the ASAP message broker (no trailing slash needed). |
| Path to the client |
| Password for the |
| Your central station ID (required on outbound messages). |
| Source ID assigned by the broker. |
| Display name of the central station. |
| Contact phone on outbound messages. |
| Batch cap for |
Outbound calls request HTTP/1.1 over TLS 1.2/1.3 with a 60-second timeout. mTLS engages whenever Certificate is set.
Outbound traffic to the broker leaves from the APIEngine host. The SBN Service Manager host only calls APIEngine; it never contacts the broker, so firewall rules for the broker address belong on the APIEngine host.
Every value in the block is checked before anything is sent. From APIEngine 08.92.0024 / 08.95.0009 / current, a problem is written to the log as ASAP configuration error: ... naming the setting and what to do (MessageBrokerRestUrl blank or not an absolute http(s) URL; Certificate missing, a directory, unreadable by the application pool identity, or not opening with CertificatePassword; CentralStationID / CentralStationSourceID blank), the send is refused, and the same text is returned in the JSON so the Dispatch Service log shows it too. An empty Certificate is a warning: the production broker requires mutual TLS. Once the block is usable one line ASAP configuration OK: ... is logged. Older builds abandon the send with Send XML exception and no REQUEST to line, and leave the addresses in Verifying.
Testing the certificate
The APIEngine settings page has a Test Certificate button directly under the Certificate Password field. Its result appears in a green or red box under the button. It checks the file and the Certificate Password as currently entered, so saving first is not needed, and it runs the same certificate load a real send to the broker uses. The Test only runs from a browser on the APIEngine server itself.
The button checks, in order:
Step | Fails when |
|---|---|
Certificate path is set | The path is blank. |
Path is a file | The path is a folder. |
File exists | Nothing is found at the path exactly as entered (leading and trailing spaces count). |
Readable | The APIEngine account (the application pool identity) cannot read the file. |
Opens with the password | The password is wrong (The specified network password is not correct) or the file is not a valid certificate. |
Has a private key | The key is taken from the .pfx, or from the Personal store (current user, then local machine) when the certificate is installed there. It must open for the APIEngine account. |
In date | The certificate has expired. |
On success it shows the certificate name and expiry date.
Every check writes each step to the APIEngine log, tagged ASAP certificate check [settings Test <id>]: the account, the path as entered in quotes, each step's result, and the certificate name, thumbprint and dates, or the failing step with Windows' exact error. Real sends log the same trail as [send <id>] once when the certificate is (re)loaded, and the configuration check logs it as [config check <id>]. The password is never written to the log. A certificate without a usable private key is refused before sending, with an ASAP configuration error.
Available in APIEngine 08.92.0027.0001, 08.95.0013.0001, and the current release.
The ASAP Broker Test Harness 2.8.0 (ASAP Broker Test Harness) pairs with the Test: its Connectivity tab has Require a client certificate, as ASAP does. With that ticked, the harness answers 403 with the reason to any message sent without a client certificate, with an expired one, or over plain HTTP, and shows the certificate name, thumbprint and expiry on every arrival. Run Test Certificate on the settings page first, then a harness run with the option ticked.
Auth
The ASAP endpoints do not check a User-Token in any version, and /receive is called by the broker, not a signed-in user. Restrict access to /api/v1/asap/ at the network or IIS layer: the broker's addresses for /receive, the SBN Service Manager host for the */send and ping routes. The controller is hidden from the API catalog.
Endpoints
Verb | Route | Purpose |
|---|---|---|
GET | /api/v1/asap/ping | Ping the configured broker; returns |
GET | /api/v1/asap/address/send | Drain pending addresses from |
GET | /api/v1/asap/alarm/send | Drain pending new-alarm rows and post them to the broker. |
GET | /api/v1/asap/chat/send | Drain pending chat messages and post them to the broker. |
POST | /api/v1/asap/receive | Inbound from broker. Accepts |
The three */send endpoints are designed to be called on a schedule (the SBN Service Manager or another scheduler calling APIEngine); each call drains one batch and returns a list of per-row results. APIEngine has no internal ASAP timer in any version.
Version differences
Item | v95 and earlier | v96 and later |
|---|---|---|
ASAP certificate checks in | Not present; use | Present (see below). |
Confirming outbound delivery
An address is marked Verifying in SBN when /address/send pulls it, before the POST to the broker. The response No address rows returned on later calls only says the batch has already been pulled; it says nothing about whether the POST succeeded. The APIEngine log is the record of the POST.
Log entry | Meaning |
|---|---|
| The broker at that URL accepted the message. Check the URL is the broker ASAP assigned for this environment (test vs production). |
| The broker refused the message. The body of the entry carries the broker's reason. |
| The APIEngine host could not complete the exchange. The sentence after the error says which layer failed: the host name did not resolve (DNS), nothing answered on the port (address/port or firewall egress), or the broker closed the connection instead of answering, which over HTTPS is what a broker that requires a client certificate does when none or the wrong one is presented. |
| The TLS handshake was refused. Check the certificate named by |
| The broker accepted the connection but did not answer within 60 seconds. |
| The message was built but rejected locally. The entry lists the failing fields; the address data needs correcting. |
| The send was refused before the network; the line names the setting to correct. On builds before 08.92.0024 / 08.95.0009 the same condition appears as |
| One pair of lines per address (alarm and chat sends log the same shape) plus a batch summary. A failed address is moved to Failed in program #1675; Reset resubmits it once the cause is fixed. |
| Every message the broker delivers to |
Two calls confirm the current configuration without waiting for a batch:
GET /api/v1/asap/pingposts a PING message toMessageBrokerRestUrland returnssuccess=truewithmessage=PING accepted by <url>when the broker answers, orsuccess=falsewithmessage= the same plain-language reason that is written to the log (configuration error, network layer that failed, broker refusal with its status).GET /api/v1/diagnostic(v96 and later) includes the ASAP certificate checks: the file exists, is a file not a directory, is readable by the APIEngine identity, and opens as a PFX withCertificatePassword.
Once the broker accepts an address, APIEngine writes an Alarm Log entry on the installation reading Address submitted for validation to <agency>. Its absence on a Verifying installation means the send never completed.