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

# Masker REST API: conventions, errors, and rate limits

> Complete reference for the Masker API: base URL, request conventions, pagination, error codes, rate limits, and versioning guarantees.

The Masker REST API is the same API that powers the portal. Anything you can do in the UI you can do over HTTP — create agents, list sessions, download compliance reports, and integrate the proxy into your voice pipeline. This page covers the conventions that apply to every endpoint.

## Base URL

```
https://masker-voice.fly.dev/api/v1
```

For self-hosted deployments, replace the hostname with your own. All paths below are relative to this base URL unless noted otherwise.

A small number of endpoints sit **outside** `/api/v1` because they're called by external systems with their own URL conventions:

| Endpoint                                     | Purpose                                                   |
| -------------------------------------------- | --------------------------------------------------------- |
| `POST /proxy/{agent_id}/v1/chat/completions` | OpenAI-compatible LLM proxy called by your voice platform |
| `POST /vapi/webhook/{agent_id}`              | Vapi assistant-request webhook                            |
| `GET /health`                                | Health check                                              |

## Conventions

* **JSON only.** All request and response bodies are `application/json` unless the endpoint explicitly returns another content type (e.g. `application/pdf` for report downloads).
* **UTF-8.** All strings are UTF-8 encoded.
* **ISO 8601 UTC** for all timestamps — for example, `2026-05-03T21:14:32.481Z`.
* **ULIDs** for resource IDs, prefixed by resource type: `agt_01HYZ...` for agents, `sess_01HYZ...` for sessions, `evt_01HYZ...` for events.
* **Snake\_case** for all request and response field names.
* **Meaningful HTTP status codes.** 2xx means success, 4xx means a problem with your request, 5xx means a problem on our end.

## Pagination

All list endpoints use **cursor-based pagination**. Pass `limit` and `cursor` as query parameters:

```bash theme={null}
curl "https://masker-voice.fly.dev/api/v1/sessions?limit=50&cursor=eyJ..."
```

<ParamField query="limit" type="number" default="25">
  Maximum number of results to return. Accepted range: 1–100.
</ParamField>

<ParamField query="cursor" type="string">
  Opaque pagination cursor returned in the previous response as `next_cursor`. Omit to start from the beginning.
</ParamField>

Every list response includes `next_cursor`. When it is `null` or absent, you have reached the last page:

```json theme={null}
{
  "data": [...],
  "next_cursor": "eyJ..."
}
```

Pass the value of `next_cursor` as `cursor` on the next request to retrieve the following page.

## Errors

All errors use a standard envelope:

```json theme={null}
{
  "error": {
    "code": "agent_not_found",
    "message": "No agent with id agt_01HYZ...",
    "request_id": "req_01HYZ..."
  }
}
```

Always log the `request_id` — it is the fastest way to diagnose an issue when contacting support.

| Code                | HTTP status | Meaning                                                      |
| ------------------- | ----------- | ------------------------------------------------------------ |
| `unauthenticated`   | 401         | No valid `masker_session` cookie                             |
| `forbidden`         | 403         | Authenticated but not permitted for this action              |
| `not_found`         | 404         | Resource does not exist or is not visible to your account    |
| `validation_failed` | 422         | Request body or query parameter failed validation            |
| `rate_limited`      | 429         | Too many requests; respect the `Retry-After` response header |
| `upstream_error`    | 502         | The upstream LLM provider returned an error                  |
| `internal_error`    | 500         | An error on our end; include `request_id` when reporting     |

## Rate limits

The hosted service enforces per-account limits:

| Endpoint group                   | Sustained limit | Burst limit |
| -------------------------------- | --------------- | ----------- |
| `/proxy/*` and `/vapi/webhook/*` | 100 req/s       | 200 req/s   |
| All other `/api/v1/*` endpoints  | 30 req/s        | 60 req/s    |

When you are rate-limited, the API returns `429` with a `Retry-After` header specifying how many seconds to wait before retrying. Self-hosted deployments have no rate limit applied by default.

## Versioning

The current API version is `v1`. Masker will not introduce breaking changes under `v1`. When `v2` ships, both versions will run in parallel for at least six months before `v1` is retired.

Backwards-compatible changes — new endpoints, new optional request fields, new optional response fields, new enum values — are added to `v1` without a version bump.

## Authentication

Every `/api/v1/*` endpoint requires a valid `masker_session` cookie. See [Authentication](/api-reference/authentication) for how to obtain and use it. The proxy and webhook endpoints use a separate mechanism described on their respective pages.
