Skip to main content

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.
ReasonHTTPWhat it meansWhat to do
MISSING_HEADER400One of the four required headers is absent.Send all four X-Access-* headers.
TIMESTAMP_INVALID400X-Access-Timestamp is not a decimal integer in milliseconds.Send Unix time in milliseconds (UTC).
TIMESTAMP_SKEW_EXCEEDED401Header timestamp is more than ±10 seconds from server time.Sync your host clock via NTP.
SIGNATURE_INVALID401Signature does not verify against the canonical request.See Troubleshooting.
REPLAY_DETECTED401This (accessKey, requestId) tuple was used within the last hour.Generate a fresh X-Access-Request-Id.
CREDENTIAL_DISABLED401Your Access Key is currently disabled.Contact BlooBank account team.
CREDENTIAL_REVOKED401Your Access Key was permanently revoked.Request a new credential.
CREDENTIAL_EXPIRED401Your 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.
ReasonHTTPWhat it meansWhat to do
RBAC_DENY403The credential lacks a required role binding.Request appropriate role from BlooBank. Include decisionId from metadata.decisionId.
WORKSPACE_DISABLED403The workspace you are calling into is disabled.Contact BlooBank account team.
SERVICE_ACCOUNT_DISABLED403The service account behind your credential is disabled.Contact BlooBank account team.

Validation (HTTP 400)

The request payload, query, or path violates input constraints.
ReasonHTTPWhat it meansWhat to do
INVALID_ARGUMENT400Generic 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_ID400An ID string is malformed and cannot be decoded.Use a well-formed id (e.g., wal_…, ord_…).
INVALID_FILTER400The filter query parameter violates SFS-1 syntax or the endpoint schema.See Filtering.
INVALID_ORDER_BY400The order_by parameter references an unknown field or invalid direction.See Pagination reference.
INVALID_PAGE_SIZE400The page_size is outside the accepted range.Use a value between 1 and 100.
INVALID_PAGE_TOKEN400The page_token is malformed, expired, or context-mismatched.Restart pagination from the beginning.
UNSUPPORTED_FILTER_OPERATION400The 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.
ReasonHTTPWhat it meansWhat to do
WALLET_NOT_FOUND404The named wallet does not exist or you cannot see it.Verify wallet name; check RBAC.
PAYMENT_ORDER_NOT_FOUND404The named payment order does not exist within the wallet.Verify the paymentOrder id and wallet pairing.
WALLET_ALREADY_EXISTS409A wallet with the requested name already exists.Pick a different name; names are immutable and globally unique.
LABEL_IMMUTABLE422Attempt 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_PARAMS422The (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_APPROVAL422PUT .../approve on an order not in AWAITING_APPROVAL.Verify the order’s current status before approving.
PAYMENT_ORDER_INVALID_STATE422PUT .../cancel on an order not in AWAITING_APPROVAL.Verify the order’s current status before canceling.

Rate limiting (HTTP 429)

ReasonHTTPWhat it meansWhat to do
RESOURCE_EXHAUSTED429Per-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)

ReasonHTTPWhat it meansWhat to do
INTERNAL500Sanitized 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_UNAVAILABLE503Downstream payment provider is unavailable or returned a transient error.Retry with exponential backoff.
DATABASE_UNAVAILABLE503Internal database unreachable.Retry with exponential backoff.
UPSTREAM_UNAVAILABLE503Some upstream dependency is unreachable.Retry with exponential backoff.
PERSISTENCE_FAILURE500Unexpected 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).
ReasonWhereWhat it means
AUTHENTICATION_REQUIREDinside 401No credentials were provided.
AUTHENTICATION_INVALIDinside 401Credentials were provided but did not verify.
TOKEN_EXPIREDinside 401The 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.