Conventions
Pagination, error shapes, rate limits, and how the API is versioned and deprecated.
Rules that hold across every endpoint and every tool. Learn them once.
Pagination
Every list — REST endpoint or MCP tool — paginates the same way, with two optional parameters:
| Parameter | Default | Notes |
|---|---|---|
limit | 20 | Maximum items to return. Capped at 100. |
offset | 0 | Items to skip. offset: 20 with limit: 20 is the second page. |
The limit is a clamp, not a validation rule
Ask for limit: 10000 and you get 100 back — the maximum — not a 400. This
is deliberate, so an agent that guesses a large number gets useful results
instead of an error it has to recover from. Never assume you received everything
you asked for; read the response.
Every list response carries the numbers you need to page:
total— the count of matching items before pagination. Compare it againstoffset + returnedto know whether another page exists.limitandoffset— echoed back, so a client can compute the next request without tracking state.
curl https://api.passo.co/v1/workspaces?limit=20&offset=20 \ -H "Authorization: Bearer $PASSO_TOKEN"MCP tools take the same limit and offset arguments and return the same
total / limit / offset fields alongside their data.
Errors
REST
The REST API uses conventional HTTP status codes. The JSON body carries a
machine-readable code and a human-readable message:
{
"code": "NOT_FOUND",
"message": "No workspace with that id."
}| Status | Code | Meaning |
|---|---|---|
| 400 | BAD_REQUEST | The request was malformed. |
| 401 | UNAUTHORIZED | The token is missing, invalid, or expired. |
| 403 | FORBIDDEN | Authenticated, but not allowed to do this. |
| 404 | NOT_FOUND | The resource does not exist — or your account cannot see it. |
| 409 | CONFLICT | The change collides with existing state (e.g. a duplicate). |
| 422 | UNPROCESSABLE_CONTENT | The input was well-formed but failed validation. |
404 hides what you can't see
Because access is enforced by row-level security, a resource outside your scope is
indistinguishable from one that does not exist — both are 404. The API never
confirms the existence of something your account cannot access. See
Authentication.
MCP
MCP tools do not raise a JSON-RPC error for an expected failure. They return a
structured result the calling model can read and act on — a missing required
argument comes back as { "error": "invalid" }, an unreachable record as
{ "error": "not_found" }. This lets the agent ask you for the missing piece or
try another record, rather than hit an opaque protocol error it cannot interpret.
Genuine protocol problems (an expired token, a malformed call) still surface as
transport errors.
REST covers every resource; MCP tools are curated
The REST API exposes every brand resource operation. The MCP server does not mirror it one-for-one — a tool is a task an agent performs, not a row it fetches, so the tool set is hand-picked for agent workflows and is a subset of the REST surface by design.
Some operations are therefore REST-only, with no MCP tool. They are available as
/v1 endpoints but are deliberately not tools:
| Operation | REST endpoint | Why no tool |
|---|---|---|
| List invites | GET /v1/workspaces/{workspaceId}/invites | Invite admin housekeeping, not an agent task. |
| Revoke an invite | POST /v1/invites/{inviteId}/revoke | Admin housekeeping. |
| Resend an invite | POST /v1/invites/{inviteId}/resend | Admin housekeeping. |
| List a version's comments | GET /v1/video-versions/{versionId}/comments | Informational read; agents review via get_video_review. |
| Resolve a comment | PATCH /v1/comments/{commentId} | Thread bookkeeping, not an agent task. |
| List a video version's sign-offs | GET /v1/video-versions/{versionId}/signoffs | Informational read. |
| List a script version's sign-offs | GET /v1/script-versions/{versionId}/signoffs | Informational read. |
If you need one of these from an agent, call the REST endpoint directly with the same token. See MCP Tools for the full tool list.
Rate limits
There are no per-request rate-limit headers to parse today. Traffic is subject to
platform-level protection, not a published per-account quota. Formal limits, when
introduced, will be documented here and announced in the
changelog before they take effect. In the
meantime, be a good citizen: paginate rather than over-fetch, and cache stable
results like whoami instead of calling it on every turn.
Versioning and deprecation
The API is versioned in the path: REST lives under /v1, and the MCP endpoint is
/v1/mcp. Everything under a version is a stable contract.
- Additive changes are not breaking and can land at any time: new endpoints, new tools, new optional fields on a response. Write clients that ignore unknown fields, and a new field will never break you.
- Breaking changes get a new version. A changed or removed field, a renamed
tool, a different default — none of these happen in place under
/v1. They arrive under a new version so your integration keeps working. - Deprecations are announced first. Anything on a path to removal is called out in the changelog with a timeline, so you have notice before it goes.
Every change to the contract is recorded in the changelog — it is generated from the committed API spec, so it cannot silently drift from what the API actually does.