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

# Authentication

> Authenticate with the Nedzo API using Bearer tokens. Learn how to create API keys, set scopes for account or workspace-level access, and secure requests.

# Authentication

The Nedzo API uses Bearer token authentication. All API requests must include your API key in the `Authorization` header.

## API Keys

API keys are created in the Nedzo dashboard and can be scoped to:

* **Account-level**: Access all workspaces in your account
* **Workspace-level**: Access only a specific workspace

The scope you choose affects whether you need to include `workspaceId` in your requests. See [Workspace ID and Request Scope](#workspace-id-and-request-scope) below.

## Workspace ID and Request Scope

Most resources in Nedzo (contacts, agents, templates, calls) belong to a specific **workspace**. How you identify the target workspace depends on the type of API key you're using.

### Workspace-scoped keys

A workspace-scoped key is locked to a single workspace. You **do not** need to send `workspaceId` — the API infers it from the key.

```bash theme={null}
# sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (workspace-scoped key)
curl -X POST "https://api.nedzo.ai/v1/contacts" \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "John",
    "phone": "+14155551234"
  }'
```

<Note>
  Scope is determined when the key is created in the dashboard — it's not encoded in the key prefix. Both account and workspace keys use the same `sk_live_*` / `sk_test_*` format.
</Note>

### Account-scoped keys

An account-scoped key can act on any workspace in your account. You **must** send `workspaceId` in the request body (or query string for list endpoints) so the API knows which workspace to target. Omitting it returns:

```json theme={null}
{
  "type": "https://api.nedzo.ai/errors/validation-error",
  "title": "Validation Error",
  "status": 400,
  "detail": "workspaceId is required for account-scoped API keys"
}
```

Same example with an account-scoped key:

```bash theme={null}
# sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (account-scoped key)
curl -X POST "https://api.nedzo.ai/v1/contacts" \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "workspaceId": "789e4567-e89b-12d3-a456-426614174000",
    "firstName": "John",
    "phone": "+14155551234"
  }'
```

### Endpoints where the workspace is implicit

Some endpoints don't need `workspaceId` because the workspace is already determined by the resource you're addressing or by the API key itself:

* **Path-scoped resources** like `GET /v1/contacts/{id}`, `PATCH /v1/agents/{id}` — the resource's workspace is looked up from its ID.
* **`POST /v1/call`** — uses `agentId` to infer the workspace.
* **Workspace-scoped endpoints** like `/v1/workspaces/{workspaceId}/billing/...` — the workspace is in the URL path.
* **List endpoints** like `GET /v1/agents`, `GET /v1/templates`, `GET /v1/contacts` — workspace-scoped keys list within their workspace; account-scoped keys list across all workspaces (grouped or filterable via `workspaceId`).
* **`/v1/workspaces` CRUD** — `GET /v1/workspaces` returns workspaces the key can access; `POST /v1/workspaces` creates inside the key's account; `GET|PATCH|DELETE /v1/workspaces/{id}` operate on the path-scoped workspace.

### Finding your workspace ID

You can get a workspace ID from the dashboard (**Settings → Workspaces**) or via the API:

```bash theme={null}
curl https://api.nedzo.ai/v1/workspaces \
  -H "Authorization: Bearer YOUR_API_KEY"
```

The response includes `id` for each workspace your key can access.

## Making Authenticated Requests

Include your API key in the `Authorization` header:

```bash theme={null}
curl https://api.nedzo.ai/v1/workspaces \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxx"
```

## API Key Format

Nedzo API keys follow this format:

| Environment | Format      | Example             |
| ----------- | ----------- | ------------------- |
| Production  | `sk_live_*` | `sk_live_abc123...` |
| Test        | `sk_test_*` | `sk_test_xyz789...` |

## Error Responses

If authentication fails, you'll receive a `401 Unauthorized` response:

```json theme={null}
{
  "type": "https://api.nedzo.ai/errors/unauthorized",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Invalid or missing API key"
}
```

## Security Best Practices

<AccordionGroup>
  <Accordion title="Never expose keys in client-side code">
    API keys should only be used in server-side code. Never include them in JavaScript that runs in browsers or mobile apps.
  </Accordion>

  <Accordion title="Use environment variables">
    Store API keys in environment variables, not in your codebase.

    ```bash theme={null}
    export NEDZO_API_KEY=sk_live_xxxxxxxx
    ```
  </Accordion>

  <Accordion title="Rotate keys regularly">
    Periodically rotate your API keys, especially if you suspect they may have been compromised.
  </Accordion>

  <Accordion title="Use workspace-scoped keys">
    When possible, use workspace-scoped keys to limit the blast radius if a key is compromised.
  </Accordion>
</AccordionGroup>

## Rate Limits

API requests are rate-limited to ensure fair usage:

| Plan       | Requests per minute |
| ---------- | ------------------- |
| Free       | 60                  |
| Pro        | 300                 |
| Enterprise | Custom              |

When rate limited, you'll receive a `429 Too Many Requests` response with a `Retry-After` header.
