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

# Choosing a surface

> Which endpoint or integration solves which problem.

Peeve exposes more than one way in. This page maps a goal to the right one so
you do not build against the wrong surface.

## By goal

| You want to                                            | Use                                                                                   | Auth                      |
| ------------------------------------------------------ | ------------------------------------------------------------------------------------- | ------------------------- |
| Put the agent in your app                              | [The widget script](/widget/install)                                                  | Publishable               |
| Tell Peeve who the signed-in user is, from the browser | [`identify`](/widget/identity-and-context)                                            | Publishable               |
| Tell Peeve who your users are, from your backend       | [`POST /v1/users`](/api/server/users/push-a-user)                                     | **Secret**                |
| Attach business context to a user                      | [`setContext`](/widget/identity-and-context) or the `attributes` field on `/v1/users` | Either                    |
| Stop Peeve serving, immediately                        | [`POST /api/killswitch`](/api/server/kill-switch/toggle-the-kill-switch)              | **Secret**                |
| Let Claude or Cursor discover your product             | [The MCP server](/mcp/overview)                                                       | None, or a per-user grant |
| Let a crawler or agent read your capability map        | [Agent artifacts](/artifacts/overview)                                                | Publishable, in the path  |

## The widget endpoints

The endpoints under `/api/*` are what the widget calls from your site. They are
documented in full under **API reference → Widget endpoints**, and you can call
them directly — they are publishable-key and origin gated, and they work from
any page on your domain.

Two things to know before you build on them:

<Warning>
  **They serve the widget first.** They are shaped around what the widget needs
  each turn, not around being a general-purpose REST API, and they change with
  the widget. If you build a custom surface on them, pin your expectations to
  the response fields you actually read and tolerate new ones appearing.
</Warning>

<Note>
  **Most of them fail open.** An unknown key, a disallowed origin, or a
  rate-limited request is answered with a harmless empty success rather than an
  error status, because a widget must never surface a console error inside a
  customer's app. That means a `200` does not always mean the call did
  something. Check the body — `stored`, `captured`, `show`, `ok` — not the
  status code. See [Errors](/reference/errors) for the per-endpoint table.
</Note>

## The agent loop, in one picture

If you are building your own surface rather than using the widget, this is the
shape of it.

```mermaid theme={null}
sequenceDiagram
    participant P as Your page
    participant A as Peeve
    P->>A: goal + page scan (elements, texts, url) + history
    A-->>P: 1-4 steps + done
    Note over P: Run the steps.<br/>A confirm step waits for the user.
    P->>P: Re-scan the page
    P->>A: same goal + fresh scan + updated history
    A-->>P: next steps, or done: true
```

Each turn is one request. You send the goal and a fresh scan of what is on
screen; Peeve returns the next one to four steps. The agent can only reference
elements you sent it — it cannot invent a target.

Writes are the part that matters. Any click on an element you marked
`write: true` comes back as a `confirm` step instead, and the batch stops
there. You show the confirmation, the user approves, and the next turn proceeds.
This is enforced on the server, so it holds whether or not the model cooperates.

## What is not documented here

* **Internal cron and admin routes** (`/api/cron/*`, `/api/admin/*`) — bearer-gated
  operational endpoints, not a customer surface.
* **Dashboard routes** — the dashboard uses server actions and cookie-authenticated
  routes such as `/api/search`. They are not an API and are not stable.
* **Connector OAuth callbacks** (`/api/connectors/*`) — driven by the dashboard's
  connect flows, not called directly.
* **Inbound webhook receivers** (`/api/webhooks/*`, `/api/stripe/webhook`) —
  configured by Peeve when you connect a channel. Not a customer surface.
