# Authentication (/authentication)

## API key format [#api-key-format]

| Item | Value |
|------|-------|
| Prefix | `ck_` |
| Secret | 64 hex characters |
| Header | `Authorization: Bearer ck_<secret>` |
| Content-Type | `application/json` |

Example:

```http
GET /v1/campaigns?page=1&limit=10 HTTP/1.1
Host: api.cloakup.me
Authorization: Bearer ck_0123456789abcdef...
Accept: application/json
```

Create keys in the [dashboard](https://app.cloakup.me/settings/api-keys). Keys are shown only once at creation.

## Prerequisites (every `/v1` request) [#prerequisites-every-v1-request]

Middleware applied to all `/v1` routes:

1. Valid API key (`Authorization: Bearer ck_...`)
2. Plan must have **API keys enabled** (`plan.api_keys_enabled`)
3. Active **cloakup** subscription
4. Route-specific **scope** (see each endpoint)
5. Rate limit (see below)

Failure at any step returns `401` or `403`. See [Errors](/errors).

## Rate limits [#rate-limits]

Every `/v1` route enforces a global limit of **120 requests/minute** per API key. Responses include standard `RateLimit-*` headers when applicable.

Some endpoints apply stricter limits on top of the global one.

### Endpoint-specific limits [#endpoint-specific-limits]

| Endpoint | Limit |
|----------|-------|
| All `/v1/*` | 120 req/min per API key |
| `PATCH /v1/domains/:id/verify` | 1 req per domain ID per 30 seconds |

When you exceed a limit, the API returns `429` with code `TOO_MANY_REQUESTS`. See [Errors](/errors).

## Scopes [#scopes]

Each key has one or more scopes. The endpoint rejects requests when the key lacks the required scope.

| Scope | Description |
|-------|-------------|
| `campaigns:list` | List campaigns |
| `campaigns:create` | Create campaign |
| `campaigns:show` | Get campaign by ID |
| `campaigns:update` | Update campaign |
| `campaigns:delete` | Delete campaign |
| `campaigns:clone` | Clone campaign |
| `campaigns:toggle` | Toggle campaign active status |
| `domains:list` | List domains |
| `domains:create` | Register domain |
| `domains:verify` | Verify domain DNS/certificate |
| `domains:delete` | Delete domain |

Presets in the dashboard:

- **Read only** — `campaigns:list`, `campaigns:show`, `domains:list`
- **Full access** — all scopes above

## IDs [#ids]

Resource IDs are numeric (`bigint`). JSON may serialize them as numbers or strings depending on the serializer.
