Zerodha Kite Connect API with Python — a Production-Minded Tutorial

The step-by-step tutorial for integrating Kite Connect with Python, including the production gotchas that tutorials skip.

Zerodha Kite Connect API with Python — a Production-Minded Tutorial

Most Kite Connect tutorials show you how to place an order. They don't show you how to keep a live system running for 200 consecutive trading days without a single production incident. This tutorial is the second one.

If you want the basic "hello world" place-order example, the official Kite Connect documentation covers it well. The article below assumes you've done the hello world and are now asking "how do I deploy this for real money?"

Step 1 — Get API access

  1. Register at developers.kite.trade with your Zerodha Kite account
  2. Create a new app — you'll be issued an API key and a one-time-visible API secret (save it; you can't retrieve it later)
  3. Subscribe to the ₹2,000/month historical data + API package
  4. Configure the redirect URL — for local development, http://127.0.0.1/ works; for production, use your actual domain

Step 2 — Install the SDK

pip install kiteconnect

The official Python SDK is thin and stable. It exposes roughly 30 REST methods and a WebSocket ticker class.

Step 3 — The three-token authentication dance

Kite Connect uses three tokens:

  1. API key — public identifier of your app
  2. API secret — proves you are the registered developer
  3. Access token — daily session token valid until 06:00 IST next morning

The authentication flow:

from kiteconnect import KiteConnect

kite = KiteConnect(api_key="your_api_key")
# User visits this URL in a browser:
print(kite.login_url())
# After login, Kite redirects to your redirect URL with ?request_token=...
# You capture the request_token, then:
data = kite.generate_session("request_token_here", api_secret="your_api_secret")
access_token = data["access_token"]
kite.set_access_token(access_token)

Production gotcha 1: the access token expires at 06:00 IST every day. A system that starts at 09:15 without fresh authentication fails at the first API call.

Production pattern: a session manager that checks expiry 10 minutes before the actual 06:00 mark, automatically re-authenticates (using TOTP for 2FA automation), and caches the fresh token. About 50 lines of code. Without it, you re-authenticate manually every morning — which is not production.

Step 4 — Place an order

The minimal order placement:

order_id = kite.place_order(
    variety=kite.VARIETY_REGULAR,
    tradingsymbol="RELIANCE",
    exchange=kite.EXCHANGE_NSE,
    transaction_type=kite.TRANSACTION_TYPE_BUY,
    quantity=1,
    product=kite.PRODUCT_MIS,  # intraday
    order_type=kite.ORDER_TYPE_LIMIT,
    price=2900.00,
    validity=kite.VALIDITY_DAY,
    tag="my-strategy-v1"
)

Production gotcha 2: the returned order_id is NOT confirmation that the order was filled or even accepted. It means Kite received your request. The order then moves through states:

  • PUT ORDER REQ RECEIVED
  • VALIDATION PENDING
  • OPEN PENDING (routed to exchange)
  • OPEN (live at exchange)
  • COMPLETE / CANCELLED / REJECTED (terminal)

Always query order status after placement:

order_status = kite.order_history(order_id)

For a production system, subscribe to Kite's order-update postback webhook. Zerodha will POST to your endpoint every time the order changes state. Polling is the fallback.

Production gotcha 3: every order should carry a unique tag — ideally a UUID. If you ever have to reconcile "did my order actually go through" after a network timeout, the tag lets you query for it without ambiguity.

Step 5 — Handle errors like they matter

Kite returns 12 error classes you need explicit handlers for:

HTTPClassMeaningCorrect action
400InputExceptionInvalid parametersFix code. Never retry.
401TokenExceptionAccess token expiredRe-authenticate.
403PermissionExceptionProduct not enabledContact Zerodha. Never retry.
429NetworkExceptionRate limitExponential backoff.
500NetworkExceptionKite backend errorRetry with backoff, max 3 attempts.
502/503/504NetworkExceptionKite gateway issueRetry with backoff, max 5 attempts.
OrderExceptionOMS rejectionLog. Escalate. Never retry.
MarginExceptionInsufficient marginHalt strategy. Never retry.
ExchangeExceptionExchange rejectLog. Never retry.
GeneralExceptionUnknownLog. Retry once.
TimeoutRequest didn't returnQuery order status before retry.
Connection errorNetwork downReconnect, then retry.

Production gotcha 4: the most dangerous mistake is to catch all exceptions and retry. That creates duplicate orders on network timeouts. Rule: before retrying ANY write operation (place, modify, cancel), query the current state first.

Step 6 — WebSocket for live ticks

Real-time market data requires the WebSocket connection:

from kiteconnect import KiteTicker

kws = KiteTicker(api_key, access_token)

def on_ticks(ws, ticks):
    print(ticks)

def on_connect(ws, response):
    ws.subscribe([738561])  # RELIANCE token
    ws.set_mode(ws.MODE_FULL, [738561])

kws.on_ticks = on_ticks
kws.on_connect = on_connect
kws.connect()

Three subscription modes:

  • LTP — last traded price only, smallest payload
  • Quote — price + OHLC + volume + top-of-book depth
  • Full — everything plus 5-level order book depth

Production gotcha 5: the WebSocket disconnects. Regularly. Without reconnect logic, your strategy runs on stale data silently. The standard reconnect protocol:

  1. Detect disconnect (via on_close callback, or 60-second tick timeout)
  2. Emit BrokerDisconnectedEvent to pause strategies
  3. Exponential backoff: 1s → 2s → 4s → 8s → 16s → 30s
  4. Reconnect
  5. Resubscribe to all previously subscribed tokens
  6. Emit BrokerReconnectedEvent
  7. Reconcile positions via REST API
  8. Resume strategy submissions

All 8 steps. Skipping any one creates silent bugs.

Step 7 — Rate limits

Kite Connect rate limits (current as of 2026):

  • Order placement: 10 requests/second, 200/minute
  • Order modification/cancellation: 25/second
  • Quote/LTP: 1 request/second per instrument list
  • Historical data: 3 requests/second

A token-bucket rate limiter per endpoint category prevents 429 errors and IP bans. The aiolimiter Python library does this in ~20 lines of code.

Step 8 — Reconciliation on startup

Before your strategy resumes trading after any restart (cold start, cloud VM reboot, WebSocket reconnect), reconcile:

  1. Fetch broker positions via /portfolio/positions
  2. Fetch open orders via /orders
  3. Compare against your event-log's projected state
  4. Resolve mismatches BEFORE allowing new orders

Production gotcha 6: never trust that your system's internal state matches the broker's after any outage. Reconcile every time, without exception. The reconciliation step catches the bugs that would otherwise compound into catastrophic losses.

Step 9 — Deployment with secrets hygiene

Keep your API secret and daily access token out of source code. Three acceptable storage patterns:

  1. Cloud secret manager (AWS Secrets Manager, GCP Secret Manager, HashiCorp Vault) — read at runtime via IAM. Best for production.
  2. .env file with 0600 permissions, gitignored — fine for solo retail at scale < ₹50 lakh.
  3. OS keychain (macOS Keychain, Windows Credential Manager) — fine for local development.

Never:

  • Hardcode secrets in .py files
  • Commit secrets to Git, even in a private repo
  • Email secrets, even to yourself
  • Store secrets in a shared Google Sheet

Secret scanners index public GitHub constantly. A leaked Kite API secret on GitHub can drain a trading account in minutes.

The minimal production stack

Pulling the above together, the minimal production stack for a live Kite Connect retail algo system:

  1. Hosting: AWS ap-south-1 Mumbai, t3.small VM (~₹1,800/month)
  2. Deployment: Docker container, non-root user, HEALTHCHECK, systemd auto-restart
  3. Secrets: AWS Secrets Manager or .env with strict perms
  4. Session: auto-reauthenticating session manager with TOTP
  5. Rate limiting: per-endpoint token-bucket
  6. WebSocket: 8-step reconnect protocol
  7. State: event-driven architecture with immutable event log; reconciliation on startup
  8. Monitoring: Prometheus + Grafana; Telegram alerts on the 6 must-monitor metrics
  9. Kill-switches: 4 levels, automated, non-overridable

Setup time for a first-time developer: 4-6 weeks end to end, including learning the Python scientific stack.

How Bharath Shiksha fits

Stage 5 Volume 3 (Broker Integration) is 75 minutes of main programme on this exact material, with a 14-page worksheet that walks through a session manager implementation, the 12 error classes, and the 8-step reconnect protocol with worked-through code.

Stage 5 as a whole is 5 volumes covering research-to-production, event-driven architecture, broker integration, deployment infrastructure, and the live deployment playbook. Priced at ₹16,999.

For the full retail-to-production path, the bundle of all 30 volumes is ₹39,999 at bharathshiksha.com.


Educational material. This tutorial is not affiliated with Zerodha. Always verify current rate limits, fees, and API behaviour against official Kite Connect documentation. Trading involves risk of capital loss.

Related reading

Ready to go deeper than this article?

Bharath Shiksha is a 30-volume curriculum across 6 stages — from chart reading (Stage 1 at ₹2,999) through capital raising (Stage 6 at ₹18,999), or the full bundle at ₹39,999. Every volume has a 14-page companion worksheet, a 10-question gate quiz, and a 7-day money-back guarantee.

See the full curriculum →