Critical | Security BUG | V3 Historical & Intraday Data NOT protected

@Ushnota , @Pradeep_Jaiswar Tagging you because this seems to be CRITICAL !!

The following V3 APIs are not protected. During my work I figured out that they don’t respect the access_token

As per their documentation pages, both the above URLS expects --header ‘Authorization: Bearer {your_access_token}’ in the request. Excerpt from the documentation :

curl --location ‘``https://api.upstox.com/v3/historical-candle/intraday/NSE_EQ|INE848E01016/minutes/1``’ \
–header ‘Content-Type: application/json’ \
–header ‘Accept: application/json’ \
–header ‘Authorization: Bearer {your_access_token}’

Now to my surprise, these URLs work seamlessly even if the entire –header ‘Authorization: Bearer {your_access_token} is NOT present !!!

So anybody in the world can access the same without any authentication !!!

Below is sample code, you may test it for yourself: (Notice that there is NO --header 'Authorization: Bearer {your_access_token} specified for the header)

Below my sample code for Intraday URL:

import requests
import pandas as pd

requestHeaders = {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
}
url = "https://api.upstox.com/v3/historical-candle/intraday/NSE_EQ|INE883F01010/minutes/5"
response = requests.get(url, headers=requestHeaders)
print(f"Response={response.status_code}")
df= pd.DataFrame(response)
print(f"Response={df}")

Output:

Response=200
Response=                                                    0
0   b’{“status”:“success”,“data”:{“candles”:[[“202…
1   b’0”,471.55,471.55,468.7,470.35,36598,0],[“202…
2   b’0”,469.8,472.0,469.6,471.5,8009,0],[“2026-02…
3   b’70.2,470.4,470.0,470.25,903,0],[“2026-02-12T…
4   b’,470.7,470.15,470.6,782,0],[“2026-02-12T14:4…
5   b’470.45,470.05,470.35,348,0],[“2026-02-12T14:…
6   b’0.75,470.05,470.55,619,0],[“2026-02-12T14:25…
7   b’,470.1,470.15,197,0],[“2026-02-12T14:15:00+0…
8   b’1,470.5,420,0],[“2026-02-12T14:05:00+05:30”,…
9   b’9,538,0],[“2026-02-12T13:55:00+05:30”,470.95…
10  b’,0],[“2026-02-12T13:45:00+05:30”,470.65,470…
11  b’,[“2026-02-12T13:35:00+05:30”,470.8,470.95,4…
12  b’026-02-12T13:25:00+05:30”,470.7,471.15,470.5…
13  b’-12T13:15:00+05:30”,471.0,471.2,470.55,471.1…
14  b’3:05:00+05:30”,471.65,471.75,470.85,470.85,7…
15  b’2:55:00+05:30”,471.15,471.9,471.0,471.3,2749…
16  b’0+05:30”,471.2,471.2,471.0,471.1,306,0],[“20…
17  b’”,471.0,471.25,471.0,471.2,433,0],[“2026-02-…
18  b’05,471.25,471.0,471.0,223,0],[“2026-02-12T12…
19  b’1.25,471.0,471.1,334,0],[“2026-02-12T12:10:0…
20  b’1.0,471.1,521,0],[“2026-02-12T12:00:00+05:30…
21  b’71.8,459,0],[“2026-02-12T11:50:00+05:30”,471…
22  b’974,0],[“2026-02-12T11:40:00+05:30”,472.2,47…
23  b’],[“2026-02-12T11:30:00+05:30”,471.45,471.45…
24  b’026-02-12T11:20:00+05:30”,471.85,472.2,471.0…
25  b’026-02-12T11:10:00+05:30”,471.0,471.6,470.9,…
26  b’-02-12T11:00:00+05:30”,471.0,471.5,470.8,471…
27  b’-12T10:50:00+05:30”,470.75,471.35,470.75,471…
28  b’2T10:40:00+05:30”,471.35,471.4,471.05,471.1,…
29  b’T10:30:00+05:30",471.0,471.4,471.0,471.25,36…
30  b’00+05:30",471.45,471.45,471.0,471.0,542,0],[…
31  b’5:30",471.4,471.75,471.0,471.2,2337,0],[“202…
32  b’”,471.45,471.8,471.05,471.05,696,0],["2026-0…
33  b’471.5,471.65,470.8,471.4,602,0],["2026-02-12…
34  b’1,471.45,471.05,471.35,767,0],["2026-02-12T0…
35  b’1.8,471.15,471.8,3167,0],["2026-02-12T09:25:…
36  b’,470.95,471.3,3599,0],["2026-02-12T09:15:00+…

Process finished with exit code 0

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


Sample code for Historical Data :

import requests
import pandas as pd

requestHeaders = {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
}
url = "https://api.upstox.com/v3/historical-candle/NSE_EQ|INE509F01029/minutes/3/2026-02-11/2026-02-09"response = requests.get(url, headers=requestHeaders)
print(f"Response={response.status_code}")
df= pd.DataFrame(response)
print(f"Response={df}")

Respose :

Response=200
Response=                                                     0
0    b’{“status”:“success”,“data”:{“candles”:[[“202…
1    b’”,434.7,435.35,434.0,434.15,61378,0],[“2026-…
2    b’,433.55,434.8,432.8,434.55,35745,0],[“2026-0…
3    b’,432.45,433.6,432.0,433.45,61002,0],[“2026-0…
4    b’”,433.8,433.8,432.5,432.8,24596,0],[“2026-02…
..                                                 …
182  b’-02-09T09:36:00+05:30”,422.95,423.65,421.55,…
183  b’26-02-09T09:30:00+05:30”,422.4,424.4,421.55,…
184  b’026-02-09T09:24:00+05:30”,422.95,424.85,422…
185  b’026-02-09T09:18:00+05:30",423.95,424.95,423…
186                                            b’]]}}’

[187 rows x 1 columns]

Process finished with exit code 0

Let me know if that helps !!

This is a SEVERE SECURITY ISSUE !!

Let me know if I can help with any more details

Thanks

Nitish

9663324524

This is BROKEN so bad that any body in the world can access it !!

It can even open in ANY browser, without anyone even having Upstox Account !!

just click the url and you can understand the SEVERITY of this !!!

https://api.upstox.com/v3/historical-candle/NSE_EQ|INE509F01029/minutes/3/2026-02-11/2026-02-09 \

or

https://api.upstox.com/v3/historical-candle/intraday/NSE_EQ|INE883F01010/minutes/5

Hi @NITISH_21951215, The Historical and Intraday Candles APIs do not require an access token, as these are data endpoints and are open to all users. We’ll update the examples in the documentation accordingly. Thanks for your feedback.

Thanks @Anand_Sajankar , but why was not the case with the V2 urls

Historical Candle Data | Upstox Developer API , seems that still seeks auth-token.

So I understand now that this details are available in public domain, and any one without even having Upstox Account can have access to the OHLC data. Even though there would be rate-limits, so would that mean the backend server can process any number of N different requests from different clients??

So if this “Working as Designed”, so I assume it remains like this and Upstox serves here as free source for Market Data Provider (while many other Brokers charge a subscription for the same), and that itself suffices the CRUX of any trading application/software. So anyone can read using the Upstox’s free api and then redirect their trade orders to any other Brokers’s API !!

Is that correct assumptions and thoughts???

Theoretically you can. But we hope you do use our API and if there are any suggestions on how it can be made better - do let us know!

Thanks @shrini , @Anand_Sajankar !!

Yes, I’ve been using the APIs, and I’ve found them great and evolving with time too. With the new V3 endpoints for Historical Candle Data V3, I see thoughtful implementations to retrieve data in custom time intervals, that’ really an edge.

I am changing my application to adapt to the newer versions, and this behavior alarmed me to flag it to the Upstox team !!

Just a kind request if the team may keep the documentation updated, it would help us save us some time in adapting to the latest feeds that Upstox keeps enhancing to..for good :slight_smile: (Some while back I noticed a changed in behavior for downloading the instruments file from CSV to JSON based –again a very thoughtful aspect, but I had to bring to the team’s notice as I stumbled there too due to some undocumented changes. : Instruments csv depreciation : field last_price is not present in the json - #5 by NITISH_21951215 )

@Anand_Sajankar

There is one thing which keeps me little worried about the orders API. Presently the APIs are a mix of V3 and V2 version urls.

For placing orders, there are new V3 urls : https://api-hft.upstox.com/v3/order, however, we need to fall back to V2 url to see the details of the order (that was placed using V3, as there is no V3 equivalent of the same to check-orders) – In case this behavior stays same in future, kindly add a note there, as many would have stumbled over this.

Thanks all for your attentions !! The documentation have been written in a very rich standard way, and have always helpful source for me, The API has been evolving, good in performance and I keep seeing updates which made me to stop using the SDK and move to the APIs. !!

Thanks again !!

Best Wishes

Nitish