Authentication
Saturday has three authentication methods, one per principal type:
Most partner integrations start with API keys. Add OAuth2 when you need athletes or coaches to connect their existing Saturday accounts. Coaches automating against their roster use a coach API key, covered in the Coach API.
API keys
All server-to-server requests pass the key in theAuthorization header as a Bearer token.
Key types
The prefix encodes both the principal and the environment, so a misrouted key fails closed instead of touching the wrong data.
Coach keys (
cp_*) are minted in the coach portal under API Keys, not via api@saturday.fit. They authenticate the coach to the Coach API and are confined to that coach’s roster and configuration. A coach whose subscription lapses below Pro Coach loses cp_ key access on the next request.
Coach keys use a separate scope vocabulary, chosen at mint time in the portal: roster:read, roster:write, reports:read, org:read, org:write, org:admin, webhooks:manage, billing:read. That is a different model from the partner-key scopes below, and the two do not mix. The portal offers each coach only the scopes their role and plan can mint.
Getting your keys
Self-serve accounts are issued a key at checkout. It is revealed once on the success page and emailed. If it never arrived,POST /v1/signup/resend with your checkout session id rotates and re-sends it.
Platform partners are issued keys as part of the agreement: contact api@saturday.fit with your platform name and use case. See Getting Access for which lane applies to you.
Using your key
Key management
Creating additional keys. One key per service or deployment stage keeps a compromise contained and makes rotation a non-event.scopes accepts ["*"] for unrestricted, ["read"] for GET/HEAD/OPTIONS, and ["write"] for POST/PUT/PATCH/DELETE. A read-write key needs both listed: write does not imply read. A request outside a key’s scopes gets a 403 with code insufficient_scope.
environment is optional and defaults to the environment of the host you call: live on api.saturday.fit, test on the sandbox host. Naming the other environment, or any other value, is a 400 with code invalid_value, because a key record only ever authenticates on the host that issued it.
Save the key immediately. The full value is returned once at creation. The
id in that response is what the rotate and revoke endpoints take, so store it with the key.Environments
The key prefix and the base URL travel together. Each environment keeps separate key records, so a key issued by the sandbox does not authenticate against
api.saturday.fit, and the reverse.
Sandbox behavior
- Athlete data is isolated. Sandbox athletes are not real people
- Nutrition calculations run the same engine as production, on sandbox profiles
POST /v1/test/athletes/{athlete_id}/simulate-subscriptionflips an athlete between tiers and fires the matching webhook. It exists only in sandbox- Teaser subscribe links carry
test=1so the whole checkout loop resolves against sandbox - Rate limits are enforced by the same code path as production, from your account’s configured limits. Sandbox is not exempt
- No billing impact
Security practices
- Store keys in environment variables, not in source code
- Use separate keys for different services and deployment stages
- Rotate on a schedule you can keep, and immediately on any suspected exposure
- Watch
/v1/partner/usagefor patterns you cannot account for - Revoke immediately if a key appears in logs, repos, or client code
Error responses
Authentication and authorization failures share the standard error envelope:
A key used against the wrong environment fails closed as
invalid_api_key, and the message names the environment the key was issued for. Each environment keeps separate key records, and a record whose environment is not the host’s is refused even if it is present.