Skip to content

Errors ​

Every error the API, the contract or the order flow can hand you, in one place, with what to do about it.

Error shape ​

API errors are JSON:

json
{ "error": "Order total is below the $1 minimum", "code": "BELOW_MIN_TOTAL" }

The two refusals that ask you to wait — 429 RATE_LIMITED and 503 WARMING_UP — carry retryAfterSec and a Retry-After header instead of code. Order endpoints answer 400 { "error": "<message>" } without a code.

POST /api/quote ​

HTTPCodeMeaningWhat to do
400(no code)The body is not valid JSON — rejected before validation, body { "error": "Unexpected token …" }. A missing body counts as {} and fails with BAD_FROM_CHAIN.Send Content-Type: application/json and a JSON object.
400BAD_FROM_CHAINchainId is not an enabled FROM chain, or the chain is paused.Pick a chain with isTestnet: false, isEnabled: true and no isPaused in /api/chains.
400BAD_TO_CHAINtoChainId is not an enabled TO chain, or paused.Same check on the TO side.
400BAD_ADDRESSfromToken, sender or toToken is empty or malformed for its chain.EVM 0x…; Solana base58; TON any form.
400BAD_FROM_TOKENfromToken is not listed for that FROM chain.Use a token from /api/chains.
400BAD_TO_TOKENtoToken is not listed for that TO chain.Use a token from /api/chains (0x0…0 = native).
400BAD_ARRAYS / EMPTY / LENGTH_MISMATCHrecipients / toAmounts not arrays, empty, or different lengths.One amount per recipient.
400TOO_MANYMore than 10 000 recipients.Split into several quotes.
400BAD_RECIPIENTA recipient fails the TO chain's validation.Check the address family (EVM / Solana / TON / Bitcoin testnet).
400BAD_TO_AMOUNTAn amount is not a positive base-unit integer string."5000000000000000000", not 5 or 5e18.
400TO_TOO_SMALLA TO amount is below the per-recipient minimum.Raise that amount.
400TO_TOO_PRECISEA TO amount is off the token's precision grid (4 decimals; whole sats for BTC).Round it.
400FROM_ROUNDS_TO_ZEROA TO amount is too small to price in the FROM token.Raise it.
400BELOW_SOL_RENT_MINSolana TO: below the 0.001 SOL rent floor.Send at least 0.001 SOL per recipient.
400BELOW_MIN_TOTALOrder total under $1 (single) / $5 (multisend).Raise the amounts.
400NO_LIQUIDITYΣ toAmounts exceeds what can be dispensed right now.Check balance in /api/quotes; lower the amounts or wait.
500NO_VAULTThe FROM chain has no pay target configured.Pick another FROM chain; tell us.
503NO_FROM_PRICEThe FROM token's price feed is missing or stale (400 with the same code if the feed reports a non-positive price).Retry later or pay with another token.
503NO_TO_PRICEThe TO token is unavailable (no rate or no liquidity data; 400 with the same code for a non-positive rate).See available in /api/quotes; try later.
503SIGNING_DISABLEDQuoting is paused by the operator.Try later.

Rate limits and availability ​

HTTPBodyMeaningWhat to do
429{ "error": "RATE_LIMITED", "retryAfterSec": n }Over 600 req/min per IP, or 10 quotes/min per IP, or 30 quotes/min per sender.Sleep Retry-After seconds, then retry. Quote only when ready to pay.
429(empty body)Edge flood protection.Back off harder.
503{ "error": "WARMING_UP", "retryAfterSec": 5, "waitingFor": [...] }Backend just restarted; prices / balances still loading.Retry after retryAfterSec.

Details: Rate limits.

Other endpoints ​

EndpointErrorMeaning
GET /api/quotes400 Missing chainId or symbolPass both or neither.
GET /api/quotes404 No quote found for symbol …No such TO token on that chain.
GET /api/prices400 Invalid addressMalformed token address.
GET /api/prices/at400 chainId, address and ts are required · 400 Invalid ts · 404 No price recorded at or before tsFix the parameters; history starts when the token was listed.
GET /api/order400 Provide order id or from_tx_hashPass one of the two.
GET /api/order?id=200 nullNot indexed yet — keep polling. Ids are case-sensitive.
GET /api/orders400 Incorrect addressThe payer identity is malformed (EVM 0x…, Solana base58, TON).
GET /api/orders400 status must be one of: …Bad status filter.
POST /api/orders/status400 ids must be an array and is required · 400 too many ids (max 500)Fix the body.
GET /api/orders/stream400 Incorrect address · 503 Too many subscribersFix the address · fall back to polling.

EVM contract reverts ​

Decode a revert against these custom errors (the ABI is on the contract page):

ErrorMeaningWhat to do
ExpiredLanded after deadline.Request a fresh quote.
MissingQuotequoteId is zero.Pass the quote's quoteId.
AmountTooLow / ZeroAmountPaid amount is zero or below the contract's per-token floor.Pay fromTotal.
TokenTransferMismatchThe token delivered less than amount (fee-on-transfer / rebasing).Use a listed token.
TokenNotAllowedThe token isn't accepted by the pay target.Use a token from /api/chains.
DirectPaymentNotAllowedA plain transfer to the contract, not a pay call.Call pay(...).
EnforcedPauseThe contract is paused.Try later.

Payments held for review ​

A payment that lands but does not match its quote — a different payer than sender, a different token, or an amount other than fromTotal — does not become an order and is not refunded automatically. It is flagged to the operator. If this happens to you, contact support on Telegram or Discord with the transaction hash. On EVM, passing the quote's fromTotal makes this impossible to hit by accident; on Solana / TON the transfer amount is yours to get right — see Payment rules.

The same applies to a second payment of a quote that was already honoured: it is held, and which of the two payments to return is decided by the operator. Never retry a payment whose transaction confirmed — track it instead.

Refund reasons ​

A payment that can't become an order gets a refund record (refund on GET /api/order, and a row in the payer's history). On TON look in the history (GET /api/orders?address=<UQ…>&view=batches): a refused payment did not consume its quote, so from_tx_hash=<quoteId> does not find it.

ReasonCauseAvoid it by
expiredPaid after deadline (Solana / TON — on EVM the contract reverts).Pay with plenty of the 180 s left; on TON set validUntil = deadline.
unknown_quoteThe memo / comment carried a quoteId the backend never issued.Put the quoteId from the quote response verbatim in the memo / comment.
unattributedNo readable quoteId at all in a transfer to the treasury (Solana / TON), above a small dust threshold.Always send the memo / comment; never transfer to the treasury without a quote.
ambiguous_memoSeveral different quoteIds in one Solana transaction.One quote per transaction.
bad_signatureThe stored quote's signature did not verify against a trusted signer key (operator-side).Nothing to avoid; the payment comes back.
failed_orderSome recipients of a batch failed.Nothing to avoid; their slice comes back (for a partial batch, capped so the delivered part still cost at least $1).

Refunds are sent by the operator; the record shows refund_pending until the return transaction is out, then refunded with refundTxHash.