Skip to main content

NG-SOS Connector

NG-SOS Connector is the umbrella name for the outbound integration in which NG-SOS sends incident data to an external partner system. The partner implements the documented contract and NG-SOS Publisher calls that partner system.

The name NG-SOS Connector is only a rename of the concept previously called PSAP Connector. It does not introduce a second integration or require an existing integration to be replaced. The older PSAP Connector names remain in the v1 and v2 contract titles for compatibility.

Versions

VersionContractPurposeDocumentation
v1PSAP Connector v1Frozen legacy contract for existing integrations.Open v1 contract
v2PSAP Connector v2Frozen successor to v1 for existing integrations.Open v2 contract
v3NG-SOS Webhooks v3Current source-aware contract for new integrations.Open v3 contract

Version 3 was introduced to support source-aware incident integrations, including Apple EED and Google ELS. It adds source-aware incident data and capability negotiation: the external system declares supported operations in GET /about; NG-SOS uses the specific operation when supported and otherwise sends one generic incident-changed notification.

A v3 integration must declare at least one of supports.incident.created and supports.incident.changed. An integration that declares neither can never be told that an incident exists, so NG-SOS rejects its /about response and does not start the integration; the rejection is logged and retried, and the outbound messages wait in the queue until the delivery window below expires. Every other flag and group stays optional, and a missing one means unsupported.

New integrations should use v3. Existing v1 and v2 integrations remain available as frozen compatibility contracts and should not be changed without an agreed migration plan.

Moving an existing v2 integration to v3 is described in the migration guide.

Integration model

NG-SOS Publisher is the service operated by NG-SOS. It publishes incident projections and ordered change notifications to the partner's HTTPS endpoints. These OpenAPI documents are implementation contracts, not APIs hosted by NG-SOS; there is no Try it workflow against NG-SOS.

Every event carries NG-SOS-Request-Id and NG-SOS-Request-Timestamp. Retries preserve both values, so deduplicate by the request ID. Answer with exactly the success status documented for the operation — 200 for every v3 event operation, the create operation included. Any other status counts as a failed delivery and is retried.

Delivery window

A failed delivery is retried with exponential backoff: the first retry one second later, the delay doubling each time, for one hour measured from the moment NG-SOS produced the event. A delivery that has not been accepted within that hour is abandoned and never arrives, and NG-SOS does not resend it later. The same hour bounds an event waiting in the queue for an integration that is not running or whose /about is being rejected.

A receiver outage longer than one hour is therefore not supported: the events raised during it are gone. What that costs depends on the event — a missed PATCH of a text field is corrected by the next one, but a missed POST /v3/incident/{incidentId}/caller/track leaves a permanent hole in a caller track, because the operation appends and nothing later re-sends the location it carried. Keep the receiver available, monitor it, and after an outage ask NG-SOS to re-send the affected incidents rather than assuming the queue will catch up.

Two consequences for the receiver:

  • Retain each NG-SOS-Request-Id for at least an hour. A retry can arrive at any point in the window and repeats the original id, so anything shorter risks processing a delivery twice.
  • Answer 200 as soon as the delivery is durably recorded and do the rest of the work afterwards. Holding the response open while you process spends the same one hour that the retries need.

Answering a delivery

200 is the only status that accepts an event delivery; anything else is a failed delivery and is retried. That rule governs event routes only. /about and /health are discovery and health endpoints, not deliveries: they answer with ordinary HTTP semantics. /about in particular is where a v3-only integration answers 401 or 403 to the legacy PsapConnector credential, which is why it is the only route that declares those statuses.

Deliveries for one incident are strictly ordered and run one at a time. NG-SOS starts the next event for an incident only once the current one has been accepted, so a delivery that keeps failing holds back every later event for that incident until it succeeds or the delivery window expires. Events for different incidents are independent of each other.

That ordering is what makes the choice of status matter beyond the single request:

  • Answer 200 once the delivery is recorded. Do the rest of the work afterwards. A receiver that answers only after processing spends the retry budget on its own latency, and stalls the incident's later events behind it.
  • Answer a non-200 only for a failure a retry could resolve — your storage was briefly unavailable, a dependency timed out. Rejecting a payload you will never accept turns one bad event into a stalled incident, because the retries change nothing and the events behind it wait.
  • A delivery you cannot process is still worth accepting. Record it, answer 200, and use the incident's openUrl to work in Portal while you investigate.

For v3, the receiver validates the NG-SOS Identity bearer token on every route. Its iss is https://identity.ng-sos.com, whose discovery document publishes the jwks_uri the signing keys come from; its typ is at+jwt; both sub and client_id equal Publisher; aud equals urn:ng-sos:webhooks:{your-agency-id}; it has the webhooks.receive scope; and it is a valid, unexpired access token. The scope grants Publisher access to the Webhooks integration as a whole; it does not select an event. The audience isolates one agency's integration from every other agency. The migration guide lists every value to validate against.

For v1 and v2, the receiver validates the NG-SOS bearer token. The aud claim must equal urn:ng-sos:agency:{your-agency-id}, both sub and client_id must equal PsapConnector, and the token must contain the psap.* scope required by the endpoint.

All three versions expose the same GET /about and GET /health endpoints. The about response reports the implemented version and supported operations; health returns 200 when the connector is available. NG-SOS calls /about with the legacy PsapConnector credential first and retries with the v3 Publisher credential, so a v3-only integration must answer 401 or 403 for the legacy credential rather than rejecting the request outright.

Every incident carries a purpose that NG-SOS sets from the way the incident was created; an integration never supplies it. To verify a receiver without faking an emergency, ask NG-SOS to create a test incident for your agency: it is delivered over the normal event routes with purpose set to Test on v3, and with isTest: true on v1 and v2. The full value list is in the migration guide. A receiver must be able to accept a test incident whatever it reports in allowsMonitoring: that flag is advisory today and NG-SOS does not filter on it.

PEMEA is a separate standardized integration option for agencies already connected through that network. See the PEMEA page for details.