Section 1
LESSON 14 · KITECONNECT API
What is KiteConnect?
intermediatelive trading
Zerodha KiteConnect is the official REST + WebSocket API for Zerodha accounts. It provides real-time quotes, historical candle data, order placement, position tracking, and WebSocket tick streams — everything needed for a complete live algo trading system.
OAuth Authentication
Daily login generates a session access_token. Expires at midnight — your algo must re-authenticate each morning.
Historical Data
Fetch OHLCV candles from 1-min to monthly for any NSE/BSE instrument. Up to 60 days for minute data.
Live Quotes
Real-time LTP, bid/ask, OI, and depth data via REST. For streaming ticks, use WebSocket (Lesson 16).
Order Placement
Place, modify, cancel orders. Market, Limit, SL-M types supported. Built-in paper trading mode available.
KiteConnect pricing: ₹2,000/month subscription + ₹2,000 security deposit. Free for the first month. You need an active Zerodha trading account. Alternative free options: Upstox API or Angel SmartAPI (covered in Lesson 16).
Section 2
Setup Steps
1
Create a KiteConnect App
Visit developers.kite.trade → My Apps → Create App. Choose "Connect" type. Note your
api_key and api_secret.2
Install the Python SDK
pip install kiteconnect — the official Python client maintained by Zerodha.3
First-Time Login (get request_token)
Open the login URL in your browser, log in with Zerodha credentials + TOTP. The redirect URL contains
request_token.4
Exchange for access_token
Use
api_key + request_token + api_secret to generate the access_token. Save it to a file — valid until midnight.5
Automate Daily Re-Authentication
Use a scheduled script or Selenium/Playwright to auto-login each morning before market opens at 09:00.
# config.json (NEVER commit to git — add to .gitignore!) { "api_key": "your_api_key_here", "api_secret": "your_api_secret_here", "access_token": "saved_after_login" }
Security rule: Never hardcode your API credentials in Python scripts. Always load from a config file or environment variables. Add
config.json and .env to .gitignore before your first commit.Section 3
Authentication Flow
from kiteconnect import KiteConnect import json, os from pathlib import Path # ── Load credentials ── with open("config.json") as f: cfg = json.load(f) kite = KiteConnect(api_key=cfg["api_key"]) # ── Step 1: Generate login URL ── login_url = kite.login_url() print(f"Open this URL and login:\n{login_url}") # ── Step 2: After login, extract request_token from redirect URL ── # Redirect looks like: https://your-app.com/?request_token=XXXX&action=login&status=success request_token = input("Paste request_token here: ") # ── Step 3: Generate session (access_token) ── data = kite.generate_session(request_token, api_secret=cfg["api_secret"]) access_token = data["access_token"] # ── Step 4: Set and save access_token ── kite.set_access_token(access_token) cfg["access_token"] = access_token with open("config.json", "w") as f: json.dump(cfg, f, indent=2) print("✅ Session ready. access_token saved to config.json") print(f"Profile: {kite.profile()['user_name']}")
Successful Authentication
Open this URL and login:
https://kite.zerodha.com/connect/login?v=3&api_key=your_key
Paste request_token here: AbcXyz123...
✅ Session ready. access_token saved to config.json
Profile: Vianmax TraderReusing a Saved Session
def get_kite_session(config_path: str = "config.json") -> KiteConnect: """Load KiteConnect session from saved access_token.""" with open(config_path) as f: cfg = json.load(f) kite = KiteConnect(api_key=cfg["api_key"]) kite.set_access_token(cfg["access_token"]) try: profile = kite.profile() print(f"✅ Session active — {profile['user_name']}") return kite except Exception as e: print(f"❌ Session expired: {e}") print("Run login.py to generate a new session.") raise # Use throughout your trading session kite = get_kite_session()
Section 4
Instruments — Finding Tokens
Every instrument on NSE/BSE has a unique instrument_token (integer). You need this token to request historical data, live quotes, or set up a WebSocket feed. Zerodha publishes a full instrument dump daily.
import pandas as pd # Download full NSE instrument list instruments = kite.instruments("NSE") df_inst = pd.DataFrame(instruments) print(df_inst.columns.tolist()) # ['instrument_token', 'exchange_token', 'tradingsymbol', 'name', # 'last_price', 'expiry', 'strike', 'tick_size', 'lot_size', # 'instrument_type', 'segment', 'exchange'] # ── Find NIFTY 50 Index token ── nifty_row = df_inst[df_inst["tradingsymbol"] == "NIFTY 50"].iloc[0] nifty_token = nifty_row["instrument_token"] print(f"NIFTY 50 token : {nifty_token}") # 256265 # ── Find BANKNIFTY token ── bn_row = df_inst[df_inst["tradingsymbol"] == "NIFTY BANK"].iloc[0] bn_token = bn_row["instrument_token"] print(f"BANKNIFTY token: {bn_token}") # 260105 # ── Find RELIANCE equity token ── reliance = df_inst[df_inst["tradingsymbol"] == "RELIANCE"] reliance = reliance[reliance["instrument_type"] == "EQ"].iloc[0] print(f"RELIANCE token : {reliance['instrument_token']}") # ── Find NIFTY Futures (current expiry) ── nf_futures = df_inst[ (df_inst["tradingsymbol"].str.startswith("NIFTY")) & (df_inst["instrument_type"] == "FUT") ].sort_values("expiry") print(nf_futures[["tradingsymbol", "expiry", "instrument_token", "lot_size"]].head(3))
Instrument Tokens
NIFTY 50 token : 256265
BANKNIFTY token: 260105
RELIANCE token : 738561
tradingsymbol expiry instrument_token lot_size
0 NIFTY24JAN 2024-01-25 11914497 50
1 NIFTY24FEB 2024-02-29 11924737 50
2 NIFTY24MAR 2024-03-28 11933697 50Token Cache Strategy
Save instrument tokens to a JSON file once per day. Download at 08:30 AM before market open, cache locally, and look up tokens from the file throughout the session. Avoids repeated API calls.Section 5
Live Quotes
# ── LTP (Last Traded Price) — fastest quote ── tokens = [256265, 260105] # NIFTY 50, BANKNIFTY ltp_data = kite.ltp(tokens) for token, val in ltp_data.items(): print(f"Token {token}: LTP = ₹{val['last_price']:,.2f}") # ── Full quote (OHLC + depth + volume + OI) ── quote = kite.quote([256265]) nifty_quote = quote["256265"] print(f"\n-- NIFTY 50 Full Quote --") print(f"LTP : ₹{nifty_quote['last_price']:,.2f}") print(f"Open : ₹{nifty_quote['ohlc']['open']:,.2f}") print(f"High : ₹{nifty_quote['ohlc']['high']:,.2f}") print(f"Low : ₹{nifty_quote['ohlc']['low']:,.2f}") print(f"Close : ₹{nifty_quote['ohlc']['close']:,.2f}") print(f"Volume : {nifty_quote['volume']:,}") print(f"Buy Qty : {nifty_quote['depth']['buy'][0]['quantity']:,}") print(f"Sell Qty: {nifty_quote['depth']['sell'][0]['quantity']:,}")
Live Quote Output
Token 256265: LTP = ₹21,985.70
Token 260105: LTP = ₹47,312.45
-- NIFTY 50 Full Quote --
LTP : ₹21,985.70
Open : ₹21,850.00
High : ₹22,010.50
Low : ₹21,800.25
Close : ₹21,920.30
Volume : 142,500
Buy Qty : 8,450
Sell Qty: 12,300| Quote Type | Method | Data | Use Case |
|---|---|---|---|
| LTP | kite.ltp(tokens) | Last price only | Quick price check, fastest |
| OHLC | kite.ohlc(tokens) | Open/High/Low/Close + LTP | Candle state during session |
| Full Quote | kite.quote(tokens) | OHLC + depth + OI + volume | Full market data snapshot |
Section 6
API Error Handling — Production Patterns
from kiteconnect import KiteConnect from kiteconnect.exceptions import ( TokenException, NetworkException, DataException, GeneralException, InputException ) import time def safe_ltp(kite: KiteConnect, tokens: list, retries: int = 3) -> dict: """ Fetch LTP with retry logic for network issues. Raises immediately on auth errors (TokenException). """ for attempt in range(1, retries + 1): try: return kite.ltp(tokens) except TokenException: print("❌ Access token expired — re-authentication required") raise # Never retry auth errors except NetworkException as e: print(f"⚠️ Network error (attempt {attempt}/{retries}): {e}") if attempt < retries: time.sleep(2 ** attempt) # exponential backoff else: raise except DataException as e: print(f"⚠️ Data error: {e}") return {} # Return empty — caller handles missing data except GeneralException as e: print(f"❌ General API error: {e}") raise # Usage ltp_data = safe_ltp(kite, [256265, 260105]) if ltp_data: nifty_ltp = ltp_data.get("256265", {}).get("last_price", None) print(f"NIFTY LTP: ₹{nifty_ltp}")
Exponential backoff on network errors: wait 2s, then 4s, then 8s. This avoids hammering the API when Zerodha's servers are briefly overloaded — a common occurrence during NSE open (09:15–09:20 AM).
Section 7
Quiz
Q1. The KiteConnect access_token expires at what time each day?
Q2. What unique identifier does KiteConnect use to identify each instrument (e.g., NIFTY 50)?
Q3. Which KiteConnect method returns ONLY the last traded price (fastest, minimal data)?
Section 8
Exercises
Exercise 01
Session Manager Script
Write a Python module
session.py with a get_kite() function that: loads config.json, creates a KiteConnect instance, sets the access_token, calls kite.profile() to verify the session, and returns the kite object. If the token is expired, print a clear error message with instructions to re-login.Exercise 02
Instrument Token Cache
Write a function
build_token_cache(kite) that downloads NSE instruments, and saves a dictionary of {tradingsymbol: instrument_token} to tokens.json. Include NIFTY 50, NIFTY BANK, RELIANCE, TCS, HDFCBANK, and the nearest NIFTY and BANKNIFTY futures contracts.Exercise 03
Live Quote Monitor
Using the instrument tokens from Exercise 02, write a loop that fetches live LTP for NIFTY 50 and BANKNIFTY every 5 seconds for 60 seconds (12 iterations). Print each reading with a timestamp. Handle NetworkException with 2 retries before giving up.
Section 9
Lesson Summary
Authentication
api_key + request_token → access_token via generate_session(). Resets each midnight.
instrument_token
Integer ID for every instrument. Download full list with kite.instruments("NSE"), cache locally.
Quote Types
ltp() for speed, ohlc() for candle state, quote() for full depth. Use ltp() in tight loops.
Error Handling
TokenException = re-login. NetworkException = retry with backoff. DataException = skip silently.
Security
credentials in config.json, never in code. .gitignore must include config.json and .env files.
Next Step
Lesson 15 covers fetching historical OHLCV candle data via the KiteConnect API.
