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

# Authentication

> How API key authentication works

# Authentication

All API requests require a Bearer token in the `Authorization` header.

## API keys

API keys follow the format `sk_live_*` and are generated through the web app's workspace settings. Each key is associated with a workspace and its connected channels.

```bash theme={null}
Authorization: Bearer sk_live_your_api_key
```

## How it works

1. Your request includes the API key in the `Authorization: Bearer` header
2. The server SHA256-hashes the key and looks it up in Redis (`mcp:apikey:*` prefix)
3. The stored context includes the workspace ID and credentials for each connected channel (Meta, LinkedIn, Google)
4. Per-request credentials are injected via `AsyncLocalStorage` — each tool call uses the correct channel credentials automatically

## Channel connections

A single API key can have multiple channels connected. The key's stored context looks like:

```json theme={null}
{
  "keyId": "key_abc123",
  "workspaceId": "ws_xyz789",
  "channels": {
    "meta": {
      "accessToken": "EAAB...",
      "accountId": "123456789"
    },
    "linkedin": {
      "accessToken": "Bearer ...",
      "accountId": "987654321"
    },
    "google-ads": {
      "accessToken": "ya29...",
      "refreshToken": "1/..."
    }
  }
}
```

If you call a source that isn't connected in your API key, you'll get a `403 FORBIDDEN` error with `ChannelNotConnectedError`.

## Error responses

| Status | Code           | Meaning                            |
| ------ | -------------- | ---------------------------------- |
| 401    | `UNAUTHORIZED` | Missing or invalid API key         |
| 403    | `FORBIDDEN`    | Channel not connected for this key |
