Complete API documentation for the Interactive Brokers Trading API wrapper.
- Overview
- Base URL & Authentication
- GET Endpoints
- POST Endpoints
- Response Formats
- Error Handling
- Code Examples
- Best Practices
The IBKR API provides a RESTful interface to Interactive Brokers trading platform. All endpoints are asynchronous and return JSON responses.
Base URL: http://localhost:8000 (default)
Interactive Documentation:
- Swagger UI:
http://localhost:8000/docs - ReDoc:
http://localhost:8000/redoc
Currently, the API runs locally without authentication. Ensure:
- IB Gateway/TWS is running
- API is enabled on port 4002 (Paper Trading) or 4001 (Live Trading)
- Trusted IP 127.0.0.1 is configured
Get account summary including balance and available cash.
Request:
GET /accountResponse:
{
"balance": 201879.04,
"cash": 200000.0
}Response Fields:
balance(float): Net liquidation value / total account equitycash(float): Available funds for trading
Example:
curl http://localhost:8000/accountGet all open positions in the account.
Request:
GET /positionsResponse:
{
"positions": [
{
"symbol": "AAPL",
"qty": 10,
"avg_cost": 230.50,
"market_value": 2305.00
},
{
"symbol": "MSFT",
"qty": -5,
"avg_cost": 350.20,
"market_value": -1751.00
}
]
}Response Fields:
positions(array): List of position objectssymbol(string): Stock symbolqty(float): Position quantity (positive = long, negative = short)avg_cost(float): Average cost per sharemarket_value(float): Total position value (qty × avg_cost)
Example:
curl http://localhost:8000/positionsGet all pending orders (orders that are not yet filled or cancelled).
Request:
GET /ordersResponse:
{
"orders": [
{
"orderId": 12345,
"permId": 1788680597,
"symbol": "AAPL",
"action": "BUY",
"quantity": 10,
"type": "LMT",
"trigger": 230.00,
"status": "SUBMITTED"
},
{
"orderId": 12346,
"permId": 1788680598,
"symbol": "TSLA",
"action": "SELL",
"quantity": 5,
"type": "STP",
"trigger": 250.00,
"status": "PENDINGSUBMIT"
}
]
}Response Fields:
orders(array): List of pending order objectsorderId(int): Temporary order ID (changes on restart)permId(int): Permanent order ID (use this for cancellation)symbol(string): Stock symbolaction(string): "BUY" or "SELL"quantity(float): Number of sharestype(string): Order type ("LMT", "MKT", "STP", etc.)trigger(float|string): Limit price, stop price, or "—" for market ordersstatus(string): Order status ("PENDINGSUBMIT", "PRESUBMITTED", "SUBMITTED", "APIPENDING")
Order Statuses:
PENDINGSUBMIT: Order is being submittedPRESUBMITTED: Order validated, waiting to be sentSUBMITTED: Order sent to exchangeAPIPENDING: Order pending API confirmation
Example:
curl http://localhost:8000/ordersGet execution history (filled orders) from multiple sources.
Request:
GET /executions
GET /executions?symbol=AAPLQuery Parameters:
symbol(string, optional): Filter executions by symbol (case-insensitive)
Response:
{
"executions": [
{
"symbol": "AAPL",
"side": "BUY",
"qty": 10,
"price": 230.50,
"time": "20240115 14:30:25",
"orderRef": "my_trade_001",
"source": "reqExecutions"
},
{
"symbol": "MSFT",
"side": "SELL",
"qty": 5,
"price": 350.20,
"orderId": 12345,
"orderRef": "strategy_2",
"source": "trades()"
}
]
}Response Fields:
executions(array): List of execution objectssymbol(string): Stock symbolside(string): "BUY" or "SELL"qty(float): Number of shares executedprice(float): Execution pricetime(string, optional): Execution timestamp (format: "YYYYMMDD HH:MM:SS")orderId(int, optional): Order IDorderRef(string, optional): Order reference stringsource(string): Data source ("reqExecutions", "trades()", "reqCompletedOrders", "positions()")
Note: Execution history resets when IB Gateway restarts. Consider saving executions to your own database.
Example:
# All executions
curl http://localhost:8000/executions
# Filtered by symbol
curl "http://localhost:8000/executions?symbol=AAPL"Place a limit order (buy/sell at a specific price or better).
Request:
POST /order/limit
Content-Type: application/jsonRequest Body:
{
"symbol": "AAPL",
"action": "BUY",
"quantity": 10,
"limit_price": 230.00,
"order_ref": "my_trade_001"
}Request Fields:
symbol(string, required): Stock symbol (e.g., "AAPL")action(string, required): "BUY" or "SELL"quantity(float, required): Number of shareslimit_price(float, required): Limit priceorder_ref(string, optional): Custom reference string for tracking
Response:
{
"status": "✅ Limit order sent",
"permId": 1788680597
}Response Fields:
status(string): Success messagepermId(int): Permanent order ID (use this to cancel the order)
Example:
curl -X POST http://localhost:8000/order/limit \
-H "Content-Type: application/json" \
-d '{
"symbol": "AAPL",
"action": "BUY",
"quantity": 10,
"limit_price": 230.00,
"order_ref": "my_trade_001"
}'Error Responses:
400 Bad Request: Invalid request parameters500 Internal Server Error: Order placement failed (check IB Gateway connection)
Place a market order (buy/sell at current market price).
Request:
POST /order/market
Content-Type: application/jsonRequest Body:
{
"symbol": "AAPL",
"action": "BUY",
"quantity": 10,
"order_ref": "market_trade_001"
}Request Fields:
symbol(string, required): Stock symbolaction(string, required): "BUY" or "SELL"quantity(float, required): Number of sharesorder_ref(string, optional): Custom reference string
Response:
{
"status": "✅ Market order sent",
"permId": 1788680598
}Example:
curl -X POST http://localhost:8000/order/market \
-H "Content-Type: application/json" \
-d '{
"symbol": "AAPL",
"action": "BUY",
"quantity": 10,
"order_ref": "market_trade_001"
}'Note: Market orders execute immediately at the current market price. Use with caution as prices can vary.
Place a stop order (stop-loss order that triggers when price reaches stop price).
Request:
POST /order/stop
Content-Type: application/jsonRequest Body:
{
"symbol": "AAPL",
"action": "SELL",
"quantity": 10,
"stop_price": 225.00,
"order_ref": "stop_loss_001"
}Request Fields:
symbol(string, required): Stock symbolaction(string, required): "BUY" or "SELL"quantity(float, required): Number of sharesstop_price(float, required): Stop price (triggers when price reaches this level)order_ref(string, optional): Custom reference string
Response:
{
"status": "✅ Stop order sent",
"permId": 1788680599
}Example:
curl -X POST http://localhost:8000/order/stop \
-H "Content-Type: application/json" \
-d '{
"symbol": "AAPL",
"action": "SELL",
"quantity": 10,
"stop_price": 225.00,
"order_ref": "stop_loss_001"
}'Stop Order Behavior:
- Stop-Loss (SELL): Triggers when price falls to or below stop price
- Stop-Buy (BUY): Triggers when price rises to or above stop price
Place a bracket order (entry order with automatic stop-loss and take-profit).
Request:
POST /order/bracket
Content-Type: application/jsonRequest Body:
{
"symbol": "AAPL",
"action": "BUY",
"quantity": 10,
"entry_price": 230.00,
"stop_loss": 225.00,
"take_profit": 240.00,
"order_ref": "protected_trade_001"
}Request Fields:
symbol(string, required): Stock symbolaction(string, required): "BUY" or "SELL"quantity(float, required): Number of sharesentry_price(float, required): Entry limit pricestop_loss(float, required): Stop-loss pricetake_profit(float, required): Take-profit priceorder_ref(string, optional): Custom reference string
Response:
{
"status": "✅ Bracket order sent",
"permIds": [1788680600, 1788680601, 1788680602]
}Response Fields:
status(string): Success messagepermIds(array): List of 3 permanent order IDs:- Parent order (entry)
- Stop-loss order
- Take-profit order
Example:
curl -X POST http://localhost:8000/order/bracket \
-H "Content-Type: application/json" \
-d '{
"symbol": "AAPL",
"action": "BUY",
"quantity": 10,
"entry_price": 230.00,
"stop_loss": 225.00,
"take_profit": 240.00,
"order_ref": "protected_trade_001"
}'Bracket Order Behavior:
- Entry order is placed first
- When entry fills, stop-loss and take-profit orders are automatically activated
- Only one of the exit orders will execute (whichever price is hit first)
- The other exit order is automatically cancelled
Cancel an order by its permanent ID.
Request:
POST /order/cancel
Content-Type: application/jsonRequest Body:
{
"perm_id": 1788680597
}Request Fields:
perm_id(int, required): Permanent order ID (from order placement response)
Response:
{
"status": "✅ Order 1788680597 cancelled"
}Example:
curl -X POST http://localhost:8000/order/cancel \
-H "Content-Type: application/json" \
-d '{"perm_id": 1788680597}'Error Responses:
404 Not Found: Order not found or already filled/cancelled500 Internal Server Error: Cancellation failed
Note: You can only cancel orders that are pending. Filled or already cancelled orders cannot be cancelled.
All successful requests return HTTP 200 OK with JSON body:
{
"status": "✅ Success message",
"data": { ... }
}Errors return appropriate HTTP status codes with JSON body:
{
"detail": "Error message description"
}Common Status Codes:
200 OK: Request successful400 Bad Request: Invalid request parameters404 Not Found: Resource not found500 Internal Server Error: Server error (check IB Gateway connection)
If IB Gateway is not running or not accessible:
{
"detail": "Failed to connect to IB Gateway"
}Solution: Ensure IB Gateway/TWS is running and API is enabled.
If order placement fails:
{
"detail": "Failed to place limit order: Could not qualify contract for symbol: INVALID"
}Common Causes:
- Invalid symbol
- Insufficient funds
- Market closed
- Contract not found
If cancellation fails:
{
"detail": "Order not found or already filled"
}Common Causes:
- Order already filled
- Order already cancelled
- Invalid permId
import requests
BASE_URL = "http://localhost:8000"
# Get account summary
response = requests.get(f"{BASE_URL}/account")
account = response.json()
print(f"Balance: ${account['balance']:,.2f}")
print(f"Cash: ${account['cash']:,.2f}")
# Place limit order
order_data = {
"symbol": "AAPL",
"action": "BUY",
"quantity": 10,
"limit_price": 230.00,
"order_ref": "python_trade_001"
}
response = requests.post(f"{BASE_URL}/order/limit", json=order_data)
order_result = response.json()
print(f"Order placed: {order_result['permId']}")
# Get pending orders
response = requests.get(f"{BASE_URL}/orders")
orders = response.json()
print(f"Pending orders: {len(orders['orders'])}")
# Cancel order
cancel_data = {"perm_id": order_result['permId']}
response = requests.post(f"{BASE_URL}/order/cancel", json=cancel_data)
print(response.json()['status'])const axios = require('axios');
const BASE_URL = 'http://localhost:8000';
async function main() {
// Get account summary
const account = await axios.get(`${BASE_URL}/account`);
console.log(`Balance: $${account.data.balance.toLocaleString()}`);
console.log(`Cash: $${account.data.cash.toLocaleString()}`);
// Place limit order
const orderData = {
symbol: 'AAPL',
action: 'BUY',
quantity: 10,
limit_price: 230.00,
order_ref: 'js_trade_001'
};
const orderResult = await axios.post(`${BASE_URL}/order/limit`, orderData);
console.log(`Order placed: ${orderResult.data.permId}`);
// Get pending orders
const orders = await axios.get(`${BASE_URL}/orders`);
console.log(`Pending orders: ${orders.data.orders.length}`);
// Cancel order
const cancelResult = await axios.post(`${BASE_URL}/order/cancel`, {
perm_id: orderResult.data.permId
});
console.log(cancelResult.data.status);
}
main().catch(console.error);# Get account
curl http://localhost:8000/account
# Place limit order
curl -X POST http://localhost:8000/order/limit \
-H "Content-Type: application/json" \
-d '{
"symbol": "AAPL",
"action": "BUY",
"quantity": 10,
"limit_price": 230.00
}'
# Get orders
curl http://localhost:8000/orders
# Cancel order
curl -X POST http://localhost:8000/order/cancel \
-H "Content-Type: application/json" \
-d '{"perm_id": 1788680597}'Always include order_ref to track your orders:
import time
order_ref = f"strategy_1_{int(time.time())}"
order_data = {
"symbol": "AAPL",
"action": "BUY",
"quantity": 10,
"limit_price": 230.00,
"order_ref": order_ref
}Verify sufficient funds before placing orders:
account = requests.get(f"{BASE_URL}/account").json()
required_cash = quantity * limit_price
if account['cash'] >= required_cash:
# Place order
pass
else:
print("Insufficient funds!")Protect your trades with automatic stop-loss and take-profit:
bracket_data = {
"symbol": "AAPL",
"action": "BUY",
"quantity": 10,
"entry_price": 230.00,
"stop_loss": 225.00, # -2.2% risk
"take_profit": 240.00 # +4.3% reward
}Execution history resets when IB Gateway restarts. Save executions:
executions = requests.get(f"{BASE_URL}/executions").json()
for exec in executions['executions']:
database.save(exec) # Your database logicAlways handle potential errors:
try:
response = requests.post(f"{BASE_URL}/order/limit", json=order_data)
response.raise_for_status()
result = response.json()
print(f"Order placed: {result['permId']}")
except requests.exceptions.HTTPError as e:
print(f"Error: {e.response.json()['detail']}")
except Exception as e:
print(f"Unexpected error: {e}")Check order status before cancelling:
orders = requests.get(f"{BASE_URL}/orders").json()
pending_perm_ids = [o['permId'] for o in orders['orders']]
if perm_id in pending_perm_ids:
# Safe to cancel
requests.post(f"{BASE_URL}/order/cancel", json={"perm_id": perm_id})Always test with Paper Trading (port 4002) before using Live Trading (port 4001).
| Order Type | Endpoint | Use Case |
|---|---|---|
| Limit | /order/limit |
Buy/sell at specific price or better |
| Market | /order/market |
Immediate execution at market price |
| Stop | /order/stop |
Stop-loss protection |
| Bracket | /order/bracket |
Entry + stop-loss + take-profit |
Currently, there are no explicit rate limits. However:
- Orders are processed sequentially (thread-safe queue)
- Each request opens/closes IB connection
- Avoid rapid-fire requests (add delays if needed)
Symptoms: 500 Internal Server Error or connection timeout
Solutions:
- Verify IB Gateway/TWS is running
- Check API is enabled (Settings → API → Settings)
- Verify port: 4002 (Paper) or 4001 (Live)
- Add 127.0.0.1 to trusted IPs
- Test connection:
telnet 127.0.0.1 4002
Common Causes:
- Price too far from market
- Market closed (9:30 AM - 4:00 PM ET)
- Insufficient funds
- Stock halted/delisted
Solution: Check order status via /orders endpoint
Explanation: Execution history resets when IB Gateway restarts
Solution: Save executions to your own database
- Interactive API Docs: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
- IB Gateway Setup: See
IB_GATEWAY.md - IB API Documentation: https://interactivebrokers.github.io/tws-api/
- ib_insync Documentation: https://ib-insync.readthedocs.io/
For issues or questions:
- Check the troubleshooting section
- Review IB Gateway setup in
IB_GATEWAY.md - Test with Paper Trading first
- Check IB Gateway logs for detailed errors