How to place an order via the Kite Connect REST API
The Kite Connect API exposes a clean REST interface for order management that supports all major Indian exchanges and order types. Once you have a valid access_token (see How to generate the request_token and access_token), you can place, modify, and cancel orders programmatically using the kiteconnect Python SDK. This guide covers the full order-placement workflow, parameter reference, and production-grade error handling.
Order model in Kite Connect
Kite Connect organises every order placement call around four orthogonal dimensions.
Variety determines how the order is handled at the OMS level. regular is the standard intraday or delivery order. amo (After Market Order) is queued outside market hours and submitted at open. co (Cover Order) is a two-legged order with a mandatory stop-loss leg. iceberg splits a large order into smaller disclosed child orders.
Exchange specifies the market segment: NSE or BSE for equities, NFO or BFO for equity derivatives, CDS for currency derivatives, MCX or NCDEX for commodity derivatives, and MF for mutual funds.
Product indicates the margin treatment. CNC (Cash and Carry) is for delivery equity positions with no intraday leverage. MIS (Margin Intraday Square-off) is for intraday positions with leverage, auto-squared off before market close. NRML is for overnight derivative positions (F&O, currency, commodity).
Order type controls execution. MARKET executes immediately at the best available price. LIMIT executes only at or better than a specified price. SL is a stop-loss limit order that triggers when the market price crosses the trigger, then places a limit order. SL-M is a stop-loss market order that triggers and executes at market price.
Step-by-step procedure
Authenticate and set the access_token
import os
from kiteconnect import KiteConnect
API_KEY = os.environ["KITE_API_KEY"]
ACCESS_TOKEN = os.environ["KITE_ACCESS_TOKEN"] # persisted from daily login
kite = KiteConnect(api_key=API_KEY)
kite.set_access_token(ACCESS_TOKEN)
If you have not yet automated the daily token generation, see How to authenticate Kite Connect with TOTP automation for a headless approach.
Place a simple market order
The minimal call to buy 1 share of Reliance Industries on NSE in delivery mode:
order_id = kite.place_order(
variety=kite.VARIETY_REGULAR,
exchange=kite.EXCHANGE_NSE,
tradingsymbol="RELIANCE",
transaction_type=kite.TRANSACTION_TYPE_BUY,
quantity=1,
product=kite.PRODUCT_CNC,
order_type=kite.ORDER_TYPE_MARKET,
)
print("Order placed. Order ID:", order_id)
kite.VARIETY_REGULAR, kite.EXCHANGE_NSE, and so on are string constants defined in the SDK for readability. You may also pass the raw strings "regular", "NSE", etc.
Place a limit order
order_id = kite.place_order(
variety=kite.VARIETY_REGULAR,
exchange=kite.EXCHANGE_NSE,
tradingsymbol="INFY",
transaction_type=kite.TRANSACTION_TYPE_BUY,
quantity=10,
product=kite.PRODUCT_MIS,
order_type=kite.ORDER_TYPE_LIMIT,
price=1450.00,
)
For a LIMIT order, price is mandatory. The order sits in the order book until the market price reaches your limit price or the session ends.
Place a stop-loss order
order_id = kite.place_order(
variety=kite.VARIETY_REGULAR,
exchange=kite.EXCHANGE_NSE,
tradingsymbol="HDFCBANK",
transaction_type=kite.TRANSACTION_TYPE_SELL,
quantity=5,
product=kite.PRODUCT_MIS,
order_type=kite.ORDER_TYPE_SL,
price=1600.00, # limit price after trigger fires
trigger_price=1605.00,
)
For SL and SL-M orders, trigger_price is mandatory. The trigger_price must be above price for a sell stop-loss and below price for a buy stop-loss.
Place an F&O order (NRML overnight)
order_id = kite.place_order(
variety=kite.VARIETY_REGULAR,
exchange=kite.EXCHANGE_NFO,
tradingsymbol="NIFTY24JUNFUT", # exact symbol from instruments CSV
transaction_type=kite.TRANSACTION_TYPE_BUY,
quantity=50, # one lot of NIFTY futures
product=kite.PRODUCT_NRML,
order_type=kite.ORDER_TYPE_MARKET,
)
The tradingsymbol for derivatives must be the exact symbol string from the Kite instruments CSV dump. Download it daily from https://api.kite.trade/instruments and filter by exchange.
Place an After Market Order (AMO)
order_id = kite.place_order(
variety=kite.VARIETY_AMO,
exchange=kite.EXCHANGE_NSE,
tradingsymbol="TCS",
transaction_type=kite.TRANSACTION_TYPE_BUY,
quantity=2,
product=kite.PRODUCT_CNC,
order_type=kite.ORDER_TYPE_LIMIT,
price=3800.00,
)
AMO orders can be placed between 3:45 PM and 8:57 AM IST. They are routed to the exchange at market open. There is no AMO window on NSE/BSE between 8:57 AM and 9:15 AM.
Confirm order placement
# Fetch the status of the specific order
history = kite.order_history(order_id)
for update in history:
print(update["status"], update["status_message"])
# Or fetch all orders for the day
orders = kite.orders()
for o in orders:
if o["order_id"] == order_id:
print(o["status"], o["average_price"])
A freshly placed order typically shows status OPEN or COMPLETE within a fraction of a second for market orders during regular trading hours.
Handle errors
from kiteconnect.exceptions import (
InputException,
OrderException,
NetworkException,
GeneralException,
)
try:
order_id = kite.place_order(
variety=kite.VARIETY_REGULAR,
exchange=kite.EXCHANGE_NSE,
tradingsymbol="RELIANCE",
transaction_type=kite.TRANSACTION_TYPE_BUY,
quantity=1,
product=kite.PRODUCT_CNC,
order_type=kite.ORDER_TYPE_MARKET,
)
print("Order placed:", order_id)
except InputException as e:
print("Bad input parameters:", e)
except OrderException as e:
print("Order rejected by OMS:", e)
except NetworkException as e:
print("Network error, retry logic here:", e)
except GeneralException as e:
print("Unhandled Kite error:", e)
Full parameter reference
| Parameter | Type | Required | Notes |
|---|---|---|---|
variety | str | Yes | regular, amo, co, iceberg |
exchange | str | Yes | NSE, BSE, NFO, BFO, CDS, MCX, NCDEX, MF |
tradingsymbol | str | Yes | Exact symbol from instruments CSV; case-sensitive |
transaction_type | str | Yes | BUY or SELL |
quantity | int | Yes | Must be a multiple of the lot size for derivatives |
product | str | Yes | CNC, MIS, NRML |
order_type | str | Yes | MARKET, LIMIT, SL, SL-M |
price | float | Conditional | Required for LIMIT and SL |
trigger_price | float | Conditional | Required for SL and SL-M |
disclosed_quantity | int | No | Portion of quantity to disclose in the market |
validity | str | No | DAY (default) or IOC (Immediate or Cancel) |
tag | str | No | User-defined tag up to 20 characters; useful for strategy identification |
iceberg_legs | int | Conditional | Required for iceberg variety; 2 to 10 |
iceberg_quantity | int | Conditional | Quantity per iceberg leg |
Modifying and cancelling orders
# Modify a pending limit order price
kite.modify_order(
variety=kite.VARIETY_REGULAR,
order_id=order_id,
price=1445.00,
)
# Cancel a pending order
kite.cancel_order(variety=kite.VARIETY_REGULAR, order_id=order_id)
Only orders with status OPEN or PENDING can be modified or cancelled. A COMPLETE or REJECTED order cannot be changed.
What can go wrong
InputException: No such instrument. Thetradingsymbolis wrong or the instrument is not available on the specified exchange. Download the fresh instruments CSV and verify the exact symbol.OrderException: Insufficient funds. Your Zerodha account does not have enough free margin or cash. Checkkite.margins()before placing the order.OrderException: RMS rule check failed. Zerodha’s Risk Management System blocked the order. Common causes: quantity exceeds SEBI lot-size limits, the F&O contract has expired, or your account has restrictions.TokenException: Invalid token. Theaccess_tokenhas expired (after 6:00 AM IST next trading day) or was not set. Regenerate the token.- Rate limit exceeded. Kite Connect allows 10 requests per second. If you are placing many orders in a loop, add a
time.sleep(0.1)between calls or use a request queue. - AMO outside window. AMO orders placed between 9:00 AM and 3:45 PM are rejected. Use
VARIETY_REGULARduring market hours. - Cover Order margin shortfall. CO orders require a specific margin structure. Check the current CO margin requirements in Zerodha’s margin calculator before placing.
Related guides
- How to generate a Kite Connect API key
- How to generate the request_token and access_token
- How to write a basic Python script using kiteconnect
- How to stream live ticks via Kite WebSocket
- How to use postback URLs on Kite Connect
- Kite Connect API overview
- Kite Connect ecosystem
- Zerodha overview
References
- Zerodha, Kite Connect orders documentation, kite.trade/docs/connect/v3/orders/, accessed 2024.
- kiteconnect Python SDK,
place_ordermethod, github.com/zerodha/pykiteconnect, accessed 2024. - Zerodha, Kite Connect instruments CSV, api.kite.trade/instruments, accessed 2024.
- SEBI, Circular on algorithmic trading by retail investors, SEBI/HO/MRD/2021 series, sebi.gov.in.
- Zerodha Support, Order types and their usage, support.zerodha.com.
- Zerodha Z-Connect blog, Building with Kite Connect, zerodha.com/z-connect.