> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bullionwale.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Trading limits

> Your weight allocation per metal and how much of it your open position uses.

Bullionwale gives your account a **weight** allocation per metal. Your open net position (buys minus sells) uses it, and an order that would take it past the allocation is refused with `400 limit_exceeded`. It is weight, not money: there is no cash balance, no margin and no rupee limit. `GET /limits` shows the allocation and how much of it is used, so your program can size an order before it sends it.

| Call | Endpoint | Scope |
| - | - | - |
| [Trading limits](#read-your-limits) | `GET /limits` | `account:read` |

| Environment | Endpoint |
| - | - |
| Test | `/api/trading/test/v1/limits` |
| Production | `/api/trading/v1/limits` |

## The limits object

One entry per metal, `gold` and `silver`:

| Field | Type | Meaning |
| - | - | - |
| `limit` | string | Your allocation, in `unit`. `0.0000` means you cannot open a position in that metal. |
| `used` | string | The size of your open net position, in `unit`: buys minus sells, without the sign. |
| `free` | string | `limit` minus `used`, never below zero: how much more exposure an order may add. |
| `reserved` | string | What your resting limit orders would need if they all triggered. For planning only: it is **not** deducted from `free`. |
| `unit` | string | `g` for gold, `kg` for silver. |

Every weight is a decimal string with 4 decimals, such as `"960.0000"`. Parse it as a decimal, not a float. The unit is the **metal's**: gold in grams and silver in kilograms, whatever symbol you trade (see [Units and pricing](/units-and-pricing)).

## Read your limits

```bash curl theme={null}
curl -s https://api.bullionwale.com/api/trading/test/v1/limits \
  -H "X-API-Key: $BULLIONWALE_API_KEY"
```

```python Python theme={null}
import os
from decimal import Decimal

import requests

BASE = "https://api.bullionwale.com/api/trading/test/v1"
HEADERS = {"X-API-Key": os.environ["BULLIONWALE_API_KEY"]}

lim = requests.get(f"{BASE}/limits", headers=HEADERS, timeout=10).json()
print("gold free:", Decimal(lim["gold"]["free"]), lim["gold"]["unit"])
```

```json 200 OK theme={null}
{
  "gold": {"limit": "1000.0000", "used": "40.0000", "free": "960.0000",
           "reserved": "20.0000", "unit": "g"},
  "silver": {"limit": "5.0000", "used": "2.0000", "free": "3.0000",
             "reserved": "0.0000", "unit": "kg"}
}
```

This is the test path, so the figures are the **test book's**: the account's allocation is 1,000 g of gold and its test orders hold a net 40 g, so a test order may add up to 960 g more. Its resting test limit orders would add 20 g if they all triggered. On the production path the same fields describe your real position.

## How the allocation is applied

* **It caps open exposure, not turnover.** Buys and sells net off: after buying 40 g and selling 40 g of gold, `used` is back to `0.0000`.
* **An order that adds exposure must fit in `free`.** With `free` at `960.0000` g, a 1,000 g gold buy is refused with `400 limit_exceeded`; a 960 g buy is accepted.
* **An order that reduces exposure is always allowed**, even when `used` is above `limit` (for example after Bullionwale lowered your allocation). With a net long of 40 g, a 40 g sell always goes through.
* **Pending orders count.** In production, an order still `pending` already counts towards `used`.
* **Resting limit orders do not hold allocation.** They count only when they trigger and book; `reserved` shows what they would need, so keep that much `free` if you want them all to be able to fire. When a limit order triggers, it is checked against your allocation at that moment, like a market order (see [Limit orders](/api-reference/limit-orders/overview)).
* **No allocation, no trading.** An account without an allocation shows `0.0000` for both metals and cannot open a position.

To change your allocation, ask your Bullionwale relationship manager or the Bullionwale desk.

## Test and production

Both environments return your **real** allocation as `limit`. In **production**, `used`, `free` and `reserved` describe your real position and your real resting limit orders.

In **test**, `used`, `free` and `reserved` come from your **test** book: your test orders (the same net position as the test `GET /positions`, see [Positions](/api-reference/positions/overview)) and your pending test limit orders. That is exactly how a test order's weight check works, so test `free` is the room a test order has: a test buy larger than `free` is refused with `400 limit_exceeded`, quoting the same figure. Real orders never change the test numbers, and test orders never change the production ones.

## Errors

| Code | Status | Meaning |
| - | - | - |
| `insufficient_scope` | 403 | The key does not have `account:read`. |
| `rate_limited` | 429 | The key's read budget is used up. Wait `Retry-After` seconds. |

`GET /limits` itself refuses nothing else. The refusal it helps you avoid is `400 limit_exceeded` on `POST /orders`. Every code is in the [Error reference](/api-reference/error-reference).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.