This guide will walk you through the complete lifecycle of placing and managing orders on Kalshi.
Prerequisites
Before you begin, you’ll need:
- A Kalshi account with API access configured
- Python with the
requests and cryptography libraries installed
- Your authentication functions set up (see our authentication guide)
This guide assumes you have the authentication code from our authentication guide, including the get() function for making authenticated requests.
Step 1: Find an Open Market
First, let’s find an open market to trade on.
# Get the first open market (no auth required for public market data)
response = requests.get('https://demo-api.kalshi.co/trade-api/v2/markets?limit=1&status=open')
market = response.json()['markets'][0]
print(f"Selected market: {market['ticker']}")
print(f"Title: {market['title']}")
Step 2: Place a Buy Order
Now let’s place an order to buy 1 YES contract for 1 cent (limit order). We’ll use a client_order_id to deduplicate orders - this allows you to identify duplicate orders before receiving the server-generated order_id in the response.
import uuid
def post(private_key, api_key_id, path, data, base_url=BASE_URL):
"""Make an authenticated POST request to the Kalshi API."""
timestamp = str(int(datetime.datetime.now().timestamp() * 1000))
signature = create_signature(private_key, timestamp, "POST", path)
headers = {
'KALSHI-ACCESS-KEY': api_key_id,
'KALSHI-ACCESS-SIGNATURE': signature,
'KALSHI-ACCESS-TIMESTAMP': timestamp,
'Content-Type': 'application/json'
}
return requests.post(base_url + path, headers=headers, json=data)
# Place a buy order for 1 YES contract at 1 cent
order_data = {
"ticker": market['ticker'],
"action": "buy",
"side": "yes",
"count": 1,
"type": "limit",
"yes_price": 1,
"client_order_id": str(uuid.uuid4()) # Unique ID for deduplication
}
response = post(private_key, API_KEY_ID, '/trade-api/v2/portfolio/orders', order_data)
if response.status_code == 201:
order = response.json()['order']
print(f"Order placed successfully!")
print(f"Order ID: {order['order_id']}")
print(f"Client Order ID: {order_data['client_order_id']}")
print(f"Status: {order['status']}")
else:
print(f"Error: {response.status_code} - {response.text}")
Complete Example Script
Here’s a complete script that creates your first order:
import requests
import uuid
# Assumes you have the authentication code from the prerequisites
# Add POST function to your existing auth code
def post(private_key, api_key_id, path, data, base_url=BASE_URL):
"""Make an authenticated POST request to the Kalshi API."""
timestamp = str(int(datetime.datetime.now().timestamp() * 1000))
signature = create_signature(private_key, timestamp, "POST", path)
headers = {
'KALSHI-ACCESS-KEY': api_key_id,
'KALSHI-ACCESS-SIGNATURE': signature,
'KALSHI-ACCESS-TIMESTAMP': timestamp,
'Content-Type': 'application/json'
}
return requests.post(base_url + path, headers=headers, json=data)
# Step 1: Find an open market
print("Finding an open market...")
response = requests.get('https://demo-api.kalshi.co/trade-api/v2/markets?limit=1&status=open')
market = response.json()['markets'][0]
print(f"Selected: {market['ticker']} - {market['title']}")
# Step 2: Place a buy order
print("\nPlacing order...")
client_order_id = str(uuid.uuid4())
order_data = {
"ticker": market['ticker'],
"action": "buy",
"side": "yes",
"count": 1,
"type": "limit",
"yes_price": 1,
"client_order_id": client_order_id
}
response = post(private_key, API_KEY_ID, '/trade-api/v2/portfolio/orders', order_data)
if response.status_code == 201:
order = response.json()['order']
print(f"Order placed successfully!")
print(f"Order ID: {order['order_id']}")
print(f"Client Order ID: {client_order_id}")
print(f"Status: {order['status']}")
else:
print(f"Error: {response.status_code} - {response.text}")
Important Notes
Client Order ID
The client_order_id field is crucial for order deduplication:
- Generate a unique ID (like UUID4) for each order before submission
- If network issues occur, you can resubmit with the same
client_order_id
- The API will reject duplicate submissions, preventing accidental double orders
- Store this ID locally to track orders before receiving the server’s
order_id
Error Handling
Common errors and how to handle them:
401 Unauthorized: Check your API keys and signature generation
400 Bad Request: Verify your order parameters (price must be 1-99 cents)
409 Conflict: Order with this client_order_id already exists
429 Too Many Requests: You’ve hit the rate limit - slow down your requests
Next Steps
Now that you’ve created your first order, you can:
- Check order status using the
/portfolio/orders/{order_id} endpoint
- List all your orders with
/portfolio/orders
- Amend your order price or quantity using PUT
/portfolio/orders/{order_id}
- Cancel orders using DELETE
/portfolio/orders/{order_id}
- Implement WebSocket connections for real-time updates
- Build automated trading strategies
For more information, check out: