Zerodha Kite Connect invalid app code TokenException access_token api_key Kite login

Kite Connect authentication errors: invalid app code and incorrect api_key or access_token

From WebNotes, a public knowledge base. Last updated . Reading time ~14 min.

Kite Connect authentication errors fall into two layers that are often confused: the human Kite login, where “Invalid app code” means the second-factor code failed, and the Kite Connect API , where “Incorrect api_key or access_token” means a programmatic session is invalid or expired. The first is almost always a device-clock problem on the time-based login code; the second is almost always the daily 6 a.m. expiry of a Kite Connect access token, returned to your program as an HTTP 403 with a TokenException. They look similar because both involve a token and both block access, but they sit at different layers and have different fixes.

The distinction matters because the wrong mental model wastes time. A trader who reads “Invalid app code” as a password problem keeps retyping a code that was never wrong; a developer who reads “Incorrect api_key or access_token” as a bad key keeps re-checking a key that is correct, when the real issue is an expired token that the login flow refreshes daily. This article takes each error in its own section: the exact message, the layer it lives on, the technical cause, and the precise fix. It draws the line between the in-app login code documented in Kite app code and the API credentials documented in how to generate a Kite Connect API key .

Conflict-of-interest disclosure. This guide is published by the WebNotes Editorial Team for informational purposes and is written independently. WebNotes operates a Zerodha account-opening referral programme, disclosed on the pages that carry the referral link; this guide does not carry it and earns no referral commission from the procedure described here.

“Invalid app code” on Kite login

The message is “Invalid App Code”. It appears on the Kite login second-factor screen, after you have entered your user ID and password and Kite asks for your app code , the six-digit code shown in the Kite mobile app or in your external authenticator.

Why it appears, even when the code is right

The app code is a time-based one-time password (TOTP). A TOTP is computed from two inputs: a secret shared once between Zerodha’s server and your device, and the current time rounded to a 30-second window. Both ends compute the same six-digit number independently and compare them. Because time is an input, the codes only match when both clocks agree. If your phone’s clock, or the clock on the device you are logging in from, has drifted by more than a window, the code your app generates lands in a different time slot from the one Zerodha’s server is checking, and the server rejects it as invalid.

So the headline cause is counter-intuitive: the “Invalid app code” error usually appears even when you have typed the correct code, because the failure is a clock mismatch rather than a wrong code. Zerodha states this directly: authentication may fail if the time on your devices is out of sync, and the code can be correct yet still rejected. Retyping the code does not help, because the next code is computed from the same drifted clock.

How to fix it

The fix is to make both clocks accurate by switching them to network-provided automatic time, then retry. Zerodha’s documented steps by platform:

  • On Android: Settings, Date and time, then turn on “Network provided time”.
  • On iPhone: Settings, General, Date and Time, then turn on “Set Automatically”.
  • On Windows: Settings, Time and Language, turn on “Set the time automatically”, then click “Sync now”.

Apply this on both the device that generates the code, your phone, and the device you are logging in from, because a drift on either side breaks the match. After both clocks are on automatic, the next app code your app shows will line up with the server’s window and the login goes through.

Two follow-ups. If you would rather not depend on the Kite app’s in-built code at all, set up an external authenticator (Authy, Google Authenticator, Microsoft Authenticator, Bitwarden, Ente Auth) from the Kite login page; once external TOTP is enabled, Kite asks for the authenticator’s code instead of the in-app app code, and the same clock rule still applies. If you have lost the device entirely and cannot read any code, you reset the second factor through Zerodha’s recovery flow rather than fighting the error; see how to reset 2FA on Zerodha .

This error is a Kite login error, seen by a person in a browser. It has nothing to do with the Kite Connect API key. A developer whose program fails to authenticate is hitting the next error, not this one.

“Incorrect api_key or access_token” on the Kite Connect API

The API returns this as “Orders couldn’t be loaded. Incorrect ‘api_key’ or ‘access token’.” in the Kite client, and as a TokenException in the raw API response. It is a programmatic error: your code, or a third-party app you authorised, called a Kite Connect endpoint with credentials the server would not accept.

What the API actually returns

Kite Connect signals an invalid or expired session with HTTP status 403, accompanied by a TokenException. Zerodha’s developer documentation describes TokenException as preceded by a 403 header and indicating the expiry or invalidation of an authenticated session, triggered by the user logging out, a natural expiry, or the user logging in to another Kite instance. The documented recommended action is to clear the user’s session and re-initiate a login. So when a program reports “Incorrect api_key or access_token”, the underlying signal is a 403 TokenException, and the right response is to re-authenticate, not to keep retrying the same call.

The api_key half of the message is rarely the real problem once an app is set up, because the api_key is a fixed public identifier that does not change between sessions. The access_token half is almost always the real problem, because the access token is short-lived by design.

Why the access token expires daily

A Kite Connect access token is not permanent. Unless you invalidate it earlier through the logout API or a master logout on Kite web, it expires at 6 a.m. on the next day, a regulatory requirement Zerodha implements on every Kite Connect session. The practical consequence is that an automated system which obtained a token yesterday will get a 403 TokenException on its first call after 6 a.m. today, because the token it is holding has lapsed. This is the single most common cause of the error in a working integration: nothing is wrong with the key or the code; the token simply aged out at the daily reset.

There is no silent renewal that keeps a running script alive across the 6 a.m. boundary on its own. The session has to be re-established by running the login flow again, which produces a fresh access token valid until the next 6 a.m.

The request-token-to-access-token exchange

Re-establishing a session uses the OAuth-style flow that every Kite Connect integration runs. The steps:

  1. Send the user to the Kite login page with your api_key. The user enters their Zerodha credentials and second factor.
  2. After a successful login, Zerodha redirects to your registered redirect URL with a request_token as a query parameter. This request token is short-lived, valid only for a few minutes, and must be exchanged at once.
  3. Your app computes a checksum, which is the SHA-256 hash of api_key + request_token + api_secret concatenated in that order.
  4. Your app POSTs api_key, request_token and checksum to the session token endpoint. Zerodha verifies the checksum, which proves your app holds the private api_secret without that secret ever travelling over the wire, and returns the full user profile along with the access_token.
  5. Your app uses that access token on every subsequent call, in the header Authorization: token api_key:access_token, until the 6 a.m. reset.

The checksum step is where a mismatched api_secret shows up. If your app signs with a stale secret, because someone regenerated the api_secret in the developer console and invalidated the old one, the checksum will not verify and the exchange fails. Regenerating the api_secret immediately invalidates every active session that used the old secret, so a regeneration is a second, less frequent cause of the error: not an expired token, but a secret your code no longer matches. For the full credential-creation flow, see how to generate a Kite Connect API key , and for the token exchange in code, how to generate the request_token and access_token .

The fixes, in order of likelihood

  1. Re-run the login flow to obtain a fresh access token. This clears the daily 6 a.m. expiry, the most common cause, and is the documented response to a 403 TokenException. Automated systems should schedule a daily login that completes before the first call of the trading day; see how to automate Kite Connect TOTP .
  2. Confirm the api_secret your code signs with matches the current secret in the developer console. If anyone regenerated it, every old session breaks; update your stored secret and re-authenticate.
  3. Confirm the Kite Connect subscription is active. If the Rs 2,000 per month subscription lapses, API calls fail with the same 403 token error; renew it from the console. See how to renew a Kite Connect subscription .
  4. Confirm you are not invalidating your own session by logging in to Kite elsewhere. A second login to another Kite instance can expire the API session, exactly as the documentation lists, so check for a stray login or another app holding the token.

Telling the two errors apart

The clean separation: “Invalid app code” is a Kite login second-factor failure that a human sees in a browser, fixed by syncing device clocks. “Incorrect api_key or access_token” is a Kite Connect API failure that a program receives as a 403 TokenException, fixed by re-authenticating to get a fresh daily access token.

They share the word “token” and both block access, which is why they get confused, but they live on different layers. The app code authenticates a person into Kite. The access token authenticates a program into the Kite Connect API. A developer building an automated system meets both: the app code (or external TOTP) gates the login step that yields the request token, and the access token gates every API call after that. The login flow at Kite Connect OAuth login flow shows how the two connect, where a second-factor success produces the request token that the checksum step turns into the access token.

See also

External references

References

  1. Zerodha support, “Why is an ‘Invalid App Code’ error displayed on Kite?” (as of 21 June 2026).
  2. Kite Connect developer documentation, “Exceptions and error handling” (TokenException, HTTP 403), kite.trade/docs/connect/v3/exceptions/ (as of 21 June 2026).
  3. Kite Connect developer documentation, “User and session” (request_token exchange, checksum as SHA-256 of api_key + request_token + api_secret, access_token expiry at 6 a.m. next day), kite.trade/docs/connect/v3/user/ (as of 21 June 2026).
  4. SEBI circular SEBI/HO/MIRSD/DOP/CIR/P/2018/147, dated 3 December 2018, on two-factor authentication for login to online trading accounts.

Frequently asked questions

Why does Kite show 'Invalid app code' when I typed the correct code?
The app code is a time-based code, so it depends on the clock. If your phone or your login device clock has drifted, the code your app shows will not match what Zerodha’s server expects, and Kite rejects it as invalid even though you typed it correctly. Set both devices to automatic, network-provided time.
How do I fix 'Invalid app code' on Kite?
Enable network-provided automatic time on both the phone that generates the code and the device you are logging in from. On Android use Settings, Date and time, Network provided time; on iPhone use Settings, General, Date and Time, Set Automatically. Then retry the login.
What does 'Incorrect api_key or access_token' mean in Kite Connect?
It is a Kite Connect API error returned with HTTP 403 and a TokenException. It means the session your app is using is invalid or has expired. The most common cause is a daily access_token expiry; a less common one is a lapsed subscription or a regenerated api_secret.
Why does my Kite Connect access token stop working every morning?
A Kite Connect access_token expires at 6 a.m. on the next day as a regulatory requirement. Your app must run the login flow each day to obtain a fresh request_token, exchange it for a new access_token, and use that token until the next 6 a.m. reset.
How is the request_token turned into an access_token?
After the user logs in, Zerodha returns a short-lived request_token to your redirect URL. Your app POSTs the api_key, the request_token, and a checksum, the SHA-256 hash of api_key plus request_token plus api_secret, to the session endpoint, and receives the access_token.
Is 'Invalid app code' the same as 'Incorrect api_key or access_token'?
No. ‘Invalid app code’ is a Kite login second-factor failure that a human sees in a browser. ‘Incorrect api_key or access_token’ is a Kite Connect API failure that a program receives as a 403 TokenException. They sit at different layers of the login stack and have different fixes.

Reviewed and published by

The WebNotes Editorial Team covers Indian capital markets, payments infrastructure and retail investor procedures. Every article is fact-checked against primary sources, principally SEBI circulars and master directions, NPCI specifications and the official support documentation published by the intermediary in question. Drafts go through a second-pair-of-eyes review and a separate compliance read before publication, and revisions are tracked against the SEBI and NPCI rule changes referenced in the methodology section.

Last reviewed
Conflicts of interest
WebNotes is independent. No relationship with any broker, registrar or bank named in this article.