# Auth.md

This page explains how to authenticate against the Boei REST API. It is written for developers and AI agents. Product overview: https://boei.help/llms.txt. Developer resources: https://boei.help/developers/.

## Discover

- Base URL: `https://app.boei.help/api/v1`
- Authentication method: API key sent as a Bearer token
- Header: `Authorization: Bearer sk_live_...`
- Transport: HTTPS only
- Format: JSON requests and JSON responses
- OpenAPI 3.0 specification: https://boei.help/openapi.json (YAML: https://boei.help/openapi.yaml)
- Interactive reference: https://app.boei.help/docs/api

For REST requests, every request uses a static API key that belongs to a Boei user account. The MCP server at `https://app.boei.help/mcp` uses OAuth 2.1; its authorization-server metadata is at https://app.boei.help/.well-known/oauth-authorization-server and its protected-resource metadata is at https://app.boei.help/.well-known/oauth-protected-resource.

## Pick a method

- Use a Bearer API key for scripts, server-to-server integrations, imports and syncs against `/api/v1`.
- Use OAuth 2.1 through the MCP server when Claude, ChatGPT, Cursor or another agent acts on behalf of a signed-in Boei administrator.

## Register

1. Sign in to the Boei dashboard at https://app.boei.help.
2. Open the account menu (top right) and choose **API Keys**, or go to https://app.boei.help/api-keys.
3. Click **Create API key**, give it a name, and copy the key. Keys start with `sk_live_`.
4. Store the key in a secret manager. Boei only shows the full key once; afterwards it is masked.

Requirements:

- API access is included on the Growth, Business, and Scale plans. Starter and trial accounts receive a `403 api_access_disabled` response.
- Only account owners and admins can create keys. Collaborators cannot.
- A user can create several keys, for example one per integration. Delete a key on the same page to revoke it immediately.

MCP clients register dynamically at `https://app.boei.help/oauth/register`. They discover this endpoint from the authorization-server metadata and must use PKCE with `S256`.

## Claim

- A REST API key inherits the account and permissions of the user who created it.
- An MCP client asks the signed-in administrator to approve the `mcp` scope. The resulting credential is limited to accounts that administrator may access.

## Exchange

REST API keys are ready to use and are not exchanged. MCP clients exchange the authorization code at `https://app.boei.help/oauth/token`; follow the authorization-server metadata rather than hard-coding the flow.

## Use credential

Send the key in the `Authorization` header on every request:

```bash
curl https://app.boei.help/api/v1/chatbots \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Accept: application/json"
```

Example response:

```json
{
  "data": [
    { "id": "abc123", "name": "Support bot", "created_at": "2026-01-15T10:22:00Z" }
  ]
}
```

## Permissions and scope

- A key inherits the permissions of the user who created it and can reach every chatbot, contact, deal, and inbox thread that user can access in the dashboard.
- Keys are not scoped per resource or per action yet. Create a separate key per integration so you can revoke one without affecting the others.
- Agency accounts: a key created by the agency owner can access sub-accounts the owner can access.

## Rate limits

- Default: 60 requests per minute per API key.
- Higher limits are available on request via https://boei.help/contact/.
- When the limit is exceeded the API returns HTTP `429` with a JSON body and a `Retry-After` header. Back off and retry after the indicated number of seconds.

## Errors

All errors are JSON objects with an `error` code and a human-readable `message`.

| HTTP status | Body | Meaning |
|---|---|---|
| 401 | `{"error": "unauthorized", "message": "..."}` | No `Authorization: Bearer` header was sent |
| 401 | `{"error": "invalid_api_key", "message": "..."}` | The key does not exist or was revoked |
| 403 | `{"error": "api_access_disabled", "message": "..."}` | The account plan does not include API access |
| 404 | `{"message": "Resource not found."}` | The resource does not exist or belongs to another account |
| 422 | `{"message": "...", "errors": {"field": ["..."]}}` | Request body failed validation; `errors` lists the fields |
| 422 | `{"error": "no_training_data", "message": "..."}` | The chatbot has no trained content yet |
| 429 | `{"error": "rate_limited", "message": "..."}` or `{"message": "Too Many Attempts."}` | Rate limit exceeded; honour `Retry-After` |

Example:

```json
{
  "error": "invalid_api_key",
  "message": "Invalid API key"
}
```

## Public endpoint without a key

`POST /api/v1/chatbots/{chatbot_id}/reply` generates an AI draft reply for an email thread using the chatbot's knowledge. It does not require an API key; the chatbot UUID in the URL is the only identifier, and it is rate limited. Each reply consumes AI credits from that chatbot's account. See the OpenAPI spec for the request shape.

## Webhooks

Boei can push events (new leads, new conversations, handoffs) to your own HTTPS endpoint. Webhook URLs are configured in the Boei dashboard (several URLs can receive the same event) and are not authenticated with your API key. Details: https://boei.help/integrations/webhooks/.

## Revocation

- REST API: delete the key under **API Keys**. It stops working immediately.
- MCP: disconnect the server in the client. To force-revoke an active connection, contact support at https://boei.help/contact/.

## Security notes

- Never embed an API key in client-side code or in a public repository.
- Rotate keys by creating a new one, switching your integration, then deleting the old one.
- Report security issues via https://boei.help/security/.

## Machine-readable discovery

- OpenAPI: https://boei.help/openapi.json
- API catalog (RFC 9727): https://boei.help/.well-known/api-catalog
- Agentic Resource Discovery catalog: https://boei.help/.well-known/ard.json
- Pricing: https://boei.help/pricing.md
