Requests and responses

Methods, the response envelope, headers, timestamps and caching rules shared by every endpoint.

Requests

  • Read with GET. The write endpoints take POST, PATCH, PUT and DELETE. A method a path doesn't take answers 404.
  • Send a write's body as JSON, with Content-Type: application/json, up to 1 MB.
  • Send X-API-Key on every request (Authentication).
  • Responses are gzip-compressed when you send Accept-Encoding: gzip. Most HTTP clients do this by default.
  • Timestamps are ISO 8601 in UTC, for example 2026-03-18T10:22:05.117Z. Columns that store only a date are serialized as midnight UTC.
  • Field names are Vitruve's own and are never renamed.

The envelope

Every response, success or error, has the same top level.

FieldTypePresentDescription
okbooleanalwaystrue on success, false on any error.
timestampnumberalwaysServer time in Unix milliseconds.
dataobject or arraysuccessA single resource, or the items of a list.
metaobjectlistsPagination state. See Pagination.
messagestringerrorsHuman-readable description of what went wrong.

A single resource

{
  "ok": true,
  "timestamp": 1738247125207,
  "data": { "id": "3b9c1e24-6f7a-4d2b-8c15-a40e9d7f1b62", "name": "Marta" }
}

A list

{
  "ok": true,
  "timestamp": 1738247125207,
  "data": [{ "id": "3b9c1e24-6f7a-4d2b-8c15-a40e9d7f1b62", "name": "Marta" }],
  "meta": { "limit": 50, "hasMore": true, "nextCursor": "ZTU2M2ZlYzMtM2Ix…" }
}

An error

{
  "ok": false,
  "timestamp": 1738247125207,
  "message": "Invalid query parameters: 'limit': Number must be less than or equal to 100"
}

Branch on the HTTP status and ok, not on the text of message. Messages are written for people and can be reworded. See Error codes.

Response headers

HeaderMeaning
X-Request-IdUnique id of the request. Include it when you contact support.
RateLimit-Limit, RateLimit-Remaining, RateLimit-ResetYour current rate-limit window, on every response past the key check. See Rate limits.
Retry-AfterOn 429 only: seconds to wait.
Idempotent-Replayed: trueOn a create retried with the same Idempotency-Key: the answer is the one kept from the first request. See Writes.
Cache-Control: private, no-storeResponses contain one organization's private data. Do not cache them in shared caches.

Nulls, missing fields and optional data

Nullable columns are returned as null, not omitted. A field you do not see in the reference is not part of the contract: ignore unknown fields so your integration keeps working when new ones appear.

On this page