How to generate the request_token and access_token on Kite Connect
Every Kite Connect API session requires a fresh access_token that is valid for the current trading day. Generating an access_token involves a two-step OAuth-style flow: the user logs in through Zerodha’s browser-based consent screen to obtain a request_token, and the server then exchanges that request_token, along with a cryptographic checksum, for an access_token. This guide explains both steps using the official kiteconnect Python SDK.
How the token flow works
Kite Connect’s authentication is modelled on OAuth 2.0 with a custom checksum step. The flow has three actors: your application, the user’s browser, and Zerodha’s API server.
Login URL. Your application constructs a URL pointing to
kite.trade/connect/loginand includes yourapi_keyas a query parameter. When a user visits this URL, Zerodha displays its standard login page (client ID, password, TOTP).request_token. After the user successfully authenticates, Zerodha redirects their browser to your registered redirect URL and appends a
request_tokenin the query string. This token is short-lived and single-use.Checksum and exchange. Your server computes a SHA-256 hash of the concatenated string
api_key + request_token + api_secret. It then sends this hash along with therequest_tokenandapi_keytoPOST /session/token. Zerodha verifies the hash (proving you possess theapi_secret) and returns theaccess_token.access_token use. Every subsequent API call includes the
access_tokenin theAuthorizationheader (or the SDK injects it automatically). Theaccess_tokenexpires the following trading day at 6:00 AM IST and must be regenerated.
This design ensures the api_secret is never sent over the network as plaintext. Only its cryptographic contribution, as part of the SHA-256 hash, is transmitted.
Step-by-step procedure
Install the kiteconnect SDK
pip install kiteconnect
Verify the installation:
python -c "import kiteconnect; print(kiteconnect.__version__)"
The SDK wraps all REST calls and WebSocket connections. Refer to the kiteconnect Python SDK repository for the full changelog and version history.
Initialise the KiteConnect object
import os
from kiteconnect import KiteConnect
API_KEY = os.environ["KITE_API_KEY"]
API_SECRET = os.environ["KITE_API_SECRET"]
kite = KiteConnect(api_key=API_KEY)
Instantiating KiteConnect does not make any network request. It stores the api_key and configures the HTTP session, base URL, and timeout parameters.
Generate and open the login URL
login_url = kite.login_url()
print(login_url)
This prints a URL of the form:
https://kite.trade/connect/login?api_key=xxxxxxxxxxxxxxxx&v=3
Open this URL in a web browser. On a server or headless environment you may print the URL, open it manually on any browser, and then transfer the request_token to your script. For automated setups, see How to authenticate Kite Connect with TOTP automation.
The user completes the standard Zerodha login: client ID, password, and TOTP. After the final authentication step, Zerodha redirects the browser to your registered redirect URL.
Capture the request_token
After login the browser address bar shows a URL like:
https://your-redirect-url/?request_token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&action=login&status=success
Extract the request_token value. In an automated setup, your server captures it programmatically from the query string of the incoming request. In a manual workflow, copy the value from the address bar.
# Manual development workflow, paste from address bar
request_token = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
The request_token is single-use and expires after a short window (a few minutes). Do not delay the next step.
Exchange the request_token for an access_token
session_data = kite.generate_session(request_token, api_secret=API_SECRET)
access_token = session_data["access_token"]
print("access_token:", access_token)
Internally, generate_session computes:
import hashlib
checksum = hashlib.sha256(
(API_KEY + request_token + API_SECRET).encode("utf-8")
).hexdigest()
It then sends a POST request to https://api.kite.trade/session/token with the api_key, request_token, and checksum. On success the API returns a JSON response containing the access_token, user_id, user_name, email, broker, and other profile fields.
Set the access_token on the client object
kite.set_access_token(access_token)
After this call all further methods on the kite object, kite.profile(), kite.positions(), kite.place_order(...), automatically include the access_token in the Authorization HTTP header.
Persist the access_token
The access_token is valid for the entire trading day. You should save it so that multiple scripts or services running on the same day can reuse it without requiring a fresh browser login.
import json
from pathlib import Path
TOKEN_FILE = Path("/tmp/kite_token.json")
def save_token(access_token: str) -> None:
TOKEN_FILE.write_text(json.dumps({"access_token": access_token}))
def load_token() -> str | None:
if TOKEN_FILE.exists():
return json.loads(TOKEN_FILE.read_text()).get("access_token")
return None
# After successful generate_session:
save_token(access_token)
# At the start of subsequent scripts:
token = load_token()
if token:
kite.set_access_token(token)
Store the token file in a path with appropriate OS-level permissions. Do not commit the token file to version control.
Full minimal example
import os
import json
from pathlib import Path
from kiteconnect import KiteConnect
API_KEY = os.environ["KITE_API_KEY"]
API_SECRET = os.environ["KITE_API_SECRET"]
TOKEN_FILE = Path("/tmp/kite_token.json")
kite = KiteConnect(api_key=API_KEY)
# Step 1: generate login URL and open in browser
print("Open this URL to log in:")
print(kite.login_url())
# Step 2: after redirect, paste the request_token
request_token = input("Paste request_token here: ").strip()
# Step 3: exchange for access_token
session_data = kite.generate_session(request_token, api_secret=API_SECRET)
access_token = session_data["access_token"]
# Step 4: set on client and persist
kite.set_access_token(access_token)
TOKEN_FILE.write_text(json.dumps({"access_token": access_token}))
print("Session ready. Profile:", kite.profile()["user_name"])
What can go wrong
request_tokenalready used. Eachrequest_tokenis single-use. Callinggenerate_sessiona second time with the same token returns aTokenException. Re-run the browser login to obtain a new token.- Checksum mismatch. If the
api_secretpassed togenerate_sessiondoes not match the one registered in the developer console, Zerodha returns aTokenException: Invalid checksum. Verify that you are using the correctapi_secretfrom kite.trade/developers/apps. - Stale access_token. After 6:00 AM IST on the following trading day, all API calls return
TokenException: Invalid token. Scripts that run overnight or early morning must regenerate the token at the start of each day. - Redirect URL mismatch. If the redirect URL in your
KiteConnectconstructor does not match the one registered in the console, Zerodha rejects the authorisation. Ensure the URLs are identical. - Network timeout during generate_session. The exchange endpoint at api.kite.trade has a default timeout. If your network is slow, increase the timeout:
KiteConnect(api_key=API_KEY, timeout=30). - User cancels login. If the user closes the browser without completing login, no
request_tokenis issued and no redirect occurs. Your UI should handle a missing or absentrequest_tokengracefully.
Related guides
- How to generate a Kite Connect API key
- How to authenticate Kite Connect with TOTP automation
- How to write a basic Python script using kiteconnect
- How to place an order via the Kite Connect REST API
- Kite Connect API overview
- Kite Connect ecosystem
References
- Zerodha, Kite Connect authentication documentation, kite.trade/docs/connect/v3/user/, accessed 2024.
- kiteconnect Python SDK,
generate_sessionmethod, github.com/zerodha/pykiteconnect, accessed 2024. - Zerodha Support, Kite Connect access token expiry, support.zerodha.com.
- SEBI, Guidelines on algorithmic trading, sebi.gov.in.
- Zerodha Z-Connect blog, Building with Kite Connect, zerodha.com/z-connect.