How to place an order via the Kite Connect REST API

From WebNotes, a public knowledge base. Last updated . Reading time ~9 min. Level: Intermediate.

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

ParameterTypeRequiredNotes
varietystrYesregular, amo, co, iceberg
exchangestrYesNSE, BSE, NFO, BFO, CDS, MCX, NCDEX, MF
tradingsymbolstrYesExact symbol from instruments CSV; case-sensitive
transaction_typestrYesBUY or SELL
quantityintYesMust be a multiple of the lot size for derivatives
productstrYesCNC, MIS, NRML
order_typestrYesMARKET, LIMIT, SL, SL-M
pricefloatConditionalRequired for LIMIT and SL
trigger_pricefloatConditionalRequired for SL and SL-M
disclosed_quantityintNoPortion of quantity to disclose in the market
validitystrNoDAY (default) or IOC (Immediate or Cancel)
tagstrNoUser-defined tag up to 20 characters; useful for strategy identification
iceberg_legsintConditionalRequired for iceberg variety; 2 to 10
iceberg_quantityintConditionalQuantity 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. The tradingsymbol is 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. Check kite.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. The access_token has 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_REGULAR during 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.

References

  1. Zerodha, Kite Connect orders documentation, kite.trade/docs/connect/v3/orders/, accessed 2024.
  2. kiteconnect Python SDK, place_order method, github.com/zerodha/pykiteconnect, accessed 2024.
  3. Zerodha, Kite Connect instruments CSV, api.kite.trade/instruments, accessed 2024.
  4. SEBI, Circular on algorithmic trading by retail investors, SEBI/HO/MRD/2021 series, sebi.gov.in.
  5. Zerodha Support, Order types and their usage, support.zerodha.com.
  6. Zerodha Z-Connect blog, Building with Kite Connect, zerodha.com/z-connect.

Reviewed and published by

The WebNotes Editorial Team covers Indian capital markets, payments infrastructure and retail investor procedures. Every article is fact-checked against primary sources, principally SEBI circulars and master directions, NPCI specifications and the official support documentation published by the intermediary in question. Drafts go through a second-pair-of-eyes review and a separate compliance read before publication, and revisions are tracked against the SEBI and NPCI rule changes referenced in the methodology section.

Last reviewed
Conflicts of interest
WebNotes is independent. No relationship with any broker, registrar or bank named in this article.