

## API keys [#api-keys]

Every request must include your API key, either in the `X-API-Key` header:

```bash
curl https://api.statshawk.ai/v1/competitions \
  -H "X-API-Key: sk_live_YOUR_KEY_HERE"
```

or as a bearer token in the `Authorization` header:

```bash
curl https://api.statshawk.ai/v1/competitions \
  -H "Authorization: Bearer sk_live_YOUR_KEY_HERE"
```

`X-API-Key` takes the raw key. `Authorization` requires the `Bearer ` scheme — a raw key
there is rejected as malformed.

## Key format [#key-format]

Keys follow this structure:

```
sk_{environment}_{32 base62 characters}
```

| Prefix      | Environment | Use                                                                        |
| ----------- | ----------- | -------------------------------------------------------------------------- |
| `sk_live_…` | Live        | Production requests                                                        |
| `sk_test_…` | Test        | Sandbox / staging traffic, kept separate in your own logs and key rotation |

Both environments authenticate, meter, and rate-limit identically — the split exists so
you can rotate and attribute the two traffic classes independently.

The first 16 characters of the full key (`sk_live_` + 8 chars) form a non-secret prefix
stored for display in your dashboard. The rest of the key is stored only as a hash — if
you lose the key you'll need to create a new one.

## Generating and revoking keys [#generating-and-revoking-keys]

Visit [API Keys](/dashboard/api-keys) in your dashboard to:

* Generate live or test keys
* Give each key a descriptive name
* Revoke any key immediately

Revocation takes effect within seconds. The request currently in flight may still complete; the next one will receive a `401`.

## No key? No request. [#no-key-no-request]

A missing or malformed key gets:

```json
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "API key required"
  }
}
```

A well-formed key that doesn't resolve to an account gets the same code with
`"Invalid API key"`. Both are `401 Unauthorized`.

If the key-validation backend itself is unavailable, you'll see
`503 AUTH_BACKEND_UNAVAILABLE` instead — that's an outage, not a bad key, and it's safe to
retry with back-off.
