# API Rate Limits

## IP-Based Rate Limits

All REST API requests consume **weight** from a fixed 1-minute window. Once the total weight consumed within the window reaches the limit, subsequent requests are rejected until the window resets.

> Endpoints not listed below default to weight **20**.

### Overall Limits

| Dimension                | Limit    |
| ------------------------ | -------- |
| Weight per minute per IP | **1200** |

***

### Public Endpoints

| Endpoint               | Weight | Notes                                      |
| ---------------------- | ------ | ------------------------------------------ |
| Query user rate limits | **20** | `GET /api/v1/user/{userAddress}/ratelimit` |

### Spot Market Endpoints

| Endpoint             | Weight          | Notes                                   |
| -------------------- | --------------- | --------------------------------------- |
| Query symbols        | **2**           |                                         |
| Query coins          | **2**           |                                         |
| Query tickers        | **2**           |                                         |
| Query mini tickers   | **2**           |                                         |
| Query book tickers   | **2**           |                                         |
| Query order book     | **5 / 10 / 20** | depth ≤100 → 5, 101–500 → 10, >500 → 20 |
| Query candles/klines | **20**          |                                         |
| Query recent trades  | **20**          |                                         |

### Spot Accounts Endpoints

| Endpoint                       | Weight | Notes                           |
| ------------------------------ | ------ | ------------------------------- |
| Query balances                 | **5**  |                                 |
| Query open orders              | **5**  |                                 |
| Query state for frontend       | **5**  |                                 |
| Query API Keys                 | **5**  |                                 |
| Query fee rate                 | **2**  |                                 |
| Query order history            | **20** | + 1 extra per 20 items returned |
| Query user trades              | **20** | + 1 extra per 20 items returned |
| Transfer asset to EVM or perps | **10** |                                 |

### Spot Trading Endpoints

| Endpoint                | Weight            | Notes                |
| ----------------------- | ----------------- | -------------------- |
| Place multiple orders   | `1 + floor(N/40)` | N = number of orders |
| Cancel multiple orders  | `1 + floor(N/40)` | N = number of orders |
| Replace multiple orders | `1 + floor(N/40)` | N = number of orders |
| Schedule cancel orders  | **1**             |                      |

***

### Perps Market Endpoints

| Endpoint             | Weight          | Notes                                   |
| -------------------- | --------------- | --------------------------------------- |
| Query symbols        | **2**           |                                         |
| Query coins          | **2**           |                                         |
| Query tickers        | **2**           |                                         |
| Query mini tickers   | **2**           |                                         |
| Query mark prices    | **2**           |                                         |
| Query book tickers   | **2**           |                                         |
| Query order book     | **5 / 10 / 20** | depth ≤100 → 5, 101–500 → 10, >500 → 20 |
| Query candles/klines | **20**          |                                         |
| Query recent trades  | **20**          |                                         |

### Perps Account Endpoints

| Endpoint                 | Weight | Notes                           |
| ------------------------ | ------ | ------------------------------- |
| Query balances           | **5**  |                                 |
| Query open orders        | **5**  |                                 |
| Query open positions     | **5**  |                                 |
| Query state for frontend | **5**  |                                 |
| Query API Keys           | **5**  |                                 |
| Query fee rate           | **2**  |                                 |
| Query order history      | **20** | + 1 extra per 20 items returned |
| Query position history   | **20** | + 1 extra per 20 items returned |
| Query trades             | **20** | + 1 extra per 20 items returned |
| Query funding history    | **20** | + 1 extra per 20 items returned |
| Transfer asset to spot   | **10** |                                 |

### Perps Trading Endpoints

| Endpoint                | Weight            | Notes                |
| ----------------------- | ----------------- | -------------------- |
| Place multiple orders   | `1 + floor(N/40)` | N = number of orders |
| Cancel multiple orders  | `1 + floor(N/40)` | N = number of orders |
| Replace multiple orders | `1 + floor(N/40)` | N = number of orders |
| Modify TP/SL order      | **1**             |                      |
| Schedule cancel orders  | **1**             |                      |
| Update leverage         | **1**             |                      |
| Update isolated margin  | **1**             |                      |

***

### Dynamic Weight Rules

#### Orderbook Depth

| Depth (`limit`) | Weight |
| --------------- | ------ |
| ≤ 100 (default) | **5**  |
| 101 – 500       | **10** |
| > 500           | **20** |

#### Batch Order Formula

```
weight = 1 + floor(batch_size / 40)
```

| Batch size | Weight |
| ---------- | ------ |
| 1 – 39     | **1**  |
| 40 – 79    | **2**  |
| 80 – 119   | **3**  |

#### History Extra Weight

History endpoints incur additional weight **after** the response, based on items returned:

```
extra_weight = floor(items_returned / 20)
```

#### Kline Cache Miss Extra Weight

Kline requests have a base weight of **20**. Additional weight may apply based on the number of rows returned:

```
extra_weight = max(1, floor(rows_returned / 25))
```

***

### Order Placement Limits

Separate from the weight budget:

| Client type  | Limit                                              | Scope       |
| ------------ | -------------------------------------------------- | ----------- |
| API key      | **600 orders / minute** and **20 orders / second** | per account |
| Web (no key) | **60 orders / minute**                             | per account |

For batched requests, the number of orders counted against these limits is the batch length: `order_count = len(batch)`.

***

### WebSocket Limits

Separate from the REST weight budget:

| Limit                                  | Value    |
| -------------------------------------- | -------- |
| Concurrent connections per IP          | **10**   |
| New connections per IP per minute      | **30**   |
| Subscriptions per IP (all connections) | **1000** |
| Unique users per IP                    | **10**   |
| Messages per IP per minute             | **2000** |
| Messages per connection per minute     | **2000** |
| Inflight requests per IP               | **100**  |

***

## Address-Based Rate Limits

Address-based limits apply per user address and only affect **actions** (order placement, cancellation, etc.), not info/query requests.

The rate limiting logic allows **1 request per 1 USDC traded** cumulatively since address inception. For example, with an order value of 100 USDC, this requires a fill rate of 1%. Each address starts with an initial buffer of **10,000 requests**.

When rate limited, an address is allowed **one request every 10 seconds**.

Cancels have a higher cumulative limit to ensure open orders can always be wound down:

```
cancel_limit = min(limit + 100000, limit * 2)
```

where `limit` is the default limit for other actions.

Each user has a default open order limit of 1000 across all symbols combined (spot + perps).

***

## Batched Requests

A batched request containing **N** orders (or cancels) is counted differently depending on the rate-limit dimension:

| Dimension           | Counted as                                         |
| ------------------- | -------------------------------------------------- |
| IP-based weight     | **1 request** (weight per the batch formula above) |
| Address-based limit | **N requests** (one per order/cancel in the batch) |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://sodex.com/documentation/trading-api/api-rate-limits.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
