Developer docs / Server-side

Webhooks

Description

StickyHealth can send events to your server as HTTPS POST requests. Today the only event we send is notification.triggered: when your organization has a webhook configured, each notification StickyHealth would send a member arrives at your server instead of as a push notification from us, and you deliver it to the member yourself.

Setting up

Webhooks are not self-serve. To turn them on, email info@stickyhealth.com with your endpoint URL. We configure the endpoint and a signing secret for your organization and share the secret with you securely.

Your endpoint must:

  • use https:// (we skip delivery to any other URL)
  • accept a POST with a JSON body
  • respond within 10 seconds

Events

EventSent when
notification.triggeredOne of the member's notifications is due, for example a reminder to log a meal.

More event types may be added later. Ignore types you don't recognize, and still answer them with a 2xx status.

Payload

Every event has the same envelope:

json
{{code.b0}}
FieldTypeDescription
idstringUnique event id (a UUID). Retries of the same event keep the same id, so use it to drop duplicates.
typestringThe event type.
created_atstringWhen the event was created, ISO 8601 in UTC.
external_uidstringThe member's id in your system: the user id (sub) from your sign-in token. If we hold no id from your sign-in for the member, our own member id.
dataobjectEvent-specific fields. For notification.triggered: title and body, the text to show the member.
metadataobject | nullExtra context, or null. For notification.triggered it holds chat_session_id when the notification belongs to a chat session.

Headers

HeaderValue
Content-Typeapplication/json
X-Miri-Signaturesha256= followed by the hex HMAC-SHA256 of the raw request body, keyed with your signing secret
X-Miri-Event-TypeThe event type, same as type
X-Miri-Webhook-IdThe event id, same as id
X-Miri-Delivery-Attempt1 for the first attempt, then 2, 3... on retries
X-Miri-External-IdThe member's id, same as external_uid

Verifying the signature

Compute the HMAC-SHA256 of the exact bytes you received, keyed with your signing secret, and compare it with the X-Miri-Signature header in constant time. Verify before you parse the JSON: parsing and re-serializing the body changes the bytes, so the signature will not match.

python
{{code.b1}}

Responses and retries

  • 2xx: delivered. Respond quickly and do any slow work afterwards.
  • 4xx: treated as a permanent rejection. We do not retry.
  • 5xx, other statuses, timeouts (10 seconds) and connection errors: we retry. An event gets at most 5 attempts in total: the first, then retries after 30 seconds, 1 minute, 2 minutes and 5 minutes. After the fifth failed attempt the event is dropped.

If your endpoint keeps failing (around 10 server errors, timeouts or connection errors in a row), we pause delivery to it for 5 minutes. Events that come due during the pause are dropped, not queued. After the pause we send one event to test the endpoint, and normal delivery resumes once one succeeds.

Because of retries, the same event can arrive more than once. Use id (or X-Miri-Webhook-Id) to ignore repeats.

← Settings Next: Authorization requests →