Free trial
Menu
Learn guide

Build Your First Python Trading Bot in India

Zerodha's Kite Connect API lets your own Python code place orders, read your account and stream live prices. This guide to Python for algo trading covers the plans, the rules that apply since April 2026, the daily login, and working code for instruments, orders, stop losses, live prices and historical data.

QuantPower Research · Updated 6 Nov 2026 · 6 min read

Key point
To place orders through Kite Connect you need a static IP registered with Zerodha, a fresh login each trading day and market protection on every market order. Live and historical market data need the paid Connect plan.

What you need

  • A Zerodha account, with F&O enabled if you trade derivatives.
  • A Kite Connect developer account, from developers.kite.trade.
  • Python 3 and Zerodha's official kiteconnect library.
  • A static IP address. Most home broadband connections do not have one, so many traders run their code on a cloud server with a fixed IP.
  • The paid Connect plan, if you need live prices or historical data.

Kite Connect plans

PlanPriceIncludes
PersonalFreeOrders, GTT, alerts, margins, holdings and positions. No live or historical market data
Connect₹500 a month per API keyEverything in Personal, plus live data over WebSocket and historical candles

Zerodha also waives the Connect fee for active users. From October 2026, Connect users who generate ₹2,000 or more in brokerage in a month receive 500 developer credits, which pay for the next month's renewal. Prices were checked on 20 October 2026, so confirm the current terms on kite.trade.

Rules your code must follow

These come from SEBI's retail algo framework and the exchange rules in force since 1 April 2026, as Zerodha applies them.

  • Static IP: orders, modifications and cancellations must come from a static IP registered in your developer account, whatever your order rate. Other calls, such as positions or market data, work from any IP. You can share a static IP only with your immediate family.
  • Order rate: Zerodha's API accepts up to 10 order requests a second per trading account. Requests above that fail with HTTP error 429.
  • Market protection: market and SL-M orders sent through the API must carry a market protection value, either a percentage or -1 for automatic. Orders without it are rejected.
  • Daily login: the access token expires every day, so you log in again each trading day.
  • Registration: your own code sending fewer than 10 orders a second, used for your account or your immediate family's, does not need exchange registration. See SEBI's algo trading rules.

Install the library and log in

Terminal
pip install --upgrade kiteconnect

Create an app in the developer console with a redirect URL. You receive an API key and an API secret. Logging in then takes four steps:

  1. Your code prints a login URL.
  2. You open it, log in with your Zerodha password and two-factor code, and approve the app.
  3. Zerodha sends you to your redirect URL with a request_token in the address.
  4. Your code exchanges the request token and your API secret for an access token.
Flow of the Kite Connect daily login, from the login URL to the access token and orders from a registered static IP (illustration)
Python
import os
from kiteconnect import KiteConnect

kite = KiteConnect(api_key=os.environ["KITE_API_KEY"])
print(kite.login_url())  # open this link and log in

request_token = input("request_token from the redirect URL: ")
session = kite.generate_session(request_token, api_secret=os.environ["KITE_API_SECRET"])
kite.set_access_token(session["access_token"])

print("Logged in as", kite.profile()["user_name"])

Keep the API key, secret and access token in environment variables or a secrets manager, never in code you share.

Find the instrument

Option symbols change with every expiry, so look them up instead of typing them. The instruments list gives each contract's trading symbol, expiry, strike and lot size.

Python
import datetime as dt

nfo = kite.instruments("NFO")
calls = [i for i in nfo if i["name"] == "NIFTY" and i["instrument_type"] == "CE"
         and i["expiry"] >= dt.date.today()]
expiry = min(i["expiry"] for i in calls)
atm = next(i for i in calls if i["expiry"] == expiry and i["strike"] == 25000)

print(atm["tradingsymbol"], atm["lot_size"])

The list is large and changes daily, so download it once each morning and keep it in memory.

Read prices

Quotes need the Connect plan.

Python
key = "NFO:" + atm["tradingsymbol"]
quote = kite.ltp(["NSE:NIFTY 50", key])
nifty = quote["NSE:NIFTY 50"]["last_price"]
option = quote[key]["last_price"]

Place an order

A limit order fills at your price or better, which makes it the simplest choice for options.

Python
order_id = kite.place_order(
    variety=kite.VARIETY_REGULAR,
    exchange=kite.EXCHANGE_NFO,
    tradingsymbol=atm["tradingsymbol"],
    transaction_type=kite.TRANSACTION_TYPE_BUY,
    quantity=atm["lot_size"],
    product=kite.PRODUCT_NRML,
    order_type=kite.ORDER_TYPE_LIMIT,
    price=round(option + 0.5, 1),
    tag="nifty_atm_buy",
)

For a market order, add market_protection=-1 for automatic protection, or a percentage such as 2. Older versions of the library do not accept this parameter, so keep it up to date.

Every order passes Zerodha's risk checks before it reaches the exchange. Check its status before you act on it:

Python
status = kite.order_history(order_id)[-1]["status"]  # OPEN, COMPLETE, REJECTED...

Add a stop loss

Once the buy order shows COMPLETE, place a stop-loss limit order. NSE does not accept SL-M orders in options, so use an SL order with a gap between the trigger and the limit.

Python
kite.place_order(
    variety=kite.VARIETY_REGULAR,
    exchange=kite.EXCHANGE_NFO,
    tradingsymbol=atm["tradingsymbol"],
    transaction_type=kite.TRANSACTION_TYPE_SELL,
    quantity=atm["lot_size"],
    product=kite.PRODUCT_NRML,
    order_type=kite.ORDER_TYPE_SL,
    trigger_price=240,
    price=235,
)

Our guide to order types explains how to choose the gap.

Stream live prices

The WebSocket feed sends price updates as they happen, for strategies that react during the day. It needs the Connect plan.

Python
from kiteconnect import KiteTicker

ticker = KiteTicker(os.environ["KITE_API_KEY"], session["access_token"])

def on_connect(ws, response):
    ws.subscribe([256265])  # Nifty 50 index
    ws.set_mode(ws.MODE_LTP, [256265])

def on_ticks(ws, ticks):
    for t in ticks:
        print(t["instrument_token"], t["last_price"])

ticker.on_connect = on_connect
ticker.on_ticks = on_ticks
ticker.connect()

Get historical data

Historical candles let you test rules on past data before trading them. They need the Connect plan.

Python
candles = kite.historical_data(
    256265, dt.datetime(2026, 9, 1), dt.datetime(2026, 9, 30, 15, 30), "15minute"
)
print(candles[0])  # date, open, high, low, close, volume

An emergency exit

Every script needs a way to stop everything at once. This function cancels open orders and closes open positions.

Python
def exit_all():
    for o in kite.orders():
        if o["status"] in ("OPEN", "TRIGGER PENDING"):
            kite.cancel_order(o["variety"], o["order_id"])
    for p in kite.positions()["net"]:
        if p["quantity"]:
            kite.place_order(
                variety=kite.VARIETY_REGULAR,
                exchange=p["exchange"],
                tradingsymbol=p["tradingsymbol"],
                transaction_type=kite.TRANSACTION_TYPE_SELL if p["quantity"] > 0 else kite.TRANSACTION_TYPE_BUY,
                quantity=abs(p["quantity"]),
                product=p["product"],
                order_type=kite.ORDER_TYPE_MARKET,
                market_protection=-1,
            )

Positions larger than the exchange's freeze quantity have to be closed in several orders.

What a live script also needs

  • A morning routine that logs in, downloads instruments and checks funds with kite.margins().
  • Risk checks before every order: maximum quantity, maximum orders per day and a daily loss limit.
  • A log of every order request and response.
  • Handling for rejections, partial fills and lost connections.
  • A server with your registered static IP, running through market hours.

Common errors

ErrorLikely causeFix
TokenExceptionThe access token has expiredLog in again and create a new session
Market orders without market protection are not allowed via APIA market or SL-M order was sent without market protectionAdd market_protection or use a limit order
Order rejected for IPThe request came from an IP not registered with ZerodhaRegister your server's public IP, and check whether it uses IPv4 or IPv6
HTTP 429More than 10 orders per secondSpace out requests, and split large orders into no more than 10 slices
Quote or historical calls failThe Personal plan has no market dataUse the Connect plan
Quantity rejectedNot a multiple of the lot sizeTake lot_size from the instruments list

Writing code or using a platform

Your own code gives you full control, and Python is a good language for it. It also makes you responsible for the server, the static IP, the daily login, error handling and testing.

QuantPower runs strategies on your Zerodha account without code. You build rules in the strategy builder, test them with backtesting and paper trading, and protect the account with an MTM stop loss. QuantPower is trading software, not a broker. It runs on your own computer or VPS, and the orders from your own rules go to Zerodha through its official API, with your own API key, from the static IP you register with Zerodha, and within the limit for self-built algos of fewer than 10 orders a second. You still log in to Zerodha each trading day with two-factor authentication, and keep that computer or VPS on during market hours. Your funds and securities stay with Zerodha. See Zerodha algo trading.

Start your free trial

Connect your broker, build a strategy and test it on paper before a single live order goes out.

Frequently asked questions

Is the Kite Connect API free?

The Personal plan is free and covers orders and account data. Live and historical market data need the Connect plan at ₹500 a month per API key. From October 2026, Connect users with ₹2,000 or more of brokerage in a month get the next month covered by developer credits.

Do I need a static IP for Kite Connect?

Yes, to place, modify or cancel orders, whatever your order rate. Other calls work from any IP.

Does my Python algo need SEBI registration?

Not if it sends fewer than 10 orders a second and trades only your account or your immediate family's. Faster algos must be registered with the exchange through your broker.

Can I run my script on my laptop?

Only if your internet connection has a static IP registered with Zerodha. Most home connections do not, so traders use a cloud server.

Why are my market orders rejected?

Market and SL-M orders through the API need a market protection value. Add market_protection to the order, or use a limit order.

Sources

  • SEBI, circular on safer participation of retail investors in algorithmic trading, 4 February 2025, and glide-path circular, 30 September 2025 (sebi.gov.in)
  • NSE, implementation standards for retail algo trading, 5 May 2025, and operational modalities, 22 July 2025 (nseindia.com)
  • NSE, equity derivatives contract specifications, lot sizes and freeze quantities (nseindia.com)
  • NSE, circular NSE/FAOP/49677 on discontinuation of stop-loss market orders in options, September 2021
  • Zerodha, Kite Connect API documentation (kite.trade) and "What are the charges for Kite APIs?" (support.zerodha.com), checked 20 October 2026
  • Kite Connect forum, "Free API subscription for active users" (kite.trade), checked 20 October 2026
  • Kite Connect forum, "Preparing to comply with SEBI's retail algo rules (Static IP, ratelimits, order types)" (kite.trade), checked 20 October 2026
Trading involves substantial risk. The code here is for learning. Test it with small quantities before relying on it, and check Zerodha's current API documentation, as parameters and rules change.