CorrConnectDocs
Early accessRequest access

API reference

Webhook events

Every event is a small JSON object with IDs only, signed with your subscription's secret. Generated from the service's OpenAPI webhooks section.

Events

activity.created

An athlete who granted activities:read added an activity. Sent to each active subscription for the app. Respond with any 2xx within 10 seconds. Anything else is tried again, up to 8 attempts in all over about two days. Payloads carry IDs only; fetch records with your token.

activity.created body
{
  "id": "evt_0123456789abcdef0123456789abcdef",
  "type": "activity.created",
  "created_at": "2026-10-09T12:00:00+00:00",
  "app_id": "app_0123456789abcdef0123456789abcdef",
  "subject": "ccu_0123456789abcdef0123456789abcdef",
  "data": {
    "activity_id": "act_0123456789abcdef0123456789abcdef"
  }
}

grant.revoked

An athlete's access for this app ended. Sent to each active subscription for the app. Respond with any 2xx within 10 seconds. Anything else is tried again, up to 8 attempts in all over about two days. Payloads carry IDs only; fetch records with your token.

grant.revoked body
{
  "id": "evt_0123456789abcdef0123456789abcdef",
  "type": "grant.revoked",
  "created_at": "2026-10-09T12:00:00+00:00",
  "app_id": "app_0123456789abcdef0123456789abcdef",
  "subject": "ccu_0123456789abcdef0123456789abcdef",
  "data": {}
}

webhook.test

You asked for a test delivery to one subscription. Sent only to the subscription you tested, after POST /v1/developer/apps/{app_id}/webhooks/{subscription_id}/test. subject is null. Retried like any other event.

webhook.test body
{
  "id": "evt_0123456789abcdef0123456789abcdef",
  "type": "webhook.test",
  "created_at": "2026-10-09T12:00:00+00:00",
  "app_id": "app_0123456789abcdef0123456789abcdef",
  "subject": null,
  "data": {}
}

Headers on every delivery

HeaderValue
CorrConnect-Signaturet=<unix seconds>,v1=<hex HMAC-SHA256 of '<t>.' + raw body, keyed with the subscription secret>.
CorrConnect-Event-IdSame on every retry of one event; use it to drop duplicates.
CorrConnect-Event-Typeactivity.created, grant.revoked or webhook.test, the same as type in the body.
CorrConnect-Delivery-IdOne delivery of the event to one subscription (whd_...); the delivery log uses the same ID.
CorrConnect-Delivery-Attempt1 on the first try, up to 8.
User-AgentCorrConnect-Webhooks/1
Content-Typeapplication/json

Event fields

FieldTypeNotes
id requiredstring
type requiredstringOne of activity.created, grant.revoked, webhook.test
created_at requiredstring (date-time)
app_id requiredstring
subject requiredstring or nullPairwise subject, the same value GET /v1/profile returns. Null for webhook.test.
data requiredobject
data.activity_idstring

Signing

CorrConnect-Signature: t=<unix seconds>,v1=<hex> where <hex> is the lowercase hex HMAC-SHA256 of <t>, a full stop and the raw request body, keyed with the subscription secret (whsec_...). Each attempt is signed again with a fresh t. Reject a t more than 300 seconds from your clock. Verification code for JavaScript, Python and Swift is in receive webhooks.

Delivery rules

RuleValue
Answer withAny 2xx within 10 seconds for the whole request. Redirects are not followed.
RetriesAfter 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours, 12 hours and 24 hours.
Attempts8 in total, then the delivery is marked failed.
PauseAfter 20 failed attempts in a row on one subscription. Turn it back on with the enable endpoint.
OrderNot guaranteed. Use created_at in the body.
DuplicatesPossible. CorrConnect-Event-Id is the same on every attempt.
Delivery logKept 30 days after a delivery finishes.
EndpointsPublic HTTPS on port 443; at most 3 subscriptions per app.
CostFree. Webhooks don't count against your rate limit; fetching the record afterwards does.

Who gets what

  • activity.created: every active subscription that listens for it, on every app holding activities:read in an active grant for the athlete. Only athletes with a verified email trigger it. One file with three sessions sends three events.
  • grant.revoked: the subscriptions of the one app whose grant ended. Pending activity.created deliveries for that athlete and app are dropped at the same time.
  • webhook.test: only the subscription you tested.

Events that happen while a subscription is paused are not stored for later.