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

shape
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

MethodFormWhen
Bearer headerAuthorization: Bearer fp_live_…Default. Use this whenever your client allows headers.
API-key headerX-API-Key: fp_live_…Clients that reserve Authorization for their own use.
URL pathhttps://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

  1. Create a new key in your dashboard and copy it.
  2. Update your client configs.
  3. 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.