Gyvar docs

Errors

One envelope, snake_case, and a stable machine-readable code you switch on.

Every error on /v1 renders the same shape:

{
  "status_code": 400,
  "message": "That network cannot be received on",
  "error": "Bad Request",
  "details": { "code": "unsupported_chain" }
}

details.code is the contract

message is prose written for a human reading a log, and it may be reworded at any time. details.code is stable. Switch on details.code and nothing else.

This is also why every authentication failure carries its own distinct code rather than a shared unauthorized. The difference matters at 2am: timestamp_skew tells your on-call their clock drifted, where a generic failure sends them to rebuild a canonical string that was fine all along.

Handle unknown codes as failures

The code set grows. A client that treats an unrecognised code as success will one day treat a refusal as a completed payment. Default to failure and alert.

Casing

Bodies on this surface are snake_case throughout, matching the webhook contract, because that is what your generated types expect. The first-party dashboard API uses camelCase - if you are reading both, they genuinely differ, and that split is deliberate rather than an oversight.

Retrying

ClassRetry?
4xx other than 429No. The request is wrong; retrying changes nothing.
409 address_limit_reachedNo. Talk to us.
429Yes, after the indicated delay.
503 service_unavailableYes, with exponential backoff and jitter.
5xxYes, with backoff. Where the operation is idempotent this is always safe.

Address creation is get-or-create on your reference, so retrying it after a timeout is safe by construction - you get the same address, never a second one.

On this page