Skip to content

Python

How to fully automate Fyers Broker API login using Python

29 November 20257 min readPython
FabTrader author portrait

FabTrader

Article overview

If you’ve been building serious algos on Fyers, you already know the pain point: the login flow.

If you’ve been building serious algos on Fyers, you already know the pain point: the login flow.

Fyers uses a secure authentication process, which is great for human users, but not so fun for automation. The standard workflow looks like this:

  1. Hit a URL
  2. Wait for a browser window
  3. Enter your credentials manually
  4. Enter your TOTP
  5. Finally retrieve the access token

For discretionary traders, this is fine. For automated traders, this is a workflow killer.

At FabTrader, everything is built around a no-touch infrastructure — scripts that run themselves without waiting for humans to type passwords. Today, I’m sharing that solution with the community. If you’re an algo trader, Python user, or someone who wants to stop hand-feeding access tokens to your trading engine, this might save you hours of frustration over time.

Cache the Token, Regenerate Only When Needed

Many brokers in India still don’t offer long-lived access tokens. Fyers, like most, issues a token that remains valid for 24 hours. Past that, you need to regenerate it. Doing this manually every day is annoying. Doing it inside a hands-off system? Practically impossible — unless you automate it.

The approach I settled on is simple:

1 — Maintain a JSON file storing the token of the day

Example:

{
  "2025-11-27": "eyJhbRZ_0"
}

2 — When the script runs:

  • If the token exists and matches today’s date → use it.
  • Else → generate a new one using the automated flow.

3 — Save the newly generated access token

This ensures:

  • No repeated logins throughout the day
  • No manual involvement
  • System restarts still work instantly
  • Scalability across servers and multiple instances

The Python Code (Full Automation)

# ------------------------------------------------------------------------------------
#                          FabTrader Algorithmic Trading Platform
# ------------------------------------------------------------------------------------
# Copyright (c) 2025 FabTrader
#
# LICENSE: PROPRIETARY SOFTWARE
# - This software is the exclusive property of FabTrader.
# - Unauthorized copying, modification, distribution, or use is strictly prohibited.
# - Written permission from the author is required for any use beyond personal,
#   non-commercial purposes.
#
# CONTACT:
# - Website: https://fabtrader.in
# - Email: [email protected]
#
# Usage: Internal/Personal use only. Not for commercial redistribution.
# Permissions and licensing inquiries should be directed to the contact email.

import pyotp
import requests
from urllib.parse import urlparse, parse_qs
import json
from fyers_apiv3 import fyersModel
import base64
from datetime import datetime, date
from time import sleep


"""
ConnectionManager :     Manages broker connection - Logging in and retaining Access Token
"""


def get_access_token() -> str:
    """
    Returns broker access token
    """

    try:
        with open("BrokerToken.json", "r") as f:
            data = json.load(f)
        return data

    except Exception as e:
        print(datetime.now(), " : ERROR : Unable to access Token file. Quitting...")
        print(e)
        raise FileNotFoundError()


def broker_login():
    """
    Function enables logging into broker apiD account.
    :return:
    Broker Instance, in case the login was successful
    None, if the login fails
    """

    broker_handle = None

    # Download Broker Login credentials from Broker app config file
    broker_credentials = {
          "broker": "Fyers",
          "userId":"XVXXXX",
          "apiKey": "xxxxxxx-100",
          "appSecret": "XXXXXXXXXX",
          "totpKey" : "XXXXXXXXXXXXXXXXXXXXXXXXX",
          "pin" : "9999"
        }

    # Extract token already (if) saved in the token file
    token = get_access_token()

    run_date = date.today().strftime("%Y-%m-%d")

    # Check if Access token was generated in the last 24 hrs. If so use that one.
    if run_date in token.keys():
        access_token = token[run_date]

    else:
        # Generate fresh Access Token and write to access token file (to be used through the day)

        try:

            def encode_input(string):
                string = str(string)
                base64_bytes = base64.b64encode(string.encode("ascii"))
                return base64_bytes.decode("ascii")

            url = "https://api-t2.fyers.in/vagator/v2/send_login_otp_v2"
            res = requests.post(url=url,
                                json={"fy_id": encode_input(broker_credentials["userId"]),
                                      "app_id": "2"}).json()

            if datetime.now().second % 30 > 27: sleep(5)
            url = "https://api-t2.fyers.in/vagator/v2/verify_otp"
            res2 = requests.post(url=url,
                                 json={"request_key": res["request_key"],
                                       "otp": pyotp.TOTP(broker_credentials["totpKey"]).now()}).json()

            ses = requests.Session()
            url = "https://api-t2.fyers.in/vagator/v2/verify_pin_v2"
            payload2 = {"request_key": res2["request_key"],
                        "identity_type": "pin",
                        "identifier": encode_input(broker_credentials["pin"])}
            res3 = ses.post(url=url, json=payload2).json()

            ses.headers.update({
                'authorization': f"Bearer {res3['data']['access_token']}"
            })

            url = "https://api-t1.fyers.in/api/v3/token"
            payload3 = {"fyers_id": broker_credentials["userId"],
                        "app_id": broker_credentials["apiKey"][:-4],
                        "redirect_uri": "https://127.0.0.1:5000/",
                        "appType": "100", "code_challenge": "",
                        "state": "None", "scope": "", "nonce": "",
                        "response_type": "code", "create_cookie": True}

            res3 = ses.post(url=url, json=payload3).json()

            url = res3['Url']
            parsed = urlparse(url)
            auth_code = parse_qs(parsed.query)['auth_code'][0]

            session = fyersModel.SessionModel(
                client_id=broker_credentials["apiKey"],
                secret_key=broker_credentials["appSecret"],
                redirect_uri="www.google.com",
                response_type="code",
                grant_type="authorization_code"
            )

            # Set the authorization code in the session object
            session.set_token(auth_code)

            # Generate the access token using the authorization code
            response = session.generate_token()
            access_token = response['access_token']

            # Save access token into token file
            try:
                dict = {run_date: access_token}
                with open('BrokerToken.json', 'w+') as token_file:
                    json.dump(dict, token_file)
            except Exception as e:
                print('Broker Login : Error saving broker access token to token file')
                return broker_handle

        except Exception as e:
            print('Broker Login : Login failed. Check Credentials and try again')
            return False

    # Initialize the FyersModel instance with your client_id, access_token
    broker_handle = fyersModel.FyersModel(client_id=broker_credentials["apiKey"],
                                          is_async=False,
                                          token=access_token,
                                          log_path="")

    # Everything looks ok. Return broker instance
    return broker_handle

if __name__ == "__main__":

    fyers = broker_login()
    if fyers is None:
        print("Broker Login failed")
    else:
        print("Broker Login successful")
        print(fyers.get_profile())

How the Script Works

1. Retrieve existing token

The script first checks BrokerToken.json. If an access token exists for today’s date, the login process is bypassed entirely.

2. Generate fresh access token

Only if required, the script triggers:

  • send_login_otp_v2
  • verify_otp using your TOTP key (no SMS needed)
  • verify_pin_v2 using your PIN
  • request for OAuth authorization code
  • exchange auth code → final access token

Everything happens via secure API calls — no browser windows, no clicks.

3. Save token and create session

The new token is written back into the JSON file and used to initialize a Fyers API session object.

4. That’s it. You're logged in. Automatically.

Security Notes

A few practical points worth mentioning:

  • Store your totpKey, API keys, and password securely (env vars or encrypted vaults).
  • JSON token file should have restricted permissions.
  • Rotate secrets periodically.
  • Never hardcode credentials in public repos.
  • This script is for educational and personal use — always follow your broker’s guidelines.

Closing Thoughts

Algo trading should be about writing strategies, not typing PIN codes at 9 AM.
This automated login flow has been bulletproof in my own systems, and I hope it helps other traders streamline their workflow too.

If you're building something ambitious — multi-strategy execution, automated portfolio rebalancing, intraday engines, whatever — shaving off manual steps makes a world of difference.

Feel free to adapt and expand the code as needed.

If this helped you, or if you want me to write an article about your own algo infra challenges, just ask.

Happy coding, and happy trading.

More from Python