Skip to main content

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 own roster use a coach API key, covered in the Coach API.

API keys

All server-to-server requests pass the key in the Authorization 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 own config. A coach whose subscription lapses below Pro Coach loses cp_ key access on the next request. Coach keys use their own scope vocabulary, chosen at mint time in the portal: roster:read, roster:write, billing:read, billing:write, org:read, org:write, webhooks:manage. That is a different model from the partner-key scopes below, and the two do not mix.
Never expose live keys in client-side code. API keys belong in server-to-server requests only. If you suspect a key has been compromised, revoke it immediately.

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.
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, and it is not derivable from the key itself, so store it too.
Rotating keys. Rotation mints a replacement and revokes the old key in the same call, with no grace period. The old key stops working immediately.
For a cutover with no downtime, do not rotate. Create a second key, deploy it everywhere, confirm traffic has moved, then revoke the first. Revoking keys. Revocation takes effect immediately.

Environments

The key prefix and the base URL travel together. A sk_test_ key does not authenticate against api.saturday.fit.

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-subscription flips an athlete between tiers and fires the matching webhook. It exists only in sandbox
  • Teaser subscribe links carry test=1 so 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

  1. Store keys in environment variables, not in source code
  2. Use separate keys for different services and deployment stages
  3. Rotate on a schedule you can keep, and immediately on any suspected exposure
  4. Watch /v1/partner/usage for patterns you cannot account for
  5. 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 resolves as invalid_api_key, because the key does not exist in that environment’s records.