Help regarding automatic Access Token generation using DhanHQ API (v2)

I am using the DhanHQ API (v2) for my Python-based trading automation project.
I have already generated my API Key, API Secret, and Client ID from the Dhan Developer section.

Currently, I am able to generate the consentAppId and manually log in via browser to get the tokenId, and then call the consume-consent API to get the access token.

However, I would like to know:
:backhand_index_pointing_right: Is there any way to automatically generate or refresh the access token (without manual login) — for example, using an API endpoint or refresh mechanism?

If possible, please share the correct procedure or documentation for automating token generation or renewal for backend applications. please
Kindly guide me on:

  1. Whether there is any official way or endpoint to auto-generate or refresh the Access Token for backend systems.
  2. If available, please share a tutorial video or official Python example that demonstrates automatic Access Token generation using the DhanHQ API v2.

This will help me integrate the Dhan API seamlessly into my automated trading system.

Hey @Shrinath ,

You can generate the access token without logging into the web by following the mentioned steps.

However, to fully automate the process, you’ll need to implement it on your end.

Be responsible for giving reply…by following the mentioned steps..please provide full code to generate automatic access token

1 Like

Could you please clarify the process for obtaining a Data API token? I’ve followed all the steps, including subscribing to the Data API and generating the token successfully. However, when I attempt to connect to the WebSocket, no data is being received. I’d appreciate your guidance on whether I’ve missed any steps or if there’s an issue with the token usage.

Dear Dhan Team,

Dont waiste our and yours time.

Check the upstox broker autologin api link. upstox-auto-login

Generate the same api.for dhan autologin.
so that dhan users can get the autologin token generation automatic easily by python code.

I use this, adapted from a Github issue: :backhand_index_pointing_down:

url = "https://api.dhan.co/v2/RenewToken"
headers = {
    "access-token": <YOUR-CURRENT-ACCESS-TOKEN>,
    "dhanClientId": <YOUR-DHAN-CLIENT-ID>,
}

r = requests.get(url, headers=headers)
r.status_code
r.json()

It’s mentioned in the docs: :open_book:

There was some confusion over whether the endpoint accepted POST, but GET works! :dizzy:

@Shrutika_Poojari Unable to connect to Live Market Feed through Websockets .. Same issue with me i am able to connect web socket but not receiving OHLC. My code was different . if u have working code can assist with which version of python.-

1> i have paid data api as well.

2> Python version Python 3.12.6

3> Name: dhanhq → Version: 2.0.2

4> Here is My Code

from dhanhq import dhanhq, marketfeedimport pandas as pdimport xlwings as xwimport timefrom datetime import date

================= CONFIG =================

CLIENT_ID = “22”ACCESS_TOKEN = “eyJ0”

SYMBOL = “NIFTY”EXPIRY_DATE = date(2026, 1, 27)ATM_STRIKE = 25000 # :red_circle: CHANGE DAILYSTRIKE_GAP = 50STRIKE_RANGE = 10 # ATM ±10EXCEL_UPDATE_MS = 0.5 # 500 ms

=========================================

print(“Starting NIFTY ATM ±10 LIVE SYSTEM”)

---------- STEP 1: LOAD INSTRUMENT MASTER ----------

df = pd.read_csv(

low_memory=False)

df[“SEM_EXPIRY_DATE”] = pd.to_datetime(df[“SEM_EXPIRY_DATE”],errors=“coerce”)

---------- STEP 2: FILTER ATM ±10 STRIKES ----------

lower = ATM_STRIKE - (STRIKE_RANGE * STRIKE_GAP)upper = ATM_STRIKE + (STRIKE_RANGE * STRIKE_GAP)

contracts = df[(df[“SEM_INSTRUMENT_NAME”] == “OPTIDX”) &(df[“SEM_CUSTOM_SYMBOL”].str.contains(“NIFTY”, na=False)) &(df[“SEM_EXPIRY_DATE”].dt.date == EXPIRY_DATE) &(df[“SEM_STRIKE_PRICE”] >= lower) &(df[“SEM_STRIKE_PRICE”] <= upper)][[“SM_SYMBOL_NAME”,“SEM_EXPIRY_DATE”,“SEM_OPTION_TYPE”,“SEM_STRIKE_PRICE”,“SEM_SMST_SECURITY_ID”]].reset_index(drop=True)

print(“Contracts loaded:”, len(contracts))if contracts.empty:raise Exception(“No contracts found”)

---------- STEP 3: EXCEL SETUP ----------

wb = xw.Book(“nifty_live.xlsx”)sheet = wb.sheets[0]sheet.clear()

sheet.range(“A1:J1”).value = [“SYMBOL”, “EXPIRY”, “TYPE”, “STRIKE”,“OPEN”, “HIGH”, “LOW”, “CLOSE”,“PREV CLOSE”, “LTP”]

sheet.range(“A2”).value = contracts[[“SM_SYMBOL_NAME”, “SEM_EXPIRY_DATE”, “SEM_OPTION_TYPE”, “SEM_STRIKE_PRICE”]].values.tolist()

---------- STEP 4: WEBSOCKET SYMBOLS ----------

symbols = [(marketfeed.NSE_FNO, str(x))for x in contracts[“SEM_SMST_SECURITY_ID”]]

feed = marketfeed.DhanFeed(CLIENT_ID,ACCESS_TOKEN,symbols,1 # :backhand_index_pointing_left: FORCE VERSION = 1 (Ticker))

---------- STEP 5: DATA STORAGE ----------

ohlc = {}last_excel_update = 0

---------- STEP 6: CALLBACK ----------

def on_message(tick):global last_excel_update

token = str(tick[“securityId”])
ltp = tick[“ltp”]
prev_close = tick.get(“prev_close”, ltp)

if token not in ohlc:
ohlc[token] = {
“open”: ltp,
“high”: ltp,
“low”: ltp,
“close”: ltp,
“prev_close”: prev_close
}
else:
ohlc[token][“high”] = max(ohlc[token][“high”], ltp)
ohlc[token][“low”] = min(ohlc[token][“low”], ltp)
ohlc[token][“close”] = ltp

Throttle Excel updates

if time.time() - last_excel_update < EXCEL_UPDATE_MS:
return

last_excel_update = time.time()

idx = contracts.index[
contracts[“SEM_SMST_SECURITY_ID”].astype(str) == token
]

if not idx.empty:
row = idx[0] + 2
data = ohlc[token]

sheet.range(f"E{row}:J{row}").value = [
    data["open"],
    data["high"],
    data["low"],
    data["close"],
    data["prev_close"],
    ltp
]

---------- STEP 7: START ----------

feed.on_message = on_messageprint(“WebSocket running…”)feed.run_forever()

=====================================Output=========================

PS C:\DemoNSEOption> python nifty_atm_10_live_excel.pyStarting NIFTY ATM ±10 LIVE SYSTEMContracts loaded: 84WebSocket running…Traceback (most recent call last):File “C:\DemoNSEOption\nifty_atm_10_live_excel.py”, line 136, infeed.run_forever()File “C:\Users\ASHISH BHANDARI\AppData\Roaming\Python\Python312\site-packages\dhanhq\marketfeed.py”, line 53, in run_foreverself.loop.run_until_complete(self.connect())File “C:\Python312\Lib\asyncio\base_events.py”, line 687, in run_until_completereturn future.result()^^^^^^^^^^^^^^^File “C:\Users\ASHISH BHANDARI\AppData\Roaming\Python\Python312\site-packages\dhanhq\marketfeed.py”, line 73, in connectraise ValueError(f"Unsupported version: {self.version}")ValueError: Unsupported version: 1

=====================Can u assit issue resolve=====================