Skip to main content

Zerodha API Access Token: How to Generate It Properly

If you have written a Kite Connect bot, you have met this problem: everything worked yesterday, and this morning every call returns a token exception. Nothing in your code changed.

This is the single most common stumbling block for new algo traders in India, and it is not a bug. Here is exactly how the Zerodha API access token works, how to generate one in Python, and how to structure your bot so the daily expiry stops being a daily emergency.

Why your access token stops working every morning

Kite Connect issues an access token that is valid for a single trading day. It expires early the next morning, before markets open. This is a deliberate security decision by Zerodha, not something you can configure away.

So there are two distinct credentials, and mixing them up causes most of the confusion:

  • api_key and api_secret — permanent, tied to your Kite Connect app. These do not change.
  • access_token — temporary, valid for one day. This is what actually authorises requests.

Any bot design that assumes a permanent token is going to fail on day two.

The official login flow, step by step

The exchange is three steps: get a login URL, log in through the browser, then swap the resulting request token for an access token.

from kiteconnect import KiteConnect

api_key = 'your_api_key'
api_secret = 'your_api_secret'

kite = KiteConnect(api_key=api_key)
print(kite.login_url())

Open that URL, log in with your Zerodha credentials and 2FA. You are redirected to your app's redirect URL with a request_token in the query string:

https://your-redirect-url/?request_token=XXXXXX&action=login&status=success

Now exchange it. Note that a request token is single-use and short-lived — if you try to reuse one, you will get a token exception.

request_token = 'XXXXXX'

data = kite.generate_session(request_token, api_secret=api_secret)
access_token = data['access_token']

kite.set_access_token(access_token)
print('Valid until tomorrow morning:', access_token)

Storing the token so your bot can read it

Your strategy script should not perform the login itself. Separate the two: one small script produces the token each morning, and your strategy reads it.

import json, os

TOKEN_FILE = 'token.json'

def save_token(access_token):
    with open(TOKEN_FILE, 'w') as f:
        json.dump({'access_token': access_token}, f)
    os.chmod(TOKEN_FILE, 0o600)   # sirf owner padh sake

def load_token():
    with open(TOKEN_FILE) as f:
        return json.load(f)['access_token']

Then your strategy starts cleanly:

kite = KiteConnect(api_key=api_key)
kite.set_access_token(load_token())

try:
    kite.profile()          # sabse sasta validity check
except Exception as e:
    print('Token invalid, aaj ka login pending:', e)
    raise SystemExit(1)

Calling profile() once at startup is the cheapest way to fail fast. Discovering an expired token halfway through a trade is considerably worse than discovering it before the market opens.

Automating the daily step, and where the line is

The obvious next question is whether the daily login can be automated entirely. Technically people script the browser flow, including the 2FA step.

Be aware of what that involves. It means storing your Zerodha password and TOTP seed on a server, and it works around a two-factor step that exists to protect your account. Broker terms of service govern what is acceptable here, and the risk of a compromised server is your entire trading account — not just your bot.

The pragmatic setup most working traders use: a one-minute manual login each morning that writes the token file, and a strategy that runs unattended for the rest of the day on the VPS. You keep 2FA intact and still get automated execution for the whole session. If you do choose to automate further, at minimum keep secrets in an encrypted store rather than plain files, and never in your code repository.

Common errors and what they actually mean

  • TokenException: Invalid session — token expired or already replaced by a newer login. Generate a fresh one.
  • TokenException on generate_session — the request token was reused, expired, or the api_secret does not match the api_key.
  • PermissionException — your Kite Connect subscription is inactive, or the app does not have that permission enabled.
  • InputException on orders — usually a wrong tradingsymbol, exchange or product combination rather than an auth problem.
  • NetworkException / rate limiting — you are calling too frequently. Add backoff and cache anything static, such as the instruments dump.

One habit worth building early: log the full exception, not just its message. When something fails at 9:20 in the morning, the difference between a useful log and a one-line message is the difference between a two-minute fix and a lost session.

Frequently Asked Questions

How long is a Zerodha access token valid?

One trading day. It expires early the following morning before markets open, so you have to complete the login exchange again each day. The api_key and api_secret are permanent, but the access token is not.

Can I generate a Zerodha access token without logging in manually?

The official flow requires a browser login with 2FA. Fully automating it means storing your password and TOTP seed on a server and working around a security step, which carries real account risk and is governed by your broker's terms. Most traders do a one-minute manual login each morning and let the bot run unattended afterwards.

Why do I get an invalid session error even after generating a new token?

Usually because the request token was already used or has expired - request tokens are single-use and short-lived. Generating a fresh session elsewhere also invalidates the previous access token, so a second login can silently break your running bot.

Where should I store my API secret?

In an environment variable or a config file that your repository ignores, never in the code itself. On a server, restrict file permissions so only the owner can read it. Credentials committed to a repository stay in its history even after the file is deleted.

Disclaimer: TheFinBaba provides educational content only - this is not investment advice. Trading involves risk of loss.

Atul Shrivastava
Written by

Atul Shrivastava

Founder & Lead Trainer, TheFinBaba

16+ years in the markets. 8+ years teaching Python algo trading.

Full profile

Found this useful? Share it:

WhatsApp Share

Disclaimer: TheFinBaba provides educational content only. Nothing in this article is investment advice or a recommendation to buy or sell any security. Trading in financial markets carries risk of loss — make every decision based on your own research and risk capacity.

Free Account Opening

Open a Free Demat & Trading Account in 5 Minutes

Start trading stocks, F&O, IPOs, bonds & ETFs with Zerodha — India's most trusted discount broker. Zero account-opening fee, paperless Aadhaar KYC, and the best APIs (Kite Connect) for Python algo trading.

  • Zero account-opening fee
  • ₹0 brokerage on equity delivery
  • Kite Connect API — best for Python algo traders
  • Paperless Aadhaar e-KYC in 5 minutes
Open Free Demat Account

* Zerodha is SEBI-registered. Account opening subject to KYC approval. Atul Shrivastava is an Authorised Person (AP) — Reg AP2516003481.

Trusted by 1.6 Cr+ Indian Investors

Zerodha is India's largest stock broker by active clients (NSE data, 2026).

₹0
Delivery
₹20
Intraday
5 min
Opening