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

# Authentication

> How to authenticate with the Kodo Status API

## API Keys

All API requests require authentication using an API key. Include your key in the `X-API-Key` header:

```bash theme={null}
curl "https://kodostatus.com/api/v1/incidents" \
  -H "X-API-Key: your_api_key_here"
```

## Getting Your API Key

1. Log in to your [Dashboard](https://kodostatus.com/dashboard)
2. Navigate to **Settings > API**
3. Click **Generate API Key**
4. Copy and securely store your key

<Warning>
  API keys grant full access to your organization. Keep them secret and never commit them to version control.
</Warning>

## Scoped API Keys

For fine-grained access control, create scoped API keys with specific permissions. This is recommended for CI/CD pipelines, integrations, and service accounts.

1. Go to **Settings > API Keys** in your dashboard
2. Click **Create Key**
3. Name your key and select the required scopes
4. Optionally set an expiry date
5. Copy the key immediately — it won't be shown again

### Available Scopes

| Scope                 | Description                             |
| --------------------- | --------------------------------------- |
| `*:*`                 | Full access (default)                   |
| `incidents:read`      | List and view incidents                 |
| `incidents:write`     | Create, update, delete incidents        |
| `services:read`       | List and view services                  |
| `services:write`      | Create, update, delete services         |
| `status_pages:read`   | List and view status pages              |
| `status_pages:write`  | Manage status pages and designs         |
| `monitors:read`       | View uptime, SSL, and domain monitors   |
| `monitors:write`      | Manage monitors                         |
| `maintenance:read`    | View maintenance windows                |
| `maintenance:write`   | Manage maintenance windows              |
| `notifications:read`  | View notification channels and webhooks |
| `notifications:write` | Manage channels and webhooks            |
| `config:read`         | Read organization configuration         |
| `config:write`        | Update configuration                    |
| `heartbeat:write`     | Send heartbeat pings                    |
| `metrics:write`       | Push metrics data                       |
| `workflows:write`     | Trigger workflows                       |
| `audit_log:read`      | Read the audit log                      |

### Scope Enforcement

When a scoped key attempts an action it doesn't have permission for, the API returns:

```json theme={null}
{
  "error": "Insufficient scope: incidents:write required"
}
```

<Info>
  Legacy API keys (from Settings > API) retain full `*:*` access for backwards compatibility.
</Info>

## Environment Variables

We recommend storing your API key in environment variables:

```bash theme={null}
# .env
KODO_API_KEY="your_api_key_here"
```

## Rate Limits

| Endpoint           | Limit                  |
| ------------------ | ---------------------- |
| Standard endpoints | 1,000 requests/minute  |
| Heartbeat endpoint | 10,000 requests/minute |
| Beacon endpoint    | No limit               |

Rate limit headers are included in all responses:

```
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1704844800
```

## Endpoints Outside `/api/v1`

Some endpoints live at `/api/` instead of `/api/v1/` and use their own authentication:

* `POST /api/heartbeat/:monitorId` - Send heartbeat pings (API key in header)
* `GET /api/heartbeat/:monitorId` - Check heartbeat status (API key in header)
* `POST /api/beacon` - Report client-side events (beacon public key in body)
* `POST /api/metrics/ingest` - Push metrics (API key in header)

All of these endpoints require authentication via the `X-API-Key` header or `Authorization: Bearer` header, except the beacon endpoint which uses a beacon public key (`bpk_...`) in the request body.
