Limits and limitations
This page is the single reference for numeric limits. Other pages link here instead of repeating them.
Rate limits
When a limit is exceeded, the response is 429 RATE_LIMITED with details.retryAfter and a Retry-After header, both in seconds. Wait that long. Do not retry in a tight loop.
Sessions. Session creation uses per-partner and per-customer quotas. The defaults are 60 and 5 per minute. Sinbad can configure different values for your partner, so confirm them during onboarding. Only a session that is actually created consumes quota. Requests with invalid credentials do not. Cache each customer’s session token until shortly before it expires.
Offers and breakdowns. Offer searches and breakdown creation share one limit for each customer. Three details affect how you count:
- A repeated call with the same
Idempotency-Keystill counts toward the limit. - Sinbad checks the request body first and the limit second.
- Sinbad checks the
Idempotency-Keyheader after the limit, so a request with a missing or malformed key still counts toward the limit.
Webhooks. Only successful calls count. A failed rotation does not count toward the rotation limit, and a replay of an earlier request with the same Idempotency-Key does not count either.
Size limits
A larger request body returns 400 VALIDATION_ERROR. Registering a sixth webhook endpoint returns 409 CONFLICT with details.kind: "ENDPOINT_LIMIT". See Payment proof and Chat and images.
Timings
Trade updates and webhooks can arrive later than the chain confirmation. Sinbad does not guarantee a delivery latency. See Sign and track transactions.
Idempotency
An Idempotency-Key must match ^[A-Za-z0-9_-]{8,128}$.
- Sending the same key with the same body returns the first result.
- Sending the same key with a different body returns
409 CONFLICT. Use a new key when you change the request. - A chat message sent twice appears twice.
- An identical proof upload returns the existing matching receipt. After an uncertain result, read the current proof before you change it.
See Errors and recovery for how to retry each status.
Webhook checks on your side
Sinbad signs each webhook delivery with a timestamp. Sinbad does not enforce the following two rules for you, so build them into your receiver:
- Reject a timestamp more than 5 minutes away from your own clock.
- Keep the IDs of the events you have processed for at least 30 days, and ignore repeats. Delivery is at least once.
See Webhooks.
Trade statuses you will not see yet
The API lists PENDING, FUNDING_FAILED and FUNDING_EXPIRED as trade statuses, but they are reserved and Sinbad does not produce them today. A trade first appears as CREATED, once the escrow is funded and confirmed. Before that, follow the breakdown, which shows AWAITING_FUNDING and then CONFIRMED or EXPIRED.
The includePending query parameter on the trade list is accepted for future use. Today it only changes the sort order. Build your status handling to accept the reserved values anyway. See Trade lifecycle.
One open trade per side
A customer can have one open BUY and one open SELL at a time. The rules for creating, replacing and releasing them are in Offers and breakdowns.
Known limitations
- Delayed status. Trade updates and webhooks can lag the chain confirmation and arrive out of order. Track existing transactions, deduplicate events, and reconcile current state by reading the trade.
- Receiving details on a SELL. A funded trade in
CREATED,PAIDorDISPUTEDreturns the customer’s selected receiving-account snapshot when you read it. Lists and webhooks include only its display label. - Deleting a customer is permanent. After
DELETE /v1/partner-users/{partnerUserId}, thatpartnerUserIdcan never get a session again. Trade history is kept. The customer’s wallet, email address and phone number can be used by a new customer. - Webhook availability. Confirm webhook delivery for your environment. Register and verify an endpoint subscribed to each event type you need. A queued test alone does not prove delivery works.
- One wallet per customer. The wallet is fixed at the first session. A session request with a different wallet or chain returns
409 CONFLICT. - Merchant actions are outside this API. On a SELL, the merchant marks the trade paid. On a BUY, the merchant releases. Both happen in Sinbad’s merchant tools, and you see them as status changes. Sinbad does not guarantee how quickly merchants act.
- Webhooks leave out private data. Payloads do not include payment account details, proof files or contact data. Read them through the API. Chat message text is included.
- No replay of earlier events. Endpoint creation, verification and subscription changes determine which events you receive. Do not expect events from before your subscription. Reconcile current trades through the API.
- Hash-only reports skip the balance check. If you report a transaction by hash instead of sending signed bytes, Sinbad does not run its gas balance check. Sending the signed bytes is the recommended path.
- Fee draft precision.
upperUsdandFLAT_USDamounts allow at most six decimal places. More returns400 VALIDATION_ERROR. - Fee publication needs your manager wallet.
POST /v1/partner/fees/publishonly prepares a transaction. You send it from your registered manager wallet and pay its gas. The new schedule applies after it confirms. - Screening and verification are yours. Location screening is off in the current phase, so blocked-country settings do not stop a customer from trading. Sinbad does not verify your customers’ identity. You are responsible for both.