Documentation Index Fetch the complete documentation index at: https://developers.bloobank.com/llms.txt
Use this file to discover all available pages before exploring further.
This is the authoritative reference for error.status (and error.details[].reason) values returned by the BlooBank Transactions Engine API. Branch on these in your client code; they are stable and additive.
For the envelope structure, see Errors overview . For the full normative contract, see the Errors reference .
Authentication (HTTP 400/401)
These fire before any business logic runs — fix the request signing.
Reason HTTP What it means What to do MISSING_HEADER400 One of the four required headers is absent. Send all four X-Access-* headers. TIMESTAMP_INVALID400 X-Access-Timestamp is not a decimal integer in milliseconds.Send Unix time in milliseconds (UTC). TIMESTAMP_SKEW_EXCEEDED401 Header timestamp is more than ±10 seconds from server time. Sync your host clock via NTP. SIGNATURE_INVALID401 Signature does not verify against the canonical request. See Troubleshooting . REPLAY_DETECTED401 This (accessKey, requestId) tuple was used within the last hour. Generate a fresh X-Access-Request-Id. CREDENTIAL_DISABLED401 Your Access Key is currently disabled. Contact BlooBank account team. CREDENTIAL_REVOKED401 Your Access Key was permanently revoked. Request a new credential. CREDENTIAL_EXPIRED401 Your Access Key passed its expiry date. Rotate the credential.
Authorization (HTTP 403)
The credential is valid but lacks permission for this action on this resource.
Reason HTTP What it means What to do RBAC_DENY403 The credential lacks a required role binding. Request appropriate role from BlooBank. Include decisionId from metadata.decisionId. WORKSPACE_DISABLED403 The workspace you are calling into is disabled. Contact BlooBank account team. SERVICE_ACCOUNT_DISABLED403 The service account behind your credential is disabled. Contact BlooBank account team.
Validation (HTTP 400)
The request payload, query, or path violates input constraints.
Reason HTTP What it means What to do INVALID_ARGUMENT400 Generic class for request validation failures. Inspect details[] for specifics. Fix the request. INVALID_FIELD (in details[].reason)— A specific field in the JSON body failed validation. metadata.field names it. Fix the named field. INVALID_ID400 An ID string is malformed and cannot be decoded. Use a well-formed id (e.g., wal_…, ord_…). INVALID_FILTER400 The filter query parameter violates SFS-1 syntax or the endpoint schema. See Filtering . INVALID_ORDER_BY400 The order_by parameter references an unknown field or invalid direction. See Pagination reference . INVALID_PAGE_SIZE400 The page_size is outside the accepted range. Use a value between 1 and 100. INVALID_PAGE_TOKEN400 The page_token is malformed, expired, or context-mismatched. Restart pagination from the beginning. UNSUPPORTED_FILTER_OPERATION400 The filter uses an operator not allowed on the field’s type. Use = / != for strings/booleans/enums; comparison operators only for numbers/timestamps.
Resource state (HTTP 404 / 409 / 422)
The request is well-formed but conflicts with the state of the target resource.
Reason HTTP What it means What to do WALLET_NOT_FOUND404 The named wallet does not exist or you cannot see it. Verify wallet name; check RBAC. PAYMENT_ORDER_NOT_FOUND404 The named payment order does not exist within the wallet. Verify the paymentOrder id and wallet pairing. WALLET_ALREADY_EXISTS409 A wallet with the requested name already exists. Pick a different name; names are immutable and globally unique. LABEL_IMMUTABLE422 Attempt to change a name that is immutable after creation. Names cannot be changed — create a new resource if needed. IDEMPOTENCY_KEY_IN_USE_WITH_DIFFERENT_PARAMS422 The (wallet, idempotencyKey) tuple was used with a different body. Use a new idempotencyKey; the first body bound to that key is final. PAYMENT_ORDER_NOT_AWAITING_APPROVAL422 PUT .../approve on an order not in AWAITING_APPROVAL.Verify the order’s current status before approving. PAYMENT_ORDER_INVALID_STATE422 PUT .../cancel on an order not in AWAITING_APPROVAL.Verify the order’s current status before canceling.
Rate limiting (HTTP 429)
Reason HTTP What it means What to do RESOURCE_EXHAUSTED429 Per-credential or per-endpoint rate limit exhausted. Backoff with Retry-After; see Rate limiting . RATE_LIMIT_EXCEEDED (in details[].reason)— Detail variant of RESOURCE_EXHAUSTED. Same — use metadata.retry_after_seconds.
Server errors (HTTP 500 / 503)
Reason HTTP What it means What to do INTERNAL500 Sanitized internal failure. details[0] is ERROR_RECORDED with metadata.id. Log metadata.id; forward to support. Do not retry blindly. ERROR_RECORDED (in details[].reason)— The server persisted an audit record. metadata.id (format exc_…) is the reference. Forward metadata.id to support. PROVIDER_UNAVAILABLE503 Downstream payment provider is unavailable or returned a transient error. Retry with exponential backoff. DATABASE_UNAVAILABLE503 Internal database unreachable. Retry with exponential backoff. UPSTREAM_UNAVAILABLE503 Some upstream dependency is unreachable. Retry with exponential backoff. PERSISTENCE_FAILURE500 Unexpected persistence-layer failure. Sanitized. Forward ERROR_RECORDED id to support.
Authentication detail reasons
Some details[].reason codes are only meaningful inside the details[] array (not as a top-level error.status).
Reason Where What it means AUTHENTICATION_REQUIREDinside 401 No credentials were provided. AUTHENTICATION_INVALIDinside 401 Credentials were provided but did not verify. TOKEN_EXPIREDinside 401 The session token has expired. Refresh and retry.
How this catalog evolves
Reasons are additive : new ones may appear; existing ones do not change meaning.
Domain reasons follow the {AGGREGATE}_{CONDITION} convention (e.g., WALLET_NOT_FOUND, PAYMENT_ORDER_INVALID_STATE).
Cross-cutting reasons follow {CONDITION} (e.g., INVALID_FIELD, INTERNAL, RESOURCE_EXHAUSTED).
Treat any reason not in this catalog as opaque — fall back to handling by error.status alone.
Next
Handling errors Branching patterns in code.
Retry strategy When to retry and how.