Qiguard API docs

Errors

Every error, on every path, has the same JSON body and the header qg-zid:

{
  "name": "INPUT_INVALID",
  "message": "sellAmount must be a positive integer string",
  "data": {
    "zid": "0x7d1e0c55a9b2f4e83c61d0aa",
    "details": [ { "field": "sellAmount", "reason": "not an integer" } ]
  }
}

400

NameWhereExtra dataWhat to do
INPUT_INVALIDanydetails[], reasonFix the field named in details
HTTPS_REQUIREDany, plain HTTP-Use https://. The key sent over plain HTTP is revoked: create a new one
API_VERSION_MISSINGkeyed-Send qg-version: v1
CHAIN_NOT_SUPPORTEDchain-boundchainIdUse a chain from /swap/chains or /gasless/chains
TOKEN_NOT_SUPPORTEDprice, quote, submittoken, reason (transfer_tax)Use a token from /tokens
TOKEN_PAIR_NOT_SUPPORTEDprice, quote, submitreason (no_anchor, wrap_unwrap, native_not_supported)Put an anchor on one side; no wrap or unwrap; no native coin on gasless
RECIPIENT_NOT_SUPPORTEDprice, quote-Leave recipient out or set it to taker
SELL_AMOUNT_TOO_SMALLprice, quote, submitminSellAmountSell at least minSellAmount
INSUFFICIENT_BALANCEgasless quote with taker (the gasless price answers 200 with issues.balance instead)token, actual, expectedThe taker needs more of the sell token
SWAP_VALIDATION_FAILEDswap quote simulationreason (slippage, adapter_not_allowed), revertQuote again; raise slippageBps for volatile pairs
UNABLE_TO_CALCULATE_GAS_FEEgasless price and quote-Retry shortly
SMART_WALLET_NOT_SUPPORTEDgasless with taker-Use the swap endpoints for contract wallets
INTEGRATOR_FEE_NOT_SUPPORTEDprice, quote-Remove the swapFee* parameters
EXACT_OUT_NOT_SUPPORTEDprice, quote-Send sellAmount instead of buyAmount
IDEMPOTENCY_KEY_REUSEDsubmit-Use a new Idempotency-Key for a different body
INSUFFICIENT_BALANCE_OR_ALLOWANCEsubmittaker, sellToken, sellAmount, minBalanceOrAllowanceTop up the balance or approve Permit2
INVALID_APPROVALsubmit-Send approval as null or leave it out
INVALID_SIGNATUREsubmit-Sign trade.eip712 again with eth_signTypedData_v4
INVALID_SIGNERsubmit-The signer must be the taker (witness.recipient)
META_TRANSACTION_EXPIRY_TOO_SOONsubmit-Quote and sign again
META_TRANSACTION_INVALIDsubmitreason (price_moved, simulation_failed, gas_too_high, ...), revertSend the typed data unchanged; on price_moved, quote and sign again
PENDING_TRADES_ALREADY_EXISTsubmit-Wait for the taker's pending trade on this chain
TRADE_ALREADY_SUBMITTEDsubmitreason (permit_nonce_used)Another app sent this trade, or the Permit2 nonce is used: quote again

401, 403, 404, 405

HTTPNameWhereExtra dataWhat to do
401API_KEY_MISSINGkeyed-Send qg-api-key (message: "No API key found in request")
401API_KEY_INVALIDkeyed-The key is unknown, malformed or revoked: use an active key
403APP_NOT_APPROVEDkeyedstatus (pending, suspended)Wait for approval, or see the app in the dashboard
403PRODUCT_NOT_ENABLEDkeyedreason (product_not_enabled, chain_not_enabled)Enable the product or chain in the app settings
403ORIGIN_NOT_ALLOWEDkeyeddetailsCall from a server; a proxy must strip Origin and Sec-Fetch-*
403TAKER_NOT_AUTHORIZED_FOR_TRADEtaker-boundreason (denied, gasless_blocked)The taker cannot trade through this endpoint
404NOT_FOUNDany-Check the path
404META_TRANSACTION_STATUS_NOT_FOUNDstatus-Use the tradeHash and chainId of a trade your app submitted
405METHOD_NOT_ALLOWEDany-Use the method in the Allow header

413, 414, 429

HTTPNameWhereExtra dataWhat to do
413PAYLOAD_TOO_LARGEsubmit-The body limit is 256 KB
414URI_TOO_LONGany-The URL limit is 8,192 characters
429RATE_LIMITEDkeyed, and the gasless per-taker hourly limitreasonWait Retry-After seconds (10 for the app limit)
429QUOTA_EXCEEDEDdaily request cap, gasless submits per dayreasonWait until 00:00 UTC (Retry-After)
429GAS_BUDGET_EXCEEDEDgaslessreason (app_daily, chain_daily, free_tier_daily)The sponsored-gas budget is used up for the day

500, 503

HTTPNameWhereExtra dataWhat to do
500INTERNAL_SERVER_ERRORany-Retry; keep the zid
500UNCATEGORIZEDany-Retry; keep the zid
503SETTLEMENT_PAUSEDchain-boundchainIdThe settlement contract of the chain is paused; GET /status shows when it is back
503SWAP_NOT_ENABLEDswapchainId, reason (switched_off)Swap is switched off on this chain for now
503GASLESS_NOT_ENABLEDgasless submitreason (gasless_not_enabled), chainIdGasless is not switched on for this chain yet; use the swap endpoints
503RELAYER_UNAVAILABLEgasless submitreason (relayer_low_balance, relayer_busy, relayer_stalled, gas_price_above_cap, relayer_timeout, relayer_unreachable); tradeHash with relayer_timeout and relayer_unreachableRetry later; Retry-After: 3 when busy or timed out. With tradeHash, first read GET /gasless/status/{tradeHash}: the trade may have been accepted (404 means it was not)
503RPC_UNAVAILABLEprice, quote, submit, status-The chain's RPC operators did not agree or answer; retry

Retrying