# Which surface to use

> The four ways to connect your system to watsi — the REST API, the MCP server, webhooks and the website widget — and when each one fits.

Source: https://docs.watsi.ai/en/api/overview

watsi exposes the same capabilities through several doors. All of them read and write **one workspace**, the one your credential belongs to, and all of them come from the same contract: an action defined once is published as a REST route and as an MCP tool at the same time, with the same scopes.

| You want to…                                                                     | Use                   | Credential                        |
| -------------------------------------------------------------------------------- | --------------------- | --------------------------------- |
| Have your backend read or write data (contacts, conversations, analytics)        | [REST API](#rest-api) | API key `wats_live_…`             |
| Let an AI assistant (Claude, ChatGPT, Cursor) query your workspace               | [MCP server](/mcp)    | API key or OAuth 2.1              |
| Find out as soon as something happens (new message, booked appointment, handoff) | [Webhooks](/webhooks) | An HTTPS endpoint watsi registers |
| Put the agent’s chat on your website                                             | Website widget        | Configured in the app             |

## REST API

```http
https://api.watsi.ai/v1/actions/<domain>/<verb>
```

Every route is an **action**: `GET` to read (parameters go in the query string) and `POST` to write (JSON body). All of them authenticate with `Authorization: Bearer <your key>` and require one or more [scopes](/guides/authentication#scopes). Responses are JSON; errors always look like `{ "error": { "code", "message" } }`.

- [Quickstart](/quickstart)
    Your first call in five minutes.
- [Authentication](/guides/authentication)
    Keys, scopes and limits.
- [Pagination](/guides/pagination)
    How each route pages.
- [Errors](/error-handling)
    Codes, retries and idempotency.

### Every route

This table is generated from the action contract when the site is built, so it cannot fall behind what the server mounts. The **Idempotency-Key** column marks the writes that accept that header ([idempotency](/api/idempotency)).

| Method | Path | Scopes | Idempotency-Key |
| --- | --- | --- | --- |
| `POST` | `/v1/actions/agents/assignment` | `agents:write` | — |
| `GET` | `/v1/actions/agents/config` | `agents:read` | — |
| `POST` | `/v1/actions/agents/create` | `agents:write` | Yes |
| `POST` | `/v1/actions/agents/knowledge` | `knowledge:write` | Yes |
| `POST` | `/v1/actions/agents/knowledge/delete` | `knowledge:write` | Yes |
| `GET` | `/v1/actions/agents/list` | `agents:read` | — |
| `POST` | `/v1/actions/agents/update` | `agents:write` | Yes |
| `GET` | `/v1/actions/analytics/agent-performance` | `analytics:read` | — |
| `GET` | `/v1/actions/analytics/escalations` | `analytics:read` | — |
| `GET` | `/v1/actions/analytics/lead-attribution` | `analytics:read` | — |
| `GET` | `/v1/actions/analytics/overview` | `analytics:read` | — |
| `GET` | `/v1/actions/analytics/profiling-report` | `analytics:read` | — |
| `POST` | `/v1/actions/attachments/create-upload` | `agents:write` | Yes |
| `POST` | `/v1/actions/attachments/finalize` | `agents:write` | Yes |
| `POST` | `/v1/actions/attachments/import-url` | `agents:write` | Yes |
| `GET` | `/v1/actions/billing/credit-usage` | `billing:read` | — |
| `GET` | `/v1/actions/billing/payment-history` | `billing:read` | — |
| `GET` | `/v1/actions/billing/status` | `billing:read` | — |
| `POST` | `/v1/actions/contacts/create` | `contacts:write` | Yes |
| `GET` | `/v1/actions/contacts/list` | `contacts:read` | — |
| `GET` | `/v1/actions/conversations/get` | `conversations:read` | — |
| `GET` | `/v1/actions/conversations/list` | `conversations:read` | — |
| `POST` | `/v1/actions/conversations/status` | `conversations:write` | — |
| `POST` | `/v1/actions/crm/tags` | `crm:write` | Yes |
| `POST` | `/v1/actions/crm/tags/remove` | `crm:write` | Yes |
| `POST` | `/v1/actions/lifecycle/attach-file` | `lifecycle:write` | Yes |
| `GET` | `/v1/actions/lifecycle/case-file` | `lifecycle:read` + `billing:read` | — |
| `POST` | `/v1/actions/lifecycle/record-call` | `lifecycle:write` | — |
| `POST` | `/v1/actions/lifecycle/step` | `lifecycle:write` | — |
| `GET` | `/v1/actions/lifecycle/transcript` | `lifecycle:read` | — |
| `GET` | `/v1/actions/messages/search` | `conversations:read` | — |
| `GET` | `/v1/actions/resources/get` | `resources:read` | — |
| `GET` | `/v1/actions/resources/list` | `resources:read` | — |
| `POST` | `/v1/actions/scheduling/member-schedules` | `scheduling:write` | — |
| `GET` | `/v1/actions/templates/search` | `templates:read` | — |
| `GET` | `/v1/actions/voice/calls` | `agents:read` | — |
| `GET` | `/v1/actions/voice/config` | `agents:read` | — |
| `POST` | `/v1/actions/voice/config` | `agents:write` | Yes |
| `GET` | `/v1/actions/voice/diagnose` | `agents:read` | — |
| `GET` | `/v1/actions/workspace/integrations` | `integrations:read` | — |
| `GET` | `/v1/actions/workspace/members` | `workspace:read` | — |
| `GET` | `/v1/actions/workspace/settings` | `workspace:read` | — |

> **Note**

The `lifecycle/*` routes serve watsi’s own customer-success process and require scopes only watsi issues. You don’t need them to integrate.

## MCP server

`https://mcp.watsi.ai/mcp` speaks the Model Context Protocol over Streamable HTTP. Every MCP tool is one of the actions above, with the same scope; the MCP server has nothing the REST API lacks. Use it when the caller is a model rather than your code. [MCP server guide](/mcp).

## Webhooks

watsi sends a `POST` to your HTTPS endpoint when an event happens: an inbound message, an assigned conversation, a booked appointment, an agent action. The watsi team registers endpoints for you. [How they work](/webhooks) · [Event catalog](/webhooks/events).

## Website widget

The agent’s chat on your site is installed with a snippet you copy from **Integrations** in the watsi app; it needs neither the API nor a key.
