Every event shares the same shape:
{
  "id": "evt_<32-hex>",
  "type": "<event-type>",
  "created_at": "<ISO 8601 UTC>",
  "data": {
    "user_id": "<DSS user id>"
  }
}
Bodies are JSON, UTF-8, sorted keys, no whitespace — the canonical form that the signature is computed over. See Signature verification for why that matters.

user.profile.updated

Fires when name, role, country, or photo URL change. Scope required for delivery: profile:read
{
  "id": "evt_3f4a9c8e2b1d4f5a8c9e0d1f2a3b4c5d",
  "type": "user.profile.updated",
  "created_at": "2026-05-26T09:14:00Z",
  "data": {
    "user_id": "65a1f0e2c3b4d5e6f7a8b9c0"
  }
}
Recommended action: GET /v1/me with the user’s access token, replace your cached profile.

user.sea_time.updated

Fires when sea-time totals change — a new sea time entry verified, an existing entry amended, or a recalculation. Scope required for delivery: seatime:read
{
  "id": "evt_a1b2c3d4e5f6789012345678abcdef01",
  "type": "user.sea_time.updated",
  "created_at": "2026-05-26T09:14:00Z",
  "data": {
    "user_id": "65a1f0e2c3b4d5e6f7a8b9c0"
  }
}
Recommended action: GET /v1/me/sea-time (and /recent if you display the trend chart).

user.vessels.updated

Fires when a vessel period is added or amended. Scope required for delivery: vessels:read
{
  "id": "evt_77f1bb31c0c64e6db4f5e8a9c2d3e4f5",
  "type": "user.vessels.updated",
  "created_at": "2026-05-26T09:14:00Z",
  "data": {
    "user_id": "65a1f0e2c3b4d5e6f7a8b9c0"
  }
}
Recommended action: GET /v1/me/vessels. If you paginate, start from the first page — a vessel period change can shift the sort order of any page.
Fires when the user disconnects your integration from the DSS dashboard. Scope required for delivery: none — this event delivers regardless of which scopes you held. A partner who never held profile:read still needs to know to clean up.
{
  "id": "evt_0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f",
  "type": "user.consent.revoked",
  "created_at": "2026-05-26T09:14:00Z",
  "data": {
    "user_id": "65a1f0e2c3b4d5e6f7a8b9c0"
  }
}
Recommended action: delete any cached DSS data for this user within 30 days (DPA-enforced). Your stored OAuth tokens are already invalidated on our side — calls with them will return 401 invalid_token even before this event reaches you.
Disconnect handling is a frequent gap in V1 integrations. Build it before going to production — we check for it as part of integration review.

webhook.test

Fired by GET /v1/webhooks/test. Identical shape to real events; user_id is the calling user (the access token’s subject). Scope required for delivery: none — the test endpoint always delivers.
{
  "id": "evt_test99887766554433221100ffeeddcc",
  "type": "webhook.test",
  "created_at": "2026-05-26T09:14:00Z",
  "data": {
    "user_id": "65a1f0e2c3b4d5e6f7a8b9c0"
  }
}
Recommended action: none — this is a fire-and-forget test. A 2xx response proves your handler is reachable, signature verification works, and your endpoint stays under the 5-second budget.

Delivery headers

Every delivery, regardless of event type:
HeaderValue
Content-Typeapplication/json
X-DSS-Signaturet=<unix-ts>,v1=<hex-sha256>
User-Agentdss-public-api-webhooks/1
The X-DSS-Signature value is HMAC-SHA256 of <ts>.<raw-body> using your webhook signing secret. See Verification.

Retry & give-up

AttemptDelay since previous
1(immediate)
2+1 minute
3+5 minutes
4+30 minutes
5+2 hours
6+6 hours
We give up after 24 hours or 6 attempts total, whichever comes first. Failed deliveries persist in our webhook delivery log; we surface gives-up in the super-admin dashboard for the integration team to investigate together.

Future events

We add events conservatively and announce on the changelog. Plan your handler with an unknown-event fallback that returns 2xx and logs — adding a new event type isn’t a breaking change.