Errors, pagination and safe retries
Read the HTTP status first, then the documented response. Keep an access denial distinct from a failed request.
Read both supported error shapes
The shared error handler returns application/problem+json with type, title, detail, status, code, requestId and a legacy error string. Some authentication middleware returns application/json with only error. A robust client can handle either without assuming every failure has a code.
{
"type": "about:blank",
"title": "Not allowed",
"detail": "The requested operation is not available for this account.",
"status": 403,
"code": "FORBIDDEN",
"requestId": "example-request-20261019",
"error": "The requested operation is not available for this account."
}Server faults return a generic client-safe message. Keep the correlation reference, not the complete private request body.
Use a recovery path for each class
| HTTP status | Typical meaning | Recovery |
|---|---|---|
| 400 | Payload, terms, token format or payment-proof mismatch. | Correct the request; do not blindly retry. |
| 401 | Missing, invalid or revoked credential. | Use the supported sign-in/provisioning flow. |
| 403 | Owner/scope/approval/reader restriction. | Check account and terminal state. |
| 404 | Missing or inaccessible resource. | Refresh the resource reference in the correct tenant. |
| 409 | Conflict, pending checkout or changed state. | Read code; keep the original purchase key if pending. |
| 410 | Expired pending purchase or retired operation. | Use the current supported flow. |
| 413 | Body/file limit exceeded. | Use the endpoint-specific smaller payload. |
| 429 | Rate limited. | Respect Retry-After when present and back off. |
| 5xx | Dependency/configuration/server failure. | Recover with bounded retries only where safe. |
No global numeric vendor quota is promised by this reference. Endpoint/infrastructure limits can differ. Do not infer capacity from a single successful request.
Choose retries by operation
- Safe reads: use a bounded retry policy with jitter for transient failures. Avoid polling aggressively.
- Checkout creation: retry the same intended purchase with its original Idempotency-Key.
- POS taps/batches: repeated calls can create additional audit/usage entries. Do not automatically replay an uncertain result without an agreed policy.
- Document upload: do not assume an interrupted upload was never accepted; refresh metadata before repeating.
- Webhook receiver: deduplicate a durably stored event ID before applying effects.
Pagination is endpoint-specific
Device logs accept page starting at 1 and limit from 1 to 100, default 20. Their pagination object returns page, limit, total and totalPages. Recent subscriptions/verifications return a maximum of 100 without a documented continuation cursor. CSV reports are separate exports; do not invent offset or cursor parameters for endpoints that do not expose them.
Report a failure without sharing secrets
Provide the request ID, UTC time, operation path with token values redacted, environment, HTTP status and nonsecret resource references. Never include raw API keys, buyer session tokens, identity files, card UIDs, signing secrets or full payment payloads in a support message.
Contact BEXO if configuration or reconciliation remains uncertain.