Documentation source
Documentation source
Documentation source
Tenant-scoped, read-only WHOOP health ingestion with OAuth offline access, incremental cursors, redacted source capture, and private health entities.
## Overview
The WHOOP connector imports recovery, sleep, workout, and physiological-cycle
records into the Sprinter tenant. It is read-only: every provider request is a
`GET`, there are no provider operations or webhook subscriptions, and synced
records are never exposed through external API-key or MCP entity readers.
The connector is a declarative `ConnectorSpec` on the
[Integration Substrate](/docs/integrations/integration-substrate). Provider
objects are provenance-stamped in the integration ledger before their mapped
entities are upserted idempotently.
| WHOOP resource | API path | Amble entity type |
| -------------- | -------------------------------- | ----------------- |
| `recovery` | `/developer/v2/recovery` | `whoop-recovery` |
| `sleep` | `/developer/v2/activity/sleep` | `whoop-sleep` |
| `workout` | `/developer/v2/activity/workout` | `whoop-workout` |
| `cycle` | `/developer/v2/cycle` | `whoop-cycle` |
All four entity types are private, hidden from normal data navigation, and use
explicit entity shares. The integration ledger stores identifiers and timing
context while WHOOP user and score payloads are hashed before persistence.
---
## Authentication
WHOOP connections use OAuth 2 with offline access through the generic `whoop`
connection preset. A dead or copied local token is not reusable; the real
account must complete a fresh Amble OAuth authorization. Access and refresh
tokens live only in `agent_connections.encrypted_credentials`.
Before every pull, the substrate refreshes an OAuth connection when necessary
and builds the request headers from the refreshed row. Tenant declarations
contain only environment-variable names and provider configuration—never
credential values.
Deployment environment names:
| Variable | Purpose |
| --------------------------------- | --------------------------------------- |
| `WHOOP_CLIENT_ID` | WHOOP OAuth application client ID |
| `WHOOP_CLIENT_SECRET` | WHOOP OAuth application client secret |
| `AGENT_CONNECTION_ENCRYPTION_KEY` | Encrypts connection credentials at rest |
No secret values belong in source control.
---
## Incremental sync
WHOOP v2 collection responses expose `next_token`; subsequent requests send the
value as `nextToken`. Each resource has an independent cursor stored in the
tenant-scoped connection config:
- `whoopRecoveryNextToken`
- `whoopSleepNextToken`
- `whoopWorkoutNextToken`
- `whoopCycleNextToken`
Requests use a page size of 25. A scheduled apply persists the returned cursor
only after the entire run completes with zero failures. A mapping or write
failure leaves the prior cursor intact so the next run can replay safely.
Entity upserts remain idempotent by provider resource and external ID.
`dry_run` is bounded to the requested sample limit and does not write raw
objects, entities, links, or cursors.
---
## Sensitive-data posture
- The connector declaration ships with `enabled: false`.
- Provider payloads use `store: "redacted"` capture policies.
- Raw WHOOP `user_id` and score objects are hash-only in
`integration_objects`.
- Mapped health entities are private and tenant-fenced.
- External API-key routes, MCP resources, and MCP entity tools treat private
health types and their records as not found.
- There is no write-back operation and no webhook subscription code.
This design deliberately keeps useful mapped health records inside the
authenticated product while preventing verbatim provider payloads from becoming
an external integration surface.
---
## Tyler enablement gate
Production ingestion must remain disabled until Tyler completes and records all
of the following:
- [ ] Register the production WHOOP OAuth application, offline scope, and exact
callback URL.
- [ ] Configure `WHOOP_CLIENT_ID` and `WHOOP_CLIENT_SECRET` in the deployment.
- [ ] Connect the intended real WHOOP account through a fresh Amble OAuth flow.
- [ ] Run a mock-backed or bounded dry run (`limit <= 5`) and review every
resource mapping.
- [ ] Verify the raw-ledger sample contains hash wrappers and no verbatim
biometric fixture values.
- [ ] Enable the connector schedule only after the privacy review passes.
- [ ] Observe the first production run, confirm tenant ownership, token refresh,
and cursor advancement, then record the result without copying health
payloads into logs or tickets.
No live WHOOP health sync was performed while implementing this connector.
---
## Follow-up
WHOOP v2 webhooks are intentionally deferred. Any future webhook lane must
separately prove signature validation, replay protection, tenant-safe routing,
deduplication, backfill, redaction, and a production kill switch.