Skip to content

Webhooks

Webhooks let your application receive real-time notifications when activities or tests are created, updated, or deleted in SweatStack.

Setting up webhooks

Configure webhook endpoints in your API settings. You can register one or more URLs where SweatStack will POST event notifications.

A Webhook Secret is generated when you create a webhook. Use it to verify that incoming events are genuinely from SweatStack. You can regenerate (roll) the secret at any time; it takes effect immediately.

Event types

SweatStack emits these events:

Event type Triggered when
activity_created A new activity has been created.
activity_updated An existing activity has been updated.
activity_deleted An activity has been deleted.
test_created A new test has been created.
test_updated An existing test has been updated.
test_deleted A test has been deleted.

Webhook payload

Every event has the same shape:

{
  "user_id": "string",
  "event_type": "activity_created",
  "resource_id": "string",
  "timestamp": "2026-05-06T12:00:00Z"
}

The resource_id is the ID of the resource that triggered the event (an activity ID for activity_* events, a test ID for test_* events).

Resource data is not included in the payload. Fetch the full resource via the appropriate endpoint when you receive the event.

Response time requirement

Your webhook endpoint must return a 2xx status code within 2 seconds to acknowledge receipt. Failed deliveries are retried with exponential backoff until either a 2xx is received or the retry window exceeds 24 hours.

Verifying webhook signatures

All webhook events are signed with HMAC-SHA256. The signature lives in the X-Sweatstack-Signature header with the format t={timestamp},v1={signature}.

To verify:

  1. Extract the timestamp and signature from the header.
  2. Construct the signed payload: {timestamp}.{json_body}.
  3. Compute HMAC-SHA256 using your webhook secret.
  4. Compare signatures using constant-time comparison.
  5. Validate the timestamp to prevent replay attacks (5 minutes is a reasonable tolerance).

Best practices

  • Verify signatures. Always verify before processing the event.
  • Return quickly. Acknowledge with 2xx within 2 seconds, then process asynchronously.
  • Be idempotent. SweatStack may retry deliveries. Make event handling idempotent on resource_id and event_type.
  • Log events. Keep a record of received webhooks for debugging and reconciliation.

Patterns and gotchas

Webhooks are app-level, not per-user. A webhook endpoint configured in your API settings receives events for every user of your app. The user_id field on the payload tells you which one.

Payloads carry IDs, not data. A webhook event tells you that something happened; it does not include the activity, test, or measurement itself. To enrich a webhook event with the actual resource, your handler calls the relevant SweatStack endpoint using that user's access token. Which means your webhook handler needs a way to look up tokens by user_id (typically a small key-value store or your own user database).

Mobile apps cannot receive webhooks directly. Webhooks are HTTP POSTs to a public endpoint, which a phone is not. The standard pattern is a server-side gateway (a small worker or function) that receives the SweatStack webhook, looks up the user's push token, and fans the event out to APNs (iOS) or FCM (Android). The gateway is also the right place to do the enrichment described above. See the native mobile app guide for an end-to-end example.

Plan for replays. SweatStack retries on failure with exponential backoff. A successful delivery is also possible alongside a retried one if your endpoint timed out after processing. Idempotency on (resource_id, event_type) keeps duplicates from corrupting state.

Next steps