Skip to main content

Troubleshooting HTTP Integrations

Start with the response status, stable error code, and request correlation id. Do not start by rotating credentials or resubmitting an uncertain order.

Fast decision path

  1. Record the UTC time, method, path template, status, X-Request-Id, body requestId, stable code, and whether a response body arrived.
  2. For 401/403, verify the credential type, account binding, scope, clock, and request-signing inputs. Create a fresh transport-auth tuple for a new HTTP attempt, but keep the action body and idempotency identity unchanged.
  3. For 409, reconcile the nonce or idempotency key. Do not parse prose when a structured code or nonce window is available.
  4. For 429/503, honor Retry-After when present. When absent, use capped exponential backoff with jitter. A 503 does not prove that a mutating request was rejected.
  5. For a timeout or lost response, query receipts, order state, private execution events, and the authoritative account bootstrap before resending.
  6. After HTTP 200 accepted: true, continue until a terminal receipt, fill, cancel, or rejection resolves the action.

Common symptoms

SymptomCheckSafe action
401Expiry, clock skew, key id, bearer type, canonical method/path/query/body hashRefresh or correct authentication, then sign a new transport attempt.
403Scope, wallet/account binding, app channel, allowed market/IP/policyCorrect permission or identity; repeating identical credentials will not help.
409 nonce conflictnonceFloor, nonceWindow, nonceHoles, nextUsableNonceSelect an unused allowed nonce only after reconciliation, then re-sign.
409 idempotency conflictKey, canonical endpoint, request hash, prior responseReplay only the identical operation or allocate a new key for a deliberately new operation.
429Retry-After, X-RateLimit-*, body retryAfterMs, live BSL limitsPace the correct scope; do not interpret missing headers as zero capacity.
503 / timeoutReadiness, receipt, private stream, order id, idempotency statePreserve identity and reconcile before retrying.
Balance/order view appears oldasOf, projection versions, receipt/event cursorUse /accounts/{account}/bootstrap?fresh=true; follow the freshness procedure below.

Sanitized diagnostic bundle

Send this through the integration access channel provided during onboarding, or email [email protected]:

Environment/host:
UTC time window:
HTTP method + path template:
HTTP status or "no response":
X-Request-Id:
Body requestId:
Stable error code:
Retriable/details (sanitized):
Admission ACK observed? yes/no/unknown:
Terminal receipt/event observed? yes/no/unknown:
Last receipt/event cursor:
Idempotency correlation label or fingerprint:
Client/SDK name and version:

Never attach API secrets, passphrases, private/session keys, seed phrases, raw authentication headers, signatures, cookies, or private request bodies. Redact wallet, account, order, and IP identifiers unless support explicitly needs one to locate the correlated server log.

Account-read workaround during freshness rollout

The explicit freshness fields are not yet available on production. Until the server returns them and public readback is verified, use this workflow:

  1. Keep the terminal receipt or private execution event for the write.
  2. Request GET /api/v1/accounts/{account}/bootstrap?fresh=true using the 20-byte engine account.
  3. Compare asOf, nonce, balances, open orders, and available projection metadata with the event being reconciled.
  4. If the view has not caught up, wait with jitter and repeat the read. Do not place from the older view and do not manufacture a new nonce from it.
  5. Escalate with both request ids and the receipt/event cursor if the view does not advance.

See Account freshness and reconciliation for the full boundary.