Salfio
API

Conventions

Response envelope, error format, and cursor pagination.

Every /v1 response follows the same shape, regardless of resource. Once you've integrated one endpoint, you've integrated all of them.

Response envelope

Successful responses wrap the payload in data and carry pagination hints in meta:

{
  "data": { "status": "ok" },
  "meta": {
    "cursor": null,
    "hasMore": false
  }
}
  • data — the resource or list of resources. Never null on success.
  • meta.cursor — opaque string; pass it to the next request to continue paginating. null when there's no next page.
  • meta.hasMoretrue if more pages exist.

Errors

Errors return a structured body regardless of HTTP status:

{
  "error": {
    "code": "unauthorized",
    "message": "Missing or invalid Bearer token.",
    "details": {}
  }
}
  • code — stable machine-readable identifier ("unauthorized", "not_found", "rate_limited", "invalid_argument", etc.). Safe to switch on.
  • message — human-readable string. Good for logs; not safe to show verbatim in end-user UIs without translation.
  • details — optional, per-code. For validation errors, contains a field-keyed map of specifics.

Common HTTP statuses:

StatusMeaning
200Success
400Invalid request (body shape, missing required fields)
401Missing / invalid / revoked token
403Authenticated but not authorized (User key without permissions)
404Resource does not exist, or belongs to another organization
409State conflict (exceeded a limit, duplicate)
429Rate limit exceeded (Rate limits)
5xxServer error — treat as retryable with backoff

Pagination

List endpoints accept two query parameters:

  • limit — integer, default 20, max 100. Values above 100 are clamped silently.
  • cursor — opaque string from a previous response's meta.cursor. Omit on the first request.

Pagination is forward-only and cursor-based — there are no page numbers. The cursor encodes sort position; it is stable across new records being added.

GET /v1/clients?limit=50
GET /v1/clients?limit=50&cursor=eyJpZCI6MTIzfQ

When meta.hasMore is false, stop paginating.

Multi-tenancy

Every request is scoped to the organization that owns the Bearer key. Objects that belong to a different organization return 404 (not 403) — Salfio does not leak the existence of other orgs' data.

On this page