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
kiteconnectlibrary. - 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
| Plan | Price | Includes |
|---|---|---|
| Personal | Free | Orders, GTT, alerts, margins, holdings and positions. No live or historical market data |
| Connect | ₹500 a month per API key | Everything 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
-1for 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
pip install --upgrade kiteconnectCreate 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:
- Your code prints a login URL.
- You open it, log in with your Zerodha password and two-factor code, and approve the app.
- Zerodha sends you to your redirect URL with a
request_tokenin the address. - Your code exchanges the request token and your API secret for an access token.
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.
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.
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.
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:
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.
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.
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.
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, volumeAn emergency exit
Every script needs a way to stop everything at once. This function cancels open orders and closes open positions.
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
| Error | Likely cause | Fix |
|---|---|---|
TokenException | The access token has expired | Log in again and create a new session |
| Market orders without market protection are not allowed via API | A market or SL-M order was sent without market protection | Add market_protection or use a limit order |
| Order rejected for IP | The request came from an IP not registered with Zerodha | Register your server's public IP, and check whether it uses IPv4 or IPv6 |
| HTTP 429 | More than 10 orders per second | Space out requests, and split large orders into no more than 10 slices |
| Quote or historical calls fail | The Personal plan has no market data | Use the Connect plan |
| Quantity rejected | Not a multiple of the lot size | Take 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.
Related guides
- Trading API: how broker APIs work, in plain terms
- API vs webhook: turning TradingView alerts into orders
- No code vs coded strategies: when to write code and when to use a builder
- SEBI rules for option trading: the retail algo framework in full
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
