> ## Documentation Index
> Fetch the complete documentation index at: https://docs.saturday.fit/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> API keys, OAuth2, environments, and securing your integration

# Authentication

Saturday supports three authentication methods depending on your use case:

| Method              | Use case                                                        | How it works                                |
| ------------------- | --------------------------------------------------------------- | ------------------------------------------- |
| **Partner API Key** | Server-to-server partner integration                            | `sk_*` Bearer token in Authorization header |
| **Coach API Key**   | A coach's own scripts/automation against their roster           | `cp_*` Bearer token in Authorization header |
| **OAuth2**          | Athlete- or coach-delegated access (incl. the Claude connector) | Authorization code flow with PKCE           |

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 — see the [Coach API](/guides/coach-api).

## API keys

All server-to-server requests use API keys passed in the `Authorization` header as Bearer tokens.

### Key types

Saturday uses prefixed API keys to prevent environment mistakes:

| Prefix     | Environment | Purpose                                                                                   |
| ---------- | ----------- | ----------------------------------------------------------------------------------------- |
| `sk_test_` | Sandbox     | Partner key — development and testing. Returns realistic data, no rate limit pressure.    |
| `sk_live_` | Production  | Partner key — real athlete data. Standard rate limits apply.                              |
| `cp_test_` | Sandbox     | Coach key — a coach's roster surface (`/v1/coach/*`) in test.                             |
| `cp_live_` | Production  | Coach key — a coach's roster surface in production. Requires the Business tier or higher. |

Coach keys (`cp_*`) are minted in the [coach portal](https://coach.saturday.fit) under **[Settings → API Keys](https://coach.saturday.fit/admin/api-keys)**, not via `api@saturday.fit`. They authenticate the coach to the [Coach API](/guides/coach-api) and are confined to that coach's roster + own config.

```bash theme={null}
# Sandbox
curl -H "Authorization: Bearer sk_test_abc123..." https://api.saturday.fit/v1/nutrition/calculate

# Production
curl -H "Authorization: Bearer sk_live_xyz789..." https://api.saturday.fit/v1/nutrition/calculate
```

<Warning>
  **Never expose live keys in client-side code.** API keys should only be used in server-to-server requests. If you suspect a key has been compromised, rotate it immediately.
</Warning>

### Getting your keys

1. Contact [api@saturday.fit](mailto:api@saturday.fit) with your platform name and use case
2. You'll receive a sandbox key after vetting
3. Complete integration testing to receive your production key

### Using your key

Include the key in the `Authorization` header on every request:

<CodeGroup>
  ```python Python theme={null}
  import requests

  headers = {"Authorization": "Bearer sk_test_abc123def456"}
  response = requests.get("https://api.saturday.fit/v1/athletes", headers=headers)
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch("https://api.saturday.fit/v1/athletes", {
    headers: { Authorization: "Bearer sk_test_abc123def456" },
  });
  ```
</CodeGroup>

### Key management

**Creating additional keys:**

```bash theme={null}
curl -X POST https://api.saturday.fit/v1/partner/api-keys \
  -H "Authorization: Bearer sk_live_xyz789..." \
  -H "Content-Type: application/json" \
  -d '{ "name": "production-nutrition-service", "environment": "live" }'
```

<Note>
  **Save the key immediately.** The full key value is only returned once at creation time. Store it securely — you won't be able to retrieve it later.
</Note>

**Rotating keys:**

Key rotation creates a new key and keeps the old one valid for 72 hours:

```bash theme={null}
curl -X POST https://api.saturday.fit/v1/partner/api-keys/key_abc123/rotate \
  -H "Authorization: Bearer sk_live_xyz789..."
```

**Revoking keys:**

Immediately invalidate a key (no grace period):

```bash theme={null}
curl -X DELETE https://api.saturday.fit/v1/partner/api-keys/key_abc123 \
  -H "Authorization: Bearer sk_live_xyz789..."
```

## Environments

| Environment | Base URL                   | Data                |
| ----------- | -------------------------- | ------------------- |
| Sandbox     | `https://api.saturday.fit` | Synthetic test data |
| Production  | `https://api.saturday.fit` | Real athlete data   |

Both environments use the same base URL — the API key prefix determines which environment you're operating in.

### Sandbox behavior

* All endpoints work identically to production
* Athlete data is isolated — sandbox athletes are not real people
* Rate limits are relaxed (higher limits for testing)
* Nutrition calculations return realistic but synthetic results
* No billing impact

## Security best practices

1. **Store keys in environment variables**, not in source code
2. **Use separate keys** for different services or deployment stages
3. **Rotate keys regularly** — at minimum every 90 days
4. **Monitor usage** for unexpected patterns
5. **Revoke immediately** if a key is exposed in logs, repos, or client code
6. **Never send keys over unencrypted channels** — all API traffic uses HTTPS

## Error responses

Authentication failures return a `401` status:

```json theme={null}
{
  "error": {
    "type": "authentication_error",
    "code": "invalid_api_key",
    "message": "The API key provided is invalid or has been revoked.",
    "documentation_url": "https://api.saturday.fit/docs/authentication",
    "request_id": "req_abc123def456"
  }
}
```

| Code                    | Meaning                                                  |
| ----------------------- | -------------------------------------------------------- |
| `invalid_api_key`       | Key doesn't exist or has been revoked                    |
| `expired_api_key`       | Key was rotated and the grace period has passed          |
| `environment_mismatch`  | Using a test key to access production data or vice versa |
| `missing_authorization` | No `Authorization` header provided                       |
