# API conventions

The HTTP API on https://webmcp.fast is small. The daemon uses it to pair a device, agents use the management MCP endpoint, and OAuth clients register themselves. The machine-readable description is [https://webmcp.fast/openapi.json](https://webmcp.fast/openapi.json) (OpenAPI 3.1); this page states the rules that hold across all of it.

## Start without an account or a key

Nothing here needs a pre-issued API key, and the first call needs no account.

- `POST https://webmcp.fast/api/v1/device/start` is anonymous. It returns `verification_uri_complete`, the one link a human opens to sign in (which creates the free account) and approve the device. Then poll `POST https://webmcp.fast/api/v1/device/poll`. This is what `webmcp up` does.
- `POST https://webmcp.fast/oauth/register` registers an OAuth client immediately (RFC 7591), with no approval step. See [auth.md](https://webmcp.fast/auth.md).
- `POST https://webmcp.fast/mcp` offers `check_handle`, `start_setup`, `setup_status` with no credential.
- `POST https://webmcp.fast/agent/identity` registers a shell-less agent anonymously (the auth.md profile); `POST https://webmcp.fast/agent/identity/claim` starts the ceremony in which the user claims it with a 6-digit code, unlocking read-only `manage` access. See [auth.md](https://webmcp.fast/auth.md).

The free tier (1 handle, 1 device, 1 server, 1 connector) is what you get. See [pricing](https://webmcp.fast/pricing).

## Versioning

The version is in the path: `/api/v1`. Every response under `/api/` carries an `API-Version: 1` header. Within a version, changes are additive only: new operations, new optional request fields, new response fields, new error codes. Clients must ignore fields they do not know. Anything that would break a correct client ships under a new path (`/api/v2`) while `/api/v1` keeps working.

The discovery documents under `/.well-known/`, the management MCP endpoint and the OAuth endpoints follow their own specifications and are versioned by those.

## Deprecation and sunset policy

- An operation or version that will be retired is announced **at least 6 months** before it stops working.
- From the announcement on, its responses carry a `Deprecation` header (RFC 9745) with the date it was deprecated and a `Sunset` header (RFC 8594) with the date it will be removed, plus a `Link` header with `rel="deprecation"` pointing at this page.
- The announcement is recorded in the changelog below and in the `x-deprecation-policy` block of the OpenAPI document, and account holders are told by email.
- After the sunset date the operation answers `410` with the usual JSON error body.

Nothing is deprecated today.

## Rate limits

Limits are per client IP, in fixed windows. Rate-limited operations report where you stand on every response, not only on refusal:

| Header | Meaning |
|---|---|
| `RateLimit-Policy` | The quota, for example `"device-start";q=10;w=900` (10 requests per 900 seconds) |
| `RateLimit` | What is left, for example `"device-start";r=9;t=412` (9 remaining, resets in 412 seconds) |
| `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` | The same three numbers for clients that read the older names. Reset is in seconds |
| `Retry-After` | On `429` only: seconds to wait |

| Operation | Limit |
|---|---|
| `POST /api/v1/device/start` | 10 per 15 minutes |
| `POST /api/v1/pair` | 20 per 15 minutes |
| `POST /agent/identity` | 10 per hour |
| `POST /agent/identity/claim` | 30 per 15 minutes, and 10 per registration |
| `POST /oauth/token` with the agent-auth grants | 120 per 15 minutes |
| Requests to `/api/` paths that match no operation | 60 per minute |

On `429`, wait `Retry-After` seconds and try again. Do not retry faster. Relayed MCP calls on a user's own endpoint are not metered for cost, only limited against abuse.

## Errors

Every error under `/api/` and `/agent/` is JSON, whatever the status: unknown paths (`404`), wrong methods (`405` with an `Allow` header), bad bodies (`400`), rate limits (`429`) and server faults (`5xx`).

```
{
  "error": "code_not_found",
  "message": "That pairing code is unknown, expired or already used.",
  "hint": "Create a new code on the dashboard, or run `webmcp up`, which needs no code.",
  "docs": "https://webmcp.fast/docs/api"
}
```

`error` is a stable machine code: match on it, never on `message`. `hint` says what to do next. The codes:

- `not_found`: No API operation exists at this path.
- `method_not_allowed`: This operation does not support that HTTP method.
- `invalid_request`: The request body is malformed or a field is missing or invalid.
- `unsupported_media_type`: The request body must be JSON.
- `rate_limited`: Too many requests from this address in the current window.
- `code_not_found`: That pairing code is unknown, expired or already used.
- `device_name_taken`: Another device on this handle already has that name.
- `device_limit`: The plan allows no more devices on this handle.
- `hardware_already_paired`: This machine is already paired to another free handle.
- `authorization_pending`: The human has not approved the device yet.
- `slow_down`: Polling faster than the allowed interval.
- `access_denied`: The human declined to approve this device.
- `expired_token`: This device authorization has expired or was already used.
- `anonymous_not_enabled`: Anonymous agent registration is not enabled on this server.
- `service_auth_not_enabled`: The service_auth registration type is not offered here.
- `issuer_not_enabled`: No external identity provider is trusted for identity_assertion registration.
- `invalid_claim_token`: That claim_token is unknown, revoked or malformed.
- `claimed_or_in_flight`: This registration has already been claimed.
- `claim_expired`: The registration's claim window (24 hours) has closed.
- `internal_error`: The gateway failed to handle the request.

The management MCP endpoint answers with JSON-RPC 2.0 error objects instead, as MCP requires, and the OAuth endpoints with RFC 6749 error objects.

## Changelog

- 2026-09-21: auth.md agent registration: `POST /agent/identity`, `POST /agent/identity/claim`, the `jwt-bearer` and `claim` grants at `/oauth/token`, and RFC 7009 revocation of `wma_` tokens. Additive.
- 2026-09-21: `/api/v1` documented. Added RateLimit headers, `hint` and `docs` on every error, `405` with `Allow`, and the `API-Version` header. No breaking changes.

## Related

[OpenAPI](https://webmcp.fast/openapi.json), [API catalog](https://webmcp.fast/.well-known/api-catalog), [auth.md](https://webmcp.fast/auth.md), [agent-driven setup](https://webmcp.fast/docs/agents), [security model](https://webmcp.fast/docs/security-model).
