# Wake API

> Read what agents did on your site, where they got stuck, what to fix and how the listing is going. Base URL `/api/wake/v1`. Auth: `Authorization: Bearer wk_live_…`. Machine description at [`/api/wake/v1/openapi.json`](/api/wake/v1/openapi.json).

## Authentication

Mint a key on your desk under **Connect your AI** (up to 10 active keys per desk; shown once; stored hashed; revoke any time). Send it as a bearer token:

```bash
curl -H "Authorization: Bearer wk_live_…" "https://agent-observatory-desk-production.up.railway.app/api/wake/v1/overview?window=7d"
```

A key reads exactly one desk (one host). Limits: 120 requests per minute per key.

## Windows

`window` is `24h`, `7d` (default) or `30d`. `24h` buckets by hour, the others by day.

## Endpoints

| Method and path | Returns |
|---|---|
| `GET /` | API index (no auth). |
| `GET /openapi.json` | OpenAPI 3.1 (no auth). |
| `GET /me` | Host, verification, collector status, key label, MCP and docs URLs. |
| `GET /overview?window=` | Events, sessions, unique agents, conversions, friction, by provider / class / intent / country, the funnel, top friction. |
| `GET /agents?window=` | One row per nickname: sessions, events, stage reached, converted, friction types, intents. |
| `GET /sessions?window=&limit=&nickname=` | Session rows, newest first (limit ≤ 500). |
| `GET /sessions.csv?window=` | The same as CSV. |
| `GET /funnel?window=` | Cumulative stages with share and drop, biggest drop. |
| `GET /friction?window=` | Friction tally by kind and page class, with the fixes it implies. |
| `GET /fixes?window=` | Ranked fixes with evidence, plus readiness recommendations (verified desks). |
| `GET /alerts?window=` | Changes versus the previous window. |
| `GET /series?window=` | Time buckets of events, sessions, agents, friction sessions, conversions. |
| `GET /pages?window=` | Page classes touched and the most common sequences. |
| `GET /readiness` | The public site as an agent sees it: scores, recommendations, probe, publish-ready files. Verified desks. |
| `GET /listing` | AEO plan, step status, arrivals (identified vs crawler), trial. |
| `POST /listing/plan` | Prepare the listing plan (never publishes). Verified desks. |
| `GET /benchmarks` | k-anonymous cohort medians, withheld below k=5. |
| `GET /install` · `?kit=1` | Collector status; with `kit=1` the deploy-ready files (verified desks). |
| `POST /mcp` | MCP endpoint, see [MCP](/wake/docs/mcp). |

## Public, no key

| Method and path | Returns |
|---|---|
| `GET /public/readiness?host=` | Readiness of any public host: scores, recommendations, publish-ready files. 20 requests per minute per address. |
| `GET /public/about` | What Wake is, with links. |
| `POST /public/mcp` | Public MCP server with `wake_check_site` and `wake_about`. Listed on Smithery as `wake-site-readiness`. |

## Shapes

A session row:

```json
{
  "nickname": "ax_1a1IT2kn",
  "provider": "anthropic",
  "agent_class": "declared_ai",
  "started_at": "2026-10-29T04:37:00.000Z",
  "ended_at": "2026-10-29T04:41:12.000Z",
  "duration_ms": 252000,
  "event_count": 6,
  "stage": "attempted_action",
  "intent": "Call the API / integrate",
  "inferred": true,
  "converted": false,
  "friction": [{ "type": "action_unauthorized", "path_class": "api", "detail": "2 failed api requests (status 401) with no success." }],
  "path_classes": ["docs", "docs", "api", "api", "auth", "api"]
}
```

Friction kinds: `auth_wall`, `action_unauthorized`, `action_rejected`, `action_server_error`, `repeated_error`, `abandoned_on_error`, `docs_dead_end`. Intent is a labelled inference with a confidence, never a claim about what the remote agent meant.

## Errors

JSON `{ "error": "…", "code": "…" }`:

| Status | code | Meaning |
|---|---|---|
| 401 | `unauthorized` | Missing, unknown or revoked key. |
| 403 | `unverified` | The desk has not verified ownership of the host. |
| 404 | `not_provisioned` / `not_found` | No collector yet, or unknown route. |
| 429 | `rate_limited` | More than 120 requests in a minute for this key. |

## Privacy

Every answer is coarse by construction: daily HMAC nicknames, page classes, status codes, operator families, country codes. There is no raw IP, user-agent, query, body, cookie or referrer anywhere in the store, so none can be returned. See [Privacy](/wake/docs/privacy).
