[API V2/V3] Invalid Instrument Key Error for Nifty 50 Index Options (NSE_INDEX|Nifty 50) - Requesting Master Contract/Expiries

Hi everyone,

I’m working on integrating the Upstox API into a Python application and running into a persistent issue when trying to retrieve option contracts/expiries for the Nifty 50 Index.

I would appreciate it if anyone who has successfully implemented this call could point out what I might be missing, or if there is a known versioning/scope issue.

1. Goal

I am trying to fetch the list of available option contracts (the option chain or expiry list) for the Nifty 50 Index.

2. Implementation Details

  • Language/SDK: Python (using requests and/or the official Upstox Python SDK wrappers)

  • Authentication: Successful (access token is generated and works for other basic calls, like profile details).

  • Index Key Used: NSE_INDEX|Nifty 50

3. The Problem

Based on the official documentation, I am trying to use the GET /option/contract endpoint, but the request fails.

A. Original Error (Observed in local logs):

My initial attempts were hitting a different endpoint (possibly old/internal), which resulted in a failure before the call was fully formed:

Code snippet

DEBUG: Fetching expiries using URL: https://api-v2.upstox.com/v2/market-quote/instruments/expiries with key: NSE_INDEX|Nifty 50
...
127.0.0.1 - - [08/Oct/2025 22:21:19] "GET /get_master_contract?index=NIFTY_50 HTTP/1.1" 404 -

B. Current Error (When targeting the documented endpoint):

When I explicitly use the correct, documented endpoint for option contracts (/v2/option/contract), I receive an API error response:

Request URL Pattern: https://api.upstox.com/v2/option/contract?instrument_key=NSE_INDEX%7CNifty%2050

API Response Status & Body:

  • HTTP Status Code:
    127.0.0.1 - - [08/Oct/2025 22:20:06] “GET / HTTP/1.1” 200 -

    127.0.0.1 - - [08/Oct/2025 22:20:07] “GET /favicon.ico HTTP/1.1” 404 -

    127.0.0.1 - - [08/Oct/2025 22:20:08] “GET /login HTTP/1.1” 302 -

    127.0.0.1 - - [08/Oct/2025 22:21:15] “GET /callback?code=yqHgZ_ HTTP/1.1” 302 -

    127.0.0.1 - - [08/Oct/2025 22:21:15] “GET /dashboard HTTP/1.1” 200 -

    DEBUG: Fetching expiries using URL: https://api-v2.upstox.com/v2/market-quote/instruments/expiries with key: NSE_INDEX|Nifty 50

    127.0.0.1 - - [08/Oct/2025 22:21:19] “GET /get_master_contract?index=NIFTY_50 HTTP/1.1” 404 -

  • Error Body: [The JSON block for the 401 error above.]


4. Steps Taken & Verification

  1. Instrument Key: Confirmed that NSE_INDEX|Nifty 50 is the correct, case-sensitive key for the Nifty 50 Index itself, as confirmed by Upstox support and the instrument master CSV.

  2. Instrument File Check: I have the latest complete.csv file, and confirmed the index key format.

  3. Endpoint Change: Switched from the possibly internal /expiries endpoint to the public /option/contract endpoint.

5. My Questions to the Community

  1. Is the GET /v2/option/contract endpoint the definitively correct and currently active way to retrieve all option expiries for a major index like Nifty 50?

  2. If you are using this API, are there any specific access token scopes (beyond basic market data) required to hit the /option/contract endpoint? Is it common to receive a 401 Unauthorized or 400 Bad Request if a specific scope is missing?

  3. Has anyone experienced an issue where the correct instrument key (NSE_INDEX|Nifty 50) still fails and had to use a different token/key for the index?

Any guidance is greatly appreciated! Thank you for your time.

Prashant

Hi @PRASHANT_1084688 , I’m able to retrieve the option contracts using the following cURL command:

curl --location 'https://api.upstox.com/v2/option/contract?instrument_key=NSE_INDEX%7CNifty%2050' \
--header 'Authorization: Bearer {access_token}'

You’re also using the correct instrument_key, and no additional permissions are required for this API.

However, it seems you’re trying to fetch the expiry using the URL https://api-v2.upstox.com/v2/market-quote/instruments/expiriesbefore retrieving the option contracts. The 404 error you’re receiving is expected because there’s no such API available to fetch expiry dates.

If you are still facing this issue, kindly share your 6 digit UCC for debugging

Thanks

Update: Cleared Python Errors, Now Facing Persistent HTTP 400

Thanks for the guidance on the endpoints! I’ve implemented the correct logic in my Python code to handle the API response structure, and the 'list' object has no attribute 'get' Python errors are now resolved.

However, I am stuck on the last mile, which appears to be an API access or instrument key configuration issue.

1. Status of Quotes API (LTP)

The request to fetch the Live Trading Price (LTP) for the index is consistently failing with a 400 Client Error: Bad Request. This prevents the application from getting the current price and, therefore, blocks the whole live data flow (Option Chain falls back to mock data).

  • Endpoint: GET /market-quote/quotes

  • Instrument Key: NSE_INDICES|Nifty 50

  • Observed Error:

    [2025-10-15 12:43:00,319] ERROR in main: Upstox API Call to /market-quote/quotes failed: 400 Client Error: Bad Request for url: https://api-v2.upstox.com/market-quote/quotes?instrument_key=NSE_INDICES%7CNifty+50
    
    

2. Status of Option APIs (After Python Fixes)

After ensuring my code handles a direct list response from the API, the application now tries to call the Option APIs:

  • Endpoint: GET /v2/option/contract

  • Endpoint: GET /v2/option/chain

Since the LTP API is failing (Error 1), my code correctly falls back to mock data, preventing me from confirming the HTTP status code for the Option APIs (it currently relies on the failing LTP to choose a strike). However, the previous logs suggest the token is valid (no 401 now), meaning the key or scope for Option APIs is likely still problematic.

My Key Question to the Upstox Team:

What is the definitive, currently accepted instrument key for the Nifty 50 Index when calling the /market-quote/quotes endpoint?

Is NSE_INDICES|Nifty 50 correct, or should I be using NSE_INDEX|Nifty 50 or another key entirely?

I strongly suspect the 400 Bad Request is due to either:

  1. The Instrument Key format for the /quotes endpoint.

  2. Missing Scopes for market_feed (though I have verified this in the developer console).

Any immediate guidance on the correct quotes key or potential scope restrictions would be appreciated!

About the 6 digit UCC for debugging, You mean my user ID: its 163010

Hi @PRASHANT_1084688, For indices use NSE_INDEX|Nifty 50

For complete list of instruments please download the Instrument JSON Instruments | Upstox Developer API

For market feed refer the API documentation Market Data Feed V3 | Upstox Developer API

Thanks

Hello Anand/Support Team,

I’m developing a Flask dashboard using the Upstox V2 API, and I am encountering two persistent and critical issues related to API stability and data structure:

1. WebSocket Authorization Failure (Error: UDAPI100012)

Despite confirming the base URLs in my code, the WebSocket market feed authorization consistently fails immediately after generating a fresh access token via the OAuth flow.

  • Endpoint Called: GET https://api.upstox.com/v2/market-quote/feed/websocket/authorize

  • Error Received (Console Log):

    JSON

    {'status': 'error', 'errors': [{'errorCode': 'UDAPI100012', 'message': 'Invalid Endpoint', ...}]}
    
    
  • Question: Could you please confirm if this error is related to missing API key scopes (e.g., must market_feed be explicitly requested?) or if there’s a specific, recent change to the required headers or base path for this endpoint?


2. Option Chain Data Structure Issue (Causes Python Crash)

The Option Chain endpoint returns a successful response structure most of the time, but when data is unavailable or a failure occurs, it returns an unexpected data type that causes a runtime crash on the client side.

  • Endpoint Called: GET https://api.upstox.com/v2/option/chain

  • Problem: The API response body, when converted to JSON, is sometimes a Python list instead of the expected JSON dictionary.

  • Client Crash: This leads to an AttributeError: 'list' object has no attribute 'get' when trying to check for a status field.

  • Question: Can you confirm the guaranteed response structure for the Option Chain endpoint in all scenarios (success, no data, and explicit failure)? We request that the endpoint consistently return a JSON dictionary with a status field to allow for robust error handling.

Any guidance on these two points would be greatly appreciated as they are currently blocking the application’s launch.

Thank you.