# API Keys

> Create, use, and manage API keys with scopes and resource access


import { CodeBlock } from "@/components/docs";

## TL;DR

- Generate keys in [Organization Settings → API Keys](https://app.databuddy.cc/organizations/settings#api-keys)
- Use either `Authorization: Bearer <key>` or `x-api-key: <key>`
- Keys start with `dbdy_` followed by 48 characters
- Scopes: `read:data`, `track:events`, `read:links`, `write:links`, `read:monitors`, `write:monitors`, `read:status_pages`, `write:status_pages`, `manage:websites`, `manage:flags`, `manage:config`
- Access can be global or scoped to a resource like a specific `website`
- For private websites, include `website_id` and ensure the key has `read:data`
- Rotate and revoke keys in [Organization Settings → API Keys](https://app.databuddy.cc/organizations/settings#api-keys); only the prefix/start should be shared/logged

### What is an API key?

An API key authenticates server-to-server calls to Databuddy. It supports fine-grained scopes and optional resource scoping to enforce least-privilege access. Keys start with `dbdy_` followed by 48 characters.

### Create a key

1. Open [Organization Settings → API Keys](https://app.databuddy.cc/organizations/settings#api-keys)
2. Click “Create API Key”
3. Choose a name, optional organization, scopes, and resource access
4. Copy the secret immediately (it’s only shown once)

We only display the `prefix` and first characters (`start`) later for identification. Never share the full secret.

### Use your key

You can authenticate with either header:

<CodeBlock 
  language="bash"
  code={`curl -X POST "https://api.databuddy.cc/v1/query?website_id={website_id}" \\
  -H "Authorization: Bearer YOUR_API_KEY" \\
  -H "Content-Type: application/json" \\
  -d '{"id":"summary","parameters":["summary"],"startDate":"2024-01-01","endDate":"2024-01-31"}'`}
/>

<CodeBlock 
  language="bash"
  code={`curl -X POST "https://api.databuddy.cc/v1/query?website_id={website_id}" \\
  -H "x-api-key: YOUR_API_KEY" \\
  -H "Content-Type: application/json" \\
  -d '{"id":"summary","parameters":["summary"],"startDate":"2024-01-01","endDate":"2024-01-31"}'`}
/>

Notes:

- For private websites, include the `website_id` query parameter and ensure the key has `read:data` for that site.
- For link shortener analytics, use `link_id` instead of `website_id`; this requires `read:data` with global access.
- `POST /track` for event ingestion lives on `basket.databuddy.cc`, not `api.databuddy.cc`.

### Scopes

- **read:data**: Read analytics data. Covers query endpoints (`POST /v1/query`, `POST /v1/query/compile`) and listing accessible websites (`GET /v1/query/websites`). Required for any dashboard-style data retrieval.
- **track:events**: Send custom events via the SDK or the `/track` endpoint on `basket.databuddy.cc`, and MCP tool calls via `@databuddy/sdk/mcp`
- **read:links**: Read short links
- **write:links**: Create, update, and delete short links
- **read:monitors**: Read uptime monitors
- **write:monitors**: Create, update, and delete uptime monitors
- **read:status_pages**: Read status pages
- **write:status_pages**: Create, update, and delete status pages
- **manage:websites**: Create, update, and delete websites and their settings
- **manage:flags**: Create, update, and delete feature flags and targeting rules
- **manage:config**: Integration config and organization settings

Grant only what you need. Prefer resource-scoped access where possible.

#### What each scope unlocks

| Scope | Endpoints / actions |
|-------|---------------------|
| `read:data` | `POST /v1/query`, `POST /v1/query/compile`, `GET /v1/query/websites`, `websites.list` RPC |
| `track:events` | `POST /track` and `POST /mcp` on `basket.databuddy.cc` (custom events, pageviews, sessions, MCP tool calls) |
| `read:links` | Read short links via the `/rpc/links/*` routes |
| `write:links` | Create, update, and delete short links via the `/rpc/links/*` routes |
| `read:monitors` | Read uptime monitors and their check history |
| `write:monitors` | Create, update, pause, and delete uptime monitors |
| `read:status_pages` | Read status pages and their configuration |
| `write:status_pages` | Create, update, and delete status pages and incidents |
| `manage:websites` | Create / update / delete websites, rotate tracking config |
| `manage:flags` | Feature flag CRUD, targeting rule edits, flag evaluation admin |
| `manage:config` | Integration config and organization-level settings |

Link analytics are queried through `POST /v1/query` with `link_id` and require `read:data` with global access, not a links scope.

Listing websites is intentionally gated by `read:data` (not a separate `read:websites` scope) because the list is only useful for picking a site to query. Any key that can list sites can already read their analytics.

### Resource access

Access can be scoped to:

- **global**: Applies to all websites in the organization
- **website**: Applies to a specific website only

Example: a key with `read:data` scoped to a single website can read analytics only for that website, not others in the organization.

### Errors

Authentication/authorization failures return structured errors:

<CodeBlock 
  language="json"
  code={`{
    "success": false,
    "error": "Authentication required",
    "code": "AUTH_REQUIRED"
  }`}
/>

<CodeBlock 
  language="json"
  code={`{
    "success": false,
    "error": "Insufficient permissions",
    "code": "FORBIDDEN"
  }`}
/>

### Rotation and revocation

- **Rotate** to generate a new secret for the same key (update your servers immediately)
- **Revoke** to immediately disable a key (cannot be undone; create a new one if needed)

Actions are available in [Organization Settings → API Keys](https://app.databuddy.cc/organizations/settings#api-keys) under each key’s detail view.

### Rate limits

All API endpoints are rate-limited. See the Rate Limits section in the API Reference. Responses include standard `X-RateLimit-*` headers where applicable.

### Audit Logging

Administrative mutations on API keys are logged: created, updated, revoked, rotated, and deleted. Per-request usage is not logged.

### Best practices

- Treat API keys like passwords; don't commit them to source control
- Use environment variables or secret managers
- Share only the prefix and `start` snippet for identification
- Use least-privilege scopes and resource scoping
- Rotate keys periodically and revoke unused keys
- Monitor audit logs for suspicious activity
- Use resource-scoped keys for better security
