Zopping

Responses & errors

Every call through the gateway returns the same envelope. Learn it once.

The envelope

{
  "code": 200,
  "status": "SUCCESS",
  "data": {},
  "meta": {}
}
FieldMeaning
codeHTTP status, echoed in the body
statusSUCCESS or ERROR
datathe payload — present on success
messagehuman-readable text — present on error
metaoptional extra info (e.g. pagination on some endpoints)

Reading the examples in this portal. Reference and guide examples show the contents of data (the part you care about). The full response wraps that in the envelope above. So when an example shows { "product": [...] }, the wire response is { "code": 200, "status": "SUCCESS", "data": { "product": [...] } }.

Inside data

The shape of data depends on the resource:

  • A single record is keyed by the resource name: data: { "product": { ... } }.
  • A list is the keyed array plus paging counters: data: { "product": [ ... ], "count": 42, "offset": 0, "limit": 20 }.

Some services key the list as data itself or use slightly different paging keys — each reference page shows the exact shape. See Pagination, limits & versioning for the conventions and the known inconsistencies.

Errors

Errors return a non-2xx code, status: "ERROR", and a message:

{
  "code": 403,
  "status": "ERROR",
  "message": "Forbidden"
}
CodeMeaningWhat to do
400Bad request / validationFix the payload; read message
401Missing/invalid tokenCheck the Authorization header
403Not granted this resource/methodAsk for the RBAC grant
404Unknown route, or record not in your orgCheck the path and organizationId
409Conflict (e.g. duplicate)Look up by clientId and update instead
429Rate limitedBack off and retry (see rate limits)
5xxServer errorRetry idempotently with backoff

Retrying safely

For writes, make retries idempotent: set your own clientId on creates so a retried create updates the existing record instead of duplicating it. Match payments/refunds on transactionId / gatewayTransactionId.

Next