Passo Developers

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:

ParameterDefaultNotes
limit20Maximum items to return. Capped at 100.
offset0Items 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 against offset + returned to know whether another page exists.
  • limit and offset — 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."
}
StatusCodeMeaning
400BAD_REQUESTThe request was malformed.
401UNAUTHORIZEDThe token is missing, invalid, or expired.
403FORBIDDENAuthenticated, but not allowed to do this.
404NOT_FOUNDThe resource does not exist — or your account cannot see it.
409CONFLICTThe change collides with existing state (e.g. a duplicate).
422UNPROCESSABLE_CONTENTThe 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.

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.

On this page