Credit-Based System
Each API request consumes a certain number of credits. The refill rate and maximum credit pool for your sub-account depend on your trading activity and tier. If a request arrives when no credits remain, we immediately send atoo_many_requests (code 10028) or similar error and terminate the session. After a disconnect, you must wait for credits to replenish and then re-establish a new connection before sending additional requests.
Key elements of this system include:
Credit Refill
Credits are replenished continuously at a fixed rate, depending on your sub-account’s tier. This refill acts like a leaky bucket: each second, a certain number of credits “drip” back into your sub-account’s credit pool. You can think of this as a “credits per second” (CPS) refill rate.Rate limits are applied per sub-account. Each sub-account has its own independent rate limit.
- Example: If your refill rate is 20 credits/second, and each request costs 1 credit, you can sustainably send 20 requests per second without depleting your credits.
- The refill continues even when you’re not making requests, allowing you to accumulate credits back up to your maximum credit limit.
- If your maximum credit cap is 200 and your refill rate is 20 credits/sec, it will take 10 seconds to fully refill from 0 to 200.
- Allow burst activity (e.g., submitting multiple orders at once), as long as it doesn’t exceed the maximum credit limit.
- Encourage consistent and predictable usage, minimizing sudden surges that could strain the system.
Maximum Credits
This is the upper bound of your available credit pool. You cannot accumulate more credits than this cap, regardless of how long you wait. It determines the size of request bursts you can make.Cost per Request
Each API method consumes a different number of credits. More resource-intensive methods may cost more than lightweight ones.| Method | Cost | Credits | Sustained Rate | Burst Capacity |
|---|---|---|---|---|
public/get_instruments | 10,000 | 500,000 | 1 request/second | 50 requests |
public/subscribe private/subscribe | 3,000 | 30,000 | ~3.3 requests/second | 10 requests |
private/position_move | 100,000 | 600,000 | 6 requests/minute | 6 requests |
private/get_transaction_log | 10,000 | 80,000 | 1 request/second | 8 requests |
Matching vs Non-Matching Engine Requests
There are two main categories of API requests:- Matching engine requests: These interact with the order book, such as placing or cancelling an order.
- Non-matching engine requests: These involve general queries, such as retrieving account information or market data.
Default Settings for Non-Matching Engine Requests
- Cost per Request: 500 credits.
- Maximum Credits: 50,000 credits.
- Refill Rate: Credits are refilled at a rate that allows up to 20 requests per second (10,000 credits per second).
- Burst Capacity: Allows up to 100 requests at once, considering the maximum credit pool.
Burst and Refill Example (non-matching defaults)
- The burst counter starts with 50,000 credits (the maximum pool).
- Each request costs 500 credits; 100 back-to-back requests would fully drain the pool if you ignore refills.
- Credits refill continuously at 10 credits per millisecond (10,000 per second) even while you are bursting.
- If credits reach zero, new requests fail with
too_many_requests(code10028). - Sustained traffic at 20 req/s (20 × 500 = 10,000) matches the refill rate, so the pool stays stable. A rapid 100+ request burst can still trigger
10028if it outpaces the current credits. - If you hit
10028and need to cancel orders, waiting ~50 ms restores ~500 credits (10 credits/ms), enough to send a mass-cancel.
Matching Engine Requests
Each sub-account has an hourly updated rate limit, applicable across all books. Users can check their current rate limits via the /private/get_account_summary method.| Tier Level | 7-Day Trading Volume | Sustained Rate Limit (Requests/Second) | Burst Rate Limit | Description |
|---|---|---|---|---|
| Tier 1 | Over USD 25 million | 30 requests/second | 100 requests (burst) | Suitable for high-volume traders, allowing up to 100 requests in a rapid burst or a steady rate of 30 requests per second. |
| Tier 2 | Over USD 5 million | 20 requests/second | 50 requests (burst) | Designed for medium-volume traders, permitting up to 50 requests in a burst or 20 requests per second. |
| Tier 3 | Over USD 1 million | 10 requests/second | 30 requests (burst) | Appropriate for active traders, enabling up to 30 requests in a burst or 10 requests per second. |
| Tier 4 | Up to USD 1 million | 5 requests/second | 20 requests (burst) | For regular traders, allowing up to 20 requests in a burst or a steady rate of 5 requests per second. |
Automatic Rate Limit Updates
- We recalculate limits every hour. There is no “volume/7 per day” delay—the most recent 7-day trading volume is evaluated each hour for every sub-account that has trading stats.
- Volume window: the trailing 7-day trading volume determines your tier. Each hourly recalculation uses the latest 7-day sum.
- Upgrades: if your 7-day volume crosses a higher-tier threshold during an hourly check, we immediately move you to that tier (we can skip intermediate tiers; e.g., jumping from Tier 1 straight to Tier 4 is possible).
- Downgrades: during an hourly check, if your 7-day volume falls below your current tier’s threshold after being above it in the prior hour, the limits are lowered accordingly. This can also skip tiers if the 7-day volume drops multiple thresholds.
- Higher and more transparent limits that scale with your sub-account’s tier.
- Client-ID visibility, letting us distinguish heavy legitimate usage from abusive traffic—so rather than an immediate block, we can apply graduated safeguards if your limit is exceeded.
Production and Testnet environment operate on separate, independently-tracked rate-limit pools. Limits are not shared between environments—exceeding Testnet limits will not affect your Production credits, and vice-versa.
Checking current rate limits
Users can access the current rate limits by calling the /private/get_account_summary method and receivinglimits field in response. The configuration of rate limits can be either on a per-currency basis or a default set applied globally across all currencies. Per-currency limits are not the default setting and are enabled only for specific clients upon request.
Per-currency rate limits currently are used exclusively to decrease access limits for specific currencies when needed. They are not applied to increase rate limits.
Limits field
non_matching_engine: Describes rate limits applicable to requests that do not involve the matching engine. Defined by:
burst: The maximum number of requests permitted in a short burst.rate: The sustained number of requests allowed over time.
matching_engine: Outlines rate limits related to operations that utilize the matching engine, with the following structure:
Common Limits for All Configurations
Spot and Cancel Limits
spot: Applies to spot trading between two different currencies.cancel_all: Used when canceling all orders globally or by label without specifying a currency.
Global vs. Per-Currency Limits
-
When
limits_per_currency=false, limits apply globally:trading: Overall trading operationsmaximum_quotes: Total number of quotesmaximum_mass_quotes: Mass quoting operationsguaranteed_mass_quotes: Guaranteed mass quotes
-
When
limits_per_currency=true, limits are set per settlement currency under thematching_engineobject:- Each currency key includes:
trading: Per-currency trading limitsmaximum_quotes: Per-currency quote limitsmaximum_mass_quotes: Per-currency mass quoting limitsguaranteed_mass_quotes: Per-currency guaranteed mass quotes
- Each currency key includes:
Cancel Method Logic
- private/cancel_all: Uses the global
cancel_alllimit. - private/cancel_all_by_currency / instrument: Applies the relevant trading or spot limit for the specified currency or instrument.
- private/cancel_all_by_kind_or_type:
- No currency specified → uses cancel_all
- Specific currency → uses per-currency trading limit
- Spot instrument → uses spot limit
Matching Engine Requests Overview
All requests not listed below are treated as non-matching engine requests.private/buyprivate/sellprivate/editprivate/edit_by_labelprivate/cancelprivate/cancel_by_labelprivate/cancel_allprivate/cancel_all_by_instrumentprivate/cancel_all_by_currencyprivate/cancel_all_by_kind_or_typeprivate/close_positionprivate/verify_block_tradeprivate/execute_block_tradeprivate/move_positionsprivate/mass_quoteprivate/cancel_quotesprivate/add_block_rfq_quoteprivate/edit_block_rfq_quoteprivate/cancel_block_rfq_quoteprivate/cancel_all_block_rfq_quotes
FIX Message Types
new_order_singleorder_cancel_requestorder_mass_cancel_requestorder_cancel_replace_requestmass_quotequote_cancel