When a crew member’s record changes, we POST a signed event to every partner who holds active consent and the relevant scope. You re-fetch via the API to get the latest state. We retry on non-2xx with a documented schedule. Webhooks are the recommended way to stay fresh — partners who poll instead will hit conditional GETs (304 Not Modified) far more often than not and burn rate-limit budget for no payload.

What you receive

Every delivery looks like this:
POST https://yourapp.example.com/integrations/dss/webhook
Content-Type: application/json
X-DSS-Signature: t=1716714840,v1=99d56ccfe6de640971036fc31a8bb476415322e6b687301c96fe15ac81e3fcff
User-Agent: dss-public-api-webhooks/1

{"created_at":"2026-05-26T09:14:00Z","data":{"user_id":"65a1f0e2c3b4d5e6f7a8b9c0"},"id":"evt_3f4a9c8e2b1d4f5a8c9e0d1f2a3b4c5d","type":"user.sea_time.updated"}
The body is a pointer, not data. You call back via the API with the user’s access token to fetch the latest state. Two reasons:
  1. Payloads stay small and our signing surface stays minimal.
  2. Scope is re-evaluated at fetch time. If the user revoked between event firing and your fetch, the fetch fails cleanly (401 invalid_token) instead of leaking stale data.
The body is serialised with sorted keys and no whitespace so the canonical form is stable across any intermediates that might re-serialise.

Delivery model

Reliability

  • At-least-once delivery. You may see the same event twice — dedupe on id.
  • Retry schedule: +1m, +5m, +30m, +2h, +6h. We give up after 24h (or 6 attempts total, whichever comes first).
  • Response budget: 5 seconds. If your handler takes longer we treat it as a failure and retry.
  • Idempotency key is the event id, stable across every attempt.

Order

Webhooks are not ordered. Multiple events for the same user can arrive out of order, especially after retries. Always fetch the latest state from the API rather than trying to apply an event as a delta — the event tells you “something changed,” the API call tells you “this is the new value.”

Registering your endpoint

During onboarding you’ll give us:
  • A single HTTPS URL.
  • A signing secret rotation contact (an email we ping when we plan to rotate).
We give you back a webhook signing secret, separate from your client_secret. Store it next to your other secrets. The client_secret and webhook_secret rotate independently — rotating either one does not affect the other. To change your webhook URL or rotate the secret in sandbox, email admin@digitalseaservice.com. Production rotation is handled by your DSS account contact.

Testing your handler

Once your URL and secret are registered, call GET /v1/webhooks/test with a valid access token and we’ll fire a webhook.test event to your URL. It’s the same shape and signing as every other event — use it to validate signature verification before any real user authorises you.
curl -sS -H "Authorization: Bearer $ACCESS_TOKEN" \
  https://api.dev.digitalseaservice.com/v1/webhooks/test
A successful call returns 200 OK with the event_id, delivery_id, and the target_url we enqueued the delivery against:
{
  "event_id": "evt_3f4a9c8e2b1d4f5a8c9e0d1f2a3b4c5d",
  "delivery_id": "dlv_77f1bb31c0c64e6db4f5e8a9c2d3e4f5",
  "target_url": "https://yachtworkerscouncil.com/integrations/dss/webhook"
}
Watch your handler logs for the delivery.

What’s next

Event catalogue

Every event we send, with payload examples and recommended action.

Signature verification

Drop-in code samples in Python and Node — copy these verbatim.