Skip to main content

Errors & Rate Limits

How the APIs report failures, and what limits apply per endpoint.

HTTP status codes

StatusMeaningWhat to do
2xxSuccess.Read the response body.
4xxMalformed request. The issue is on your end — bad parameters, missing fields, invalid signature, expired epoch.Read message (Spot/Futures) or retMsg (HFT). Fix and retry.
401Authentication failed. Bad signature, wrong API key, or X-AUTH-EPOCH skew >60s.Verify your signing flow against the Reference Client.
422Validation failed. A field is missing or has an invalid value.The message names the field.
429Rate limit exceeded.Back off (see Backoff) and retry.
5xxServer error on our side. Do not assume the request failed — the operation may have succeeded but the response was lost.For order placement and cancellation: query Get Order or Get Order Status with your client_order_id / orderLinkId before retrying.
caution

A 5xx is not a failed operation. The execution status is unknown. Always reconcile by querying with your client-supplied ID before retrying — otherwise you risk placing the same order twice.

Idempotency on retries

Network blips, timeouts, and 5xx errors are facts of life. The safe pattern for any state-changing call (place / cancel / transfer):

  1. Always send a client-supplied ID on the first attempt:
    • Spot orders → client_order_id
    • Futures orders → client_order_id
    • HFT orders → orderLinkId
    • HFT transfers → client_txn_id
  2. On timeout or 5xx, do not blindly retry. Query the relevant endpoint by your client ID first:
  3. If the order/transaction exists, the original request succeeded — use that record, don't re-place. If it doesn't exist, retry with the same client ID. Re-sending the same client ID is safe; we de-duplicate.

Sketch:

def place_with_retry(payload, max_retries=3):
payload["client_order_id"] = str(uuid.uuid4())
for attempt in range(max_retries):
try:
return place_order(payload)
except (Timeout, ServerError):
existing = get_order(client_order_id=payload["client_order_id"])
if existing:
return existing # request actually succeeded
# else fall through and retry
raise RuntimeError("place_order failed after retries")

Error response shapes

Spot and Futures v2 return a flat error object:

HTTP 422
{ "message": "Input symbol is missing" }
HTTP 400
{ "message": "Amount is more than available balance" }
HTTP 401
{ "message": "Invalid Access" }

HFT wraps errors in the standard envelope:

HTTP 200, retCode != 0
{
"retCode": 10001,
"retMsg": "Invalid parameter",
"result": {},
"retExtInfo": {},
"time": 1756460688504
}

For HFT, always check retCode === 0 before reading result. HTTP 200 only means the request reached the server.

Common error messages

StatusMessageCause
422Input <field> is missingA required parameter is absent from the request.
422The value you provided for the field is not valid. Please check the documentation for valid values and try again.A field has the wrong type or an out-of-range value.
400Amount is more than available balanceInsufficient free_balance (Spot) or available equity (Futures) to cover the order.
401Invalid AccessAuthentication failed. Re-check your API key, signature, and epoch.

Rate limits

Public market-data endpoints have generous limits. Order placement and cancellation are tighter — they're the most expensive operations to honour and the most abused under volatile conditions.

When you exceed a limit, the server returns HTTP 429. Limits are applied per API key.

Spot

EndpointLimit
Create Order100 / 10s
List Orders10000 / 10s
Portfolio5000 / 10s
TDS25 / 10s

Other Spot endpoints (Cancel Order, Get Order, Trade Info, Active Coins, Exchange Precision, Trading Fee, Trades, Depth, Candles, Tickers) do not have a published per-endpoint limit. They are subject to a global per-key fair-use limit; if you start seeing 429s on these, back off and contact api@coinswitch.co for a higher allocation.

Futures

EndpointLimit
Place Order20 / 60s
Cancel Order10 / 60s
Cancel All Open Orders10 / 60s
Get Order Status20 / 60s
Open Orders20 / 60s
Closed Orders20 / 60s
Get Positions20 / 60s
Update Leverage10 / 60s
Get Leverage20 / 60s
Add Margin10 / 60s
Get Wallet Balance20 / 60s
Get Transactions20 / 60s
Get Instrument Info100 / 60s
Get Order Book100 / 60s
Get Ticker100 / 60s
Get All Pairs Ticker100 / 60s
KLines30 / 60s
Get Trades100 / 60s

HFT

Treat HFT rate limits conservatively — back off on 429, monitor your error rate, and if you need a higher allocation, contact api@coinswitch.co.

Backoff

When you hit a 429:

  1. Stop sending for at least the duration of the limit window. For an endpoint at 100 / 10s, wait at least 10 seconds before retrying.
  2. Use exponential backoff for repeated failures — double the wait on each consecutive 429, capped at a sensible ceiling (60s).
  3. Add jitter — randomize each wait by ±25% to avoid thundering herds when many of your processes hit the limit at the same instant.
  4. Don't retry on the same connection if you're seeing 5xx and 429 together — the server may be shedding load. Open a fresh connection on retry.

If you find yourself hitting limits regularly under normal operation, your strategy needs adjustment (batch reads, cache aggressively, prefer WebSockets over polling) — or it may be a fit for the HFT API.