Issue with Live Market Data Feed for Websocke

Hello Upstox Team / Community,

I am currently using a Basic plan account and trying to access the Upstox V3 market data feed via WebSocket for both indices (e.g., Nifty Bank) and equities (e.g., RELIANCE).

Here is what I observe:

  • WebSocket connects successfully. :white_check_mark:

  • Market info messages are received (server time, segment status). :white_check_mark:

  • Subscriptions to indices work, but no LTP/feed data is received for equities. :warning:

I am using the following subscription request structure, as per the Upstox V3 documentation:
import asyncio
import json
import ssl
import requests
import websockets
import nest_asyncio
import uuid
from datetime import datetime
import time
from google.protobuf.json_format import MessageToDict
import MarketDataFeedV3_pb2 as pb # compiled proto

Allow nested asyncio loops (for Jupyter)

nest_asyncio.apply()

def get_market_data_feed_authorize_v3(access_token: str):
“”“Direct V3 authorization call (bypasses v2 SDK).”“”
url = “https://api.upstox.com/v3/feed/market-data-feed/authorize”
headers = {“Authorization”: f"Bearer {access_token}"}
resp = requests.get(url, headers=headers)
resp.raise_for_status()
data = resp.json()
print(“:key: Authorization response:”, data)
return data[“data”][“authorized_redirect_uri”]

def decode_protobuf(buffer):
“”“Decode protobuf message into dictionary.”“”
feed_response = pb.FeedResponse()
feed_response.ParseFromString(buffer)
return MessageToDict(feed_response)

async def fetch_market_data(access_token: str, instruments=None, run_seconds=120):
“”"
Fetch live market data via Upstox V3 WebSocket.

Parameters:
- access_token : str : valid Upstox access token
- instruments : list[str] : list of instrument keys to subscribe
- run_seconds : int : how long to run the feed (optional)
"""
if instruments is None:
    instruments = ["NSE_EQ|RELIANCE"]

end_time = time.time() + run_seconds

while time.time() < end_time:
    try:
        # Step 1: Authorize
        ws_url = get_market_data_feed_authorize_v3(access_token)

        # Step 2: Connect websocket
        ssl_context = ssl.create_default_context()
        # Uncomment below if self-signed certs cause issues
        # ssl_context.check_hostname = False
        # ssl_context.verify_mode = ssl.CERT_NONE

        async with websockets.connect(ws_url, ssl=ssl_context) as websocket:
            print("✅ WebSocket connected")

            # Step 3: Subscribe
            sub_req = {
                "guid": str(uuid.uuid4()),
                "method": "sub",
                "data": {
                    "mode": "full",
                    "instrumentKeys": instruments
                }
            }
            await websocket.send(json.dumps(sub_req))
            print(f"🔔 Subscription sent (full mode): {instruments}")

            # Step 4: Receive messages
            while time.time() < end_time:
                try:
                    message = await asyncio.wait_for(websocket.recv(), timeout=5)

                    if isinstance(message, bytes):
                        decoded = decode_protobuf(message)
                        print("📥 Raw Protobuf Decoded:", decoded)   # 👈 Debug print
                    else:
                        decoded = json.loads(message)
                        print("📥 Raw JSON Message:", decoded)       # 👈 Debug print

                    # 1️⃣ Feed messages (LTPs)
                    if "feeds" in decoded:
                        print("📥 Raw Feed:", decoded)  # debug
                        for instrument, tick in decoded["feeds"].items():
                            ltp = tick.get("ltp") or tick.get("lastPrice") \
                                  or tick.get("ltpc", {}).get("ltp")
                            print(f"📊 {instrument} | LTP = {ltp}")

                    # 2️⃣ Market info messages (raw + parsed view)
                    elif decoded.get("type") == "market_info":
                        ts = decoded.get("currentTs")
                        dt = None
                        if ts:
                            dt = datetime.fromtimestamp(int(ts) / 1000)  # convert ms → seconds

                        market_info = decoded.get("marketInfo", {})
                        segment_status = market_info.get("segmentStatus", {})

                        print("ℹ️ Parsed Market Info:")
                        print(f"   🕒 Server Time: {dt}")
                        for segment, status in segment_status.items():
                            print(f"   📍 {segment}: {status}")

                    # 3️⃣ Subscription confirmation / other messages
                    elif decoded.get("type") == "sub_response":
                        print(f"✅ Subscription Response: {decoded}")

                    else:
                        print("ℹ️ Other Parsed Message:", decoded)

                except asyncio.TimeoutError:
                    print("⚠️ No feed in last 5 sec, waiting...")
                except websockets.ConnectionClosed:
                    print("⚠️ WebSocket closed, reconnecting...")
                    break
                except Exception as e:
                    print("⚠️ Error:", e)
                    await asyncio.sleep(1)

    except Exception as e:
        print("⚠️ Connection failed, retrying in 5 sec...", e)
        await asyncio.sleep(5)

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

Run in Jupyter

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

ACCESS_TOKEN = “-------”

Run for 120 seconds, for example

await fetch_market_data(ACCESS_TOKEN, run_seconds=120)

The output response is:

:key: Authorization response: {‘status’: ‘success’, ‘data’: {‘authorizedRedirectUri’: ‘wss://wsfeeder-api.upstox.com/market-data-feeder/v3/upstox-developer-api/feeds?requestId=44dd2c22-d0ee-43fb-be7b-80930cf95dcc&code=3tDT6-b8f7c414-058e-4c40-9a79-c28139375169’, ‘authorized_redirect_uri’: ‘wss://wsfeeder-api.upstox.com/market-data-feeder/v3/upstox-developer-api/feeds?requestId=44dd2c22-d0ee-43fb-be7b-80930cf95dcc&code=3tDT6-b8f7c414-058e-4c40-9a79-c28139375169’}}
:white_check_mark: WebSocket connected
:bell: Subscription sent (full mode): [‘NSE_EQ|RELIANCE’]
:inbox_tray: Raw Protobuf Decoded: {‘type’: ‘market_info’, ‘currentTs’: ‘1757407087597’, ‘marketInfo’: {‘segmentStatus’: {‘BSE_INDEX’: ‘NORMAL_OPEN’, ‘NSE_COM’: ‘NORMAL_OPEN’, ‘BSE_EQ’: ‘NORMAL_OPEN’, ‘MCX_FO’: ‘NORMAL_OPEN’, ‘NCD_FO’: ‘NORMAL_OPEN’, ‘BCD_FO’: ‘NORMAL_OPEN’, ‘BSE_FO’: ‘NORMAL_OPEN’, ‘NSE_FO’: ‘NORMAL_OPEN’, ‘NSE_EQ’: ‘NORMAL_OPEN’, ‘US_EQ’: ‘NORMAL_CLOSE’, ‘MCX_INDEX’: ‘NORMAL_OPEN’, ‘NSE_INDEX’: ‘NORMAL_OPEN’}}}
:information_source: Parsed Market Info:
:three_o_clock: Server Time: 2025-09-09 14:08:07.597000
:round_pushpin: BSE_INDEX: NORMAL_OPEN
:round_pushpin: NSE_COM: NORMAL_OPEN
:round_pushpin: BSE_EQ: NORMAL_OPEN
:round_pushpin: MCX_FO: NORMAL_OPEN
:round_pushpin: NCD_FO: NORMAL_OPEN
:round_pushpin: BCD_FO: NORMAL_OPEN
:round_pushpin: BSE_FO: NORMAL_OPEN
:round_pushpin: NSE_FO: NORMAL_OPEN
:round_pushpin: NSE_EQ: NORMAL_OPEN
:round_pushpin: US_EQ: NORMAL_CLOSE
:round_pushpin: MCX_INDEX: NORMAL_OPEN
:round_pushpin: NSE_INDEX: NORMAL_OPEN
:warning: No feed in last 5 sec, waiting…

I would like to confirm:

  1. Does the Basic plan allow real-time LTP feeds for equities?

  2. If yes, is there any special permission or setup required to receive these feeds via WebSocket?

  3. If not, can you provide guidance on the plan required to receive live equity feeds?

I would appreciate any advice or documentation references to resolve this issue.

Thank you for your support.

Best regards,
Rashmi More
Email ID - pawarmanesh1437@gmail.com

I was facing same issue, have look in WebSocket Connected but Not Receiving NIFTY 50 Live or LTP Data - #12 by RAIYANI_1192177