# Authentication

> Create and manage API keys, authenticate requests, and understand security best practices for the watsi API.

Source: https://docs.watsi.ai/en/guides/authentication

All watsi API requests require a Bearer token. This guide covers how to create API keys, authenticate requests, and keep your credentials secure.

## Creating an API key

### Sign in

Sign in to the [watsi dashboard](https://app.watsi.ai).

### Open the key settings

Navigate to **Settings → API Keys**.

### Generate the key

Click **Generate new key**.

### Copy it

Copy the key immediately — it is displayed only once.

> **Important**

Store your API key in a secure location such as an environment variable or secret manager. Never commit API keys to source control.

## Using your API key

Include the API key in the `Authorization` header of every request using the `Bearer` scheme:

```bash
curl https://api.watsi.ai/api/v1/conversations \
  -H "Authorization: Bearer YOUR_API_KEY"
```

If the key is missing or invalid, the API returns a `401 Unauthorized` response:

```json 401 Unauthorized
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Unauthorized"
  }
}
```

## API key scopes

Each API key is scoped to a single workspace. The key inherits the permissions of the user who created it and can access all resources within that workspace.

| Scope           | Access                                     |
| --------------- | ------------------------------------------ |
| `conversations` | List, read, and manage conversations       |
| `customers`     | List, read, create, and update contacts    |
| `messages`      | Send messages within open conversations    |
| `templates`     | List and manage WhatsApp message templates |
| `tags`          | Create, list, and assign tags to contacts  |
| `users`         | List workspace team members                |

## MCP authentication

The MCP server lives at a single endpoint and speaks **Streamable HTTP**, stateless. There is no `/sse` endpoint.

```http
POST https://mcp.watsi.ai/mcp
```

The same API key works for MCP connections. Clients that speak Streamable HTTP natively (Cursor, Windsurf, custom agents) take the URL and the header directly:

```json MCP client config
{
  "mcpServers": {
    "watsi": {
      "url": "https://mcp.watsi.ai/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}
```

Web clients that cannot send a custom header — Claude.ai and ChatGPT — use **OAuth 2.1 with Dynamic Client Registration** instead, which is live: add the URL as a custom connector, sign in to watsi, pick the workspace, and approve the scopes on the consent screen.

Tools are projected from the same action contract as these REST endpoints, so a scope means the same thing on both. Most of the catalog reads; a small set of agent-configuration tools writes (create an agent, update its configuration, add or remove knowledge, set the assignment policy, set member schedules, update the voice-calling config) and each needs an explicit `agents:write`, `knowledge:write` or `scheduling:write` scope.

> **Info**

The dashboard key picker does not offer those three (it does offer other write scopes such as `messages:write` and `contacts:write`), so a dashboard key can carry write scopes for messages and contacts but cannot change the agent configuration.

The authoritative catalog is the one the server publishes over `tools/list` after you connect — it is not pinned in this guide, because a tool whose backing service is not wired in an environment is withheld there rather than announced and failing. See the [MCP guide](/mcp) for the full setup.

## Security best practices

- **Rotate keys regularly** — generate a new key and revoke the old one periodically
- **Use environment variables** — never hardcode keys in application source code
- **Restrict server-side usage** — never expose API keys in client-side code or browser requests
- **Monitor usage** — review API key activity in the dashboard and revoke any keys you no longer need
- **Use HTTPS only** — all API requests must be made over HTTPS. Plain HTTP requests are rejected

## Rate limits

The API allows **100 requests per minute** per API key. When you exceed the limit, the API returns `429 Too Many Requests` with a `Retry-After` header indicating how many seconds to wait.

> **Tip**

See the [error handling guide](/error-handling) for retry strategies.
