Learning Hub Market Data & APIs Lesson 14
Phase 2 — Lesson 5 of 8
Hub
Phase 2 · Market Data & APIs · Lesson 14

Zerodha KiteConnect
API Setup

KiteConnect is India's most widely used broker API for algo trading. Learn to set up authentication, manage sessions, find instrument tokens, and fetch live quotes — the gateway to every live NSE trading system.

~45 min
Intermediate
3 Quiz Questions
3 Exercises
Phase 2 Progress63%
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 Trader

Reusing 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 50
💜
Token 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 TypeMethodDataUse Case
LTPkite.ltp(tokens)Last price onlyQuick price check, fastest
OHLCkite.ohlc(tokens)Open/High/Low/Close + LTPCandle state during session
Full Quotekite.quote(tokens)OHLC + depth + OI + volumeFull 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.
Prev