Skip to navigation

Errors and recovery

Error body

{
"error": {
"code": "CONFLICT",
"numericId": 1004,
"message": "Action is unavailable for this role or trade state. Refresh the trade.",
"requestId": "<request id>",
"details": { "reason": "INVALID_STATE" }
}
}

details is optional. Validation errors may identify details.fields. Rate limits send Retry-After in seconds. The request ID is also returned in X-Request-Id. Browser code may not be able to read response headers that are not CORS-exposed; use the body’s request ID and rate-limit details when available.

Codes and next steps

HTTPCode / numeric IDWhat to do
400VALIDATION_ERROR / 1000Fix missing or unknown fields, account schema, decimal precision or body size. Default JSON limit is 16 KB; proof and chat-image uploads have a 5 MB JSON limit.
401UNAUTHENTICATED / 1001Check the credential. For an expired or revoked session, ask your backend to mint a new one for the same customer.
403FORBIDDEN / 1002Check origin, integration, chain, verification trust and consistency headers. Retrying unchanged is not useful.
404NOT_FOUND / 1003Check the route and ownership. Another customer’s resource is hidden as missing.
409CONFLICT / 1004Read the current state again, then check each possible cause: a uniqueness rule, the fixed wallet and chain, a changed offer or fee, an expired deadline, an open trade, a replaced breakdown, the wallet nonce or an idempotency key bound to a different request.
400INSUFFICIENT_BALANCE / 4001Fund the required USDT or POL. A customer SELL with too little USDT fails on POST /v1/trade-breakdowns. Not enough POL for the network fee fails on POST /v1/transactions with details.kind: "NATIVE_GAS", details.chainId and the required, current and missing amounts in wei and POL.
502BLOCKCHAIN_TX_FAILED / 4002A funding receipt shows an on-chain failure. Inspect the receipt and read the trade again before you try another attempt.
409INSUFFICIENT_LIQUIDITY / 4005On a customer BUY, the merchant can no longer fund the trade. Returned by POST /v1/trade-breakdowns, and by POST /v1/transactions when you send signed bytes. Search again after recovering any submitted transaction.
409CONFLICT with details.reason: "ACTIVE_TRADE_EXISTS"The customer already has an active trade on that side, or a breakdown whose escrow transaction was reported or is under review. Raised by POST /v1/trade-breakdowns. An unsubmitted breakdown does not cause this: a new idempotency key replaces it with a fresh quote. Show the existing trade, or wait for it to finish.
400VALIDATION_ERROR with details.reason: "SELF_TRADE_NOT_ALLOWED"The only usable match is the customer’s own listing (“You cannot trade with your own wallet.”). Raised by POST /v1/offers/best and POST /v1/trade-breakdowns. Offer a different amount or listing.
409PAYMENT_METHOD_ALREADY_EXISTS / 4008Reuse or reactivate the saved account with the same catalog identity.
429RATE_LIMITED / 4004Wait for Retry-After or details.retryAfter. Do not retry in a tight loop.
502 / 503UPSTREAM_ERROR / 1005Read the message: chain, RPC or pricing may be temporarily unavailable, or the request may need Sinbad’s intervention. Retry only when appropriate.

UPSTREAM_ERROR defaults to 502. Some handlers override it to 503, including unexpected service failures. Do not assume this code always has one HTTP status.

Common situations

SituationResponse and next step
A partner secret call includes an Origin header403 FORBIDDEN. Make the call from your server.
The browser origin is not registered, the consistency headers do not match, or the chain is not allowed403 FORBIDDEN. Check the integration settings.
The first session request is missing the name, a verified email address, a wallet or a chain400 VALIDATION_ERROR.
A session request reuses another active customer’s wallet, email address or phone number409 CONFLICT, with the conflicting fields in details.fields.
Your partner account setup is not finished, and you register a new customer or change contact details502 UPSTREAM_ERROR. Contact Sinbad and quote the X-Request-Id. Do not change customer IDs to work around it.
A later session request changes the registered wallet or chain409 CONFLICT.
A session request uses a deleted customer ID401 UNAUTHENTICATED.
The customer has no active saved account matching the offer’s catalog method400 VALIDATION_ERROR, on both BUY and SELL.
No inventory matches an offer search200 with empty instant and alternatives arrays. A missing or stale currency or an invalid method can instead return 400, and unavailable pricing can return UPSTREAM_ERROR.
You modify breakdownInput, fees or availability change, the signing window expires, or a newer breakdown replaces yours409 CONFLICT. A selection that no longer exists can return 404. Search again or create a new breakdown.
A dispute is prepared too early409 CONFLICT with details.reason: "TOO_EARLY" and details.availableAt. Wait until that time and try again. Other role or state conflicts use INVALID_STATE.
Proof already exists, its revision changed, or the trade is closed409 CONFLICT. Read the trade and the proof again. To change or remove proof, send its current ID as expectedProofId. Do not retry different contents against a stale revision. See Payment proof.
A SELL customer tries to upload or edit proof403 FORBIDDEN. Only the fiat payer uploads.
The current proof or its stored file does not exist404 NOT_FOUND on a read.
A wallet hash is not yet visible to the networkUPSTREAM_ERROR. Retry reporting the same hash. Do not send a new transaction.

New proof and chat files must be PNG or JPEG files of up to 3 MiB. Those limits do not restrict how Sinbad reads merchant files that already exist.

Customer verification is the partner’s responsibility, and there is no separate screening request. Location enforcement is not active yet, so an unknown location by itself does not produce an empty offer response.

Transaction recovery

HTTP 202 means accepted, not confirmed. A timeout or BROADCAST_UNKNOWN can still mean a transaction was sent. Keep tracking the same preparationId and hash, including after the signing deadline. Follow the recovery steps in Wallets and gas before you create another attempt.

Transaction outcomes such as REVERTED or REVIEW_REQUIRED are returned in a successful status-read body. Check transaction.status as well as the HTTP result. Keep request IDs and transaction IDs for support; never send a private key or partner secret.