API keys
One bearer key is the entire credential. No OAuth flow between your client and us — that's the design.
Why a key and not OAuth
An OAuth flow between your MCP client and FitnessPeak would mean a consent screen in every client, on every device, plus token storage in each one. You already did one OAuth flow — to WHOOP, on our site, once. Making you do a second one against us would add friction without adding safety, because the thing being protected is the same read-only data either way.
What a key gives up is granularity. What it buys is a two-minute install that works in clients with no OAuth support at all.
Key format
fp_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
fp_live_prefix, then 32 bytes of CSPRNG entropy in base64url — 256 bits- We store only
SHA-256(key); the plaintext exists in exactly one HTTP response and is never recoverable - Lookup is a unique-indexed hash match, so there's no per-row comparison and no timing oracle
- Revoking is instant and permanent
Three ways to send it
| Method | Form | When |
|---|---|---|
| Bearer header | Authorization: Bearer fp_live_… | Default. Use this whenever your client allows headers. |
| API-key header | X-API-Key: fp_live_… | Clients that reserve Authorization for their own use. |
| URL path | https://fitnesspeak.app/mcp/fp_live_… | Clients with a single URL field and no header support. |
The path form is a considered trade-off. A key in a URL can land in proxy logs and browser history — genuinely worse than a header. We support it because the alternative is telling a chunk of users their client is unsupported, and because the mitigation is good: our access logs redact fp_live_ values, and you can rotate a key in five seconds. Use the header form when you can.
Rotating a key
- Create a new key in your dashboard and copy it.
- Update your client configs.
- Revoke the old key.
Do it in that order and there's no downtime — multiple keys can be active at once, which is also handy for giving each client its own key so you can see which one is actually being used.
If a key leaks
Revoke it. It stops working on the next request. A leaked key could only ever read your fitness data — it can't change your WHOOP account, can't see your card details, and can't sign in to your FitnessPeak dashboard.
Rate limits
120 calls per minute per key. Well beyond anything a human-driven assistant does, and low enough to make a runaway loop obvious. Exceed it and you get HTTP 429 with a Retry-After header.