Signals webhooks

Receive Signals alerts, episodes, readings and patient changes as signed webhooks: subscribers, events, reach, signatures and redelivery.

Signals can push events to your system instead of you polling GET /alert. A subscriber is a Signals client with a webhook URL and a list of events. Signals manages the deliveries; Ovok exposes the routes to create and run subscribers, and holds their credentials.

Every route on this page needs a Manager application or a user with the capabilities shown.

TaskRouteCapabilities
Create a subscriberPOST /v1/signals/api/usersignals_webhooks:update, signals_events:read
Change its URL, events or reachPOST /v1/signals/api/user/:idsignals_webhooks:update, signals_events:read
Delete itDELETE /v1/signals/api/user/:idsignals_webhooks:delete
Check its endpointGET /v1/signals/api/subscriber/:id/webhooksignals_webhooks:read
Send a test eventPOST .../webhook/testsignals_webhooks:update
Turn it off or onPOST .../webhook/disable, .../enablesignals_webhooks:update
Rotate its signing secretPOST .../webhook/rotate-secretsignals_webhooks:update
See what was sentGET /v1/signals/api/events, .../events/:id/attemptssignals_events:read
Send events againPOST /v1/signals/api/events/redeliver, .../events/:id/redeliversignals_webhooks:update

Create a subscriber

curl --request POST 'https://api.sandbox.ovok.com/v1/signals/api/user' \
  --user "${OVOK_MANAGER_ID}:${OVOK_MANAGER_SECRET}" \
  --header 'Content-Type: application/json' \
  --data '{
    "role": "SUBSCRIBER",
    "name": "Ward alerts",
    "webhookUrl": "https://example.com/signals/webhook",
    "events": ["alert.*"],
    "reach": "all"
  }'
  • Add episode.* only once your tenant has episodicAlerts on; until then it answers 403 FEATURE_DISABLED (see Events).
  • Send role: "SUBSCRIBER". Through Ovok, only subscribers are created; any other role answers 403.
  • Don't send clientId, secret or webhookSecret. Ovok generates the subscriber's id and Signals login, which it never uses, and answers 422 if you send them.
  • Subscribers are on event schema 2. Sending another eventSchema answers 422.
  • The answer carries signingSecret once. Store it: you need it to verify deliveries, and you get a new one only by rotating it.
  • Location names the new subscriber under /v1/signals/api/user/:id.

A create retried after a timeout can make a second subscriber. List them with GET /v1/signals/api/user and delete the extra one.

Reach: which patients it hears about

reachPatients
attached (default)Only the patients attached to it. Attach them with POST /v1/signals/api/subscriber/:id/patients.
allEvery patient of your tenant, including patients enrolled later.

Events

Name exact events, or a whole family with a wildcard such as alert.*.

EventWhen
alert.triggeredA reading breaches a trigger and opens an alert.
alert.refiredAnother breach refreshes an open alert.
alert.resolvedA trigger resolves the alert.
alert.acknowledgedSomeone acknowledges the alert.
alert.empty, alert.note, alert.inactiveAn empty reading, a note, or a patient going quiet raises an alert.
episode.opened, episode.closedAn episode starts or ends.
observation.created, observation.updatedA reading is stored or changed. One delivery per reading: subscribe only if you need them.
patient.subscribed, patient.unsubscribedA patient is attached to or detached from the subscriber.
patient.config, patient.inactiveA patient's config changes, or the patient goes inactive.
webhook.testYou sent a test event. It is not queued, retried or listed.
webhook.disabledSignals turned another subscriber's endpoint off because it answered 410 or kept failing. You are never told about your own.

Readings posted with Prefer: respond-sync report their alerts in the answer, and send no webhook for them.

Episode events need episodes. Signals records episodes only while your tenant has episodicAlerts on. Naming an episode event while it is off answers 403 FEATURE_DISABLED. Turn it on with PATCH /v1/signals/api/tenant and {"settings":{"episodicAlerts":true}}.

Verify each delivery

Deliveries follow Standard Webhooks. Each one carries webhook-id, webhook-timestamp and webhook-signature; verify them with a Standard Webhooks library and the subscriber's signingSecret (whsec_…). The body is one JSON event with its type, its data and when it happened. If you set custom, every delivery carries it back as x-actimi-custom.

Answer 2xx quickly and do the work afterwards. A delivery that fails is retried.

Rotating the secret. rotate-secret returns the new secret once. The old one keeps signing for 24 hours, so webhook-signature carries both and you can switch with no gap. Rotate again only after your receiver uses the new secret.

When deliveries fail

SituationWhat happens
Recent attempts failedThe endpoint is failing. Signals keeps retrying.
Five days of failures with no deliverySignals turns the endpoint off (disabledReason: failing).
Your endpoint answers 410 GoneSignals turns it off at once (disabledReason: gone).
You disabled itNothing is sent (disabledReason: manual).

While an endpoint is off, new events are held, not dropped. Ovok tells your project's admins when Signals turns one off. After you fix the receiver, enable it, then send the held events with POST /v1/signals/api/events/redeliver?status=held&since=<ISO 8601 time>. since is required; the call answers 202 with how many it queued, at most 1,000 at a time. Enabling alone re-queues nothing.

GET /v1/signals/api/events lists every event with how its delivery went. It pages oldest first, and can lag a little behind the newest deliveries.

Last updated on

On this page