---
name: wilmo-api
description: Use Wilmo's public API (REST /api/v2, MCP, the wilmo CLI) to read a customer-support organization's tickets, conversations, teams and reporting. Use when an integration, a script or an agent needs Wilmo data, when a request to app.wilmo.ai fails, or when choosing between a key, OAuth, MCP and the CLI.
---

# Wilmo API

One operation, every surface: each Wilmo operation is at once a REST endpoint, an MCP tool
and a CLI command, with the same input and output. Names say what the rows are, never whose:
your key or grant decides whose rows come back.

```text
REST   https://app.wilmo.ai/api/v2/<resource>        e.g. GET /api/v2/tickets
MCP    https://app.wilmo.ai/api/mcp                   tool list_tickets (<keyword>_<resource>)
CLI    npx @wilmo/cli tickets list                    the same tool
DOCS   https://app.wilmo.ai/api/public/v1/openapi     OpenAPI 3.1, every public operation

TODAY (tools/list and the OpenAPI document list yours)
REST                                       MCP tool / OpenAPI operationId
GET /api/v2/teams                          list_teams
GET /api/v2/tickets                        list_tickets
GET /api/v2/tickets/{ticket_id}            get_ticket
GET /api/v2/ticket-counts                  get_ticket_counts
GET /api/v2/dashboards                     list_dashboards
GET /api/v2/reports/{report_id}/results    get_report_results
GET /api/v2/metrics/autopilot              get_autopilot_metrics
GET /api/v2/ticket-analytics               get_ticket_analytics
GET /api/v2/skills                         list_skills
GET /api/v2/tags                           list_tags
```

## Authenticate

```text
team API key          Settings > API keys             one team               REST + MCP
organization key      Settings > Connected apps       every team of ONE org  REST + MCP
OAuth (Claude, CLI)   "Sign in with Wilmo"            every team of one org  MCP
                      an organization admin consents; read-only
```

Send `Authorization: Bearer <key or token>`. Never put a key in a URL.

## Discover what you may call

- Your operations: MCP `tools/list`, or `GET /api/public/v1/openapi` with your key as Bearer
  (it lists the ones your scopes and your organization's enabled features allow).
- Map a market or brand to a team first: `GET /api/v2/teams` (MCP `list_teams`).

## Headers

```text
Wilmo-Version: 2026-11-06     shape requests and responses for this version (pin it in code)
Wilmo-Organization: <uuid>    which organization, for a principal in several
Idempotency-Key: <uuid>       on POST/PUT/PATCH/DELETE: a retry returns the first response
Request-Id (response)         quote it when asking Wilmo for help
```

## Responses

```text
200/201  the object itself (null when the operation returns nothing, e.g. a delete)
         a list: { "object": "list", "data": [...], "has_more": true, "next_cursor": "..." }
         next page: the same request with cursor=<next_cursor>; stop when has_more is false
         a list that takes offset (its next_cursor is always null): offset=<offset + data.length>
         while has_more is true; total_count is every row
202      accepted: the work was queued; the body says what to follow (a job or run id)
204      done, no body
4xx/5xx  { "error": { "type", "code", "message", "param", "request_id", "doc_url" } }
```

`error.message` is one short sentence saying what to fix. Act on `code`, not on the text:

```text
invalid_input / invalid      fix error.param and resend
authentication_required      send a valid key or token
forbidden / permission_*     the key lacks the scope, or the person is not an admin
not_found                    it does not exist, is not yours, or its id is malformed: do not retry
rate_limited                 wait Retry-After seconds, then retry
idempotency_conflict         a different request reused the key: use a new key
api_error (5xx)              retry with the same Idempotency-Key, with backoff
```

## Rate limits

MCP: 300 requests per 10 minutes per grant or key, 1,500 per organization. REST: per key, per
team and per customer. A 429 carries `Retry-After`.

## Versions

Every key and grant is pinned to the API version of the day it was created. Breaking changes ship
only in a new dated version; see the wilmo-api-migrations skill and
https://app.wilmo.ai/api/public/v1/api-versions.
