CorrConnectDocs
Early accessRequest access

Guides

Testing your integration

There is no separate sandbox. You test against the same service with an athlete account you control, which means what passes in testing behaves the same way in production.

Set up a test athlete

  1. Create a second CorrConnect account for testing, with an email address you can read (you'll need to verify it).
  2. Register a separate app for development, so your test grants and limits stay apart from production. An account can own up to 10 apps.
  3. Approve the development app with the test athlete, as in the Quickstart.

Add test data

Sign in as the test athlete and add activities in the portal:

  • Upload a FIT file from your own watch or bike computer, or a GPX or TCX export. Each upload creates one record per session, track or activity, and sends activity.created.
  • Import JSON summaries when you need exact values, for example a run with no distance to check your code handles distance_meters: null.

Uploading the same file twice is ignored, so change the file (or use a different one) when you need a fresh event.

Test webhooks

  • Point a subscription at a public HTTPS tunnel to your machine; plain-HTTP localhost callbacks aren't accepted by the hosted service.
  • Send a webhook.test event and check your signature check passes.
  • Then make it fail on purpose: change one byte of the body, or use a timestamp more than 5 minutes old. Both must be rejected.
  • Return 500 once and watch the retry arrive with the same CorrConnect-Event-Id and CorrConnect-Delivery-Attempt: 2 about a minute later.

Rehearse the endings

Run each of these with the test athlete and check your app recovers:

Do thisYour app should see
Revoke the app in the athlete's CorrConnect accountgrant.revoked, then 401 on calls
Click your own Disconnect (calls POST /oauth/revoke){"status": "revoked"}, then grant.revoked
Refresh twice with the same refresh token, a minute apartinvalid_grant on the second, then grant.revoked
Approve again with only profile:read403 insufficient_scope on /v1/activities
Wait an hour without refreshing401 invalid_access_token, then a successful refresh
Ask for scope=sleep:readThe authorize page stops with invalid_scope

Check your limits

Every Bearer response with a valid token carries RateLimit-Remaining and X-RateLimit-User-Remaining. Log them during a backfill to see how close you run to the 100-per-15-minutes app limit and the 30-per-15-minutes limit for one athlete. Your test athlete's calls count against your development app only.