Skip to main content
Every JSON response from the Vestrapay API uses one of two envelopes. Learn them once and every endpoint, from initialise to splits to partners, reads the same way.

Success

Any HTTP 2xx response that has a body is wrapped like this:
The resource, or the result of the operation, is always inside the data property. Nothing meaningful is ever returned at the top level beside status and data. Initialise returns HTTP 201, verify returns HTTP 200, and operations that create something generally return 201. Money is always a string in major units, such as “100.00”. Timestamps are ISO 8601 in UTC, such as “2026-05-10T14:30:00.000Z”.

Lists and pagination

List endpoints put their rows inside data too. Depending on the endpoint, data is either an array or an object with the rows next to a meta object that describes paging. For example, listing sub-accounts returns:
Paged endpoints accept page and pageSize query parameters. pageSize is capped at 100. Always read the shape from the endpoint’s page rather than assuming one.

No-content responses

Some operations return HTTP 204 with no body. Deleting a service, deleting a sub-account and resending a partner invitation all behave this way. Do not try to parse a body from a 204.

Failure

When a request fails, the body is:
Some failures carry extra context alongside these fields, such as a hint or a details object. Treat unknown fields as optional. The HTTP status code tells you the class of problem (400 validation, 401 credentials, 403 permission, 404 not found, 409 conflict, 410 expired, 5xx server or processor), and the error code tells you exactly which problem. Every response includes an X-Request-Id header. Log it with every call, and include it when you contact tech@vestrapay.com. It is the fastest way for the team to trace a specific request. See Errors for the catalogue of codes and what to do about each.

Two kinds of status

Two different fields are called status, and mixing them up is a common source of bugs.
  • The outer status says whether the HTTP call worked. It is success or failed.
  • The payment status lives inside data and says where the payment is in its life cycle.
Checkout charge calls are the clearest example. They return HTTP 201 and an outer status of success even when the card was declined, because the call itself worked. The outcome is in data.status:
On verify, data.status takes the values pending, processing, success, failed and abandoned. Only success means paid.

Responses that are not wrapped

A few responses deliberately fall outside the envelope.
  • Webhook bodies are posted to your server as { "event", "data", "timestamp" } with no outer status. See Webhooks.
  • Checkout events at /v1/payment/checkout/events are a server-sent event stream, not JSON responses.
  • CSV exports of settlements return a file attachment.
  • 204 responses have no body.

Which credential each call needs

Merchant session endpoints also check the signed-in user’s permissions for the relevant dashboard area. A user without access to that area receives a 403.