Skip to Main Content
WSwss://api.shoonya.com/NorenWSAPI/

WebSocket Overview

How the Shoonya WebSocket feed is structured, and when to use it instead of REST polling.

Overview

The WebSocket gateway delivers independent feed types over one connection: live touchline ticks, market depth, and order-status updates. You connect once, then subscribe to each feed type separately.

Purpose

Use the WebSocket for anything that needs to react to price movement or fills in real time — strategy engines, live dashboards, risk monitors. It replaces polling Market Quotes or Order Book in a loop.

Connection flow

  1. Open a WebSocket connection to wss://api.shoonya.com/NorenWSAPI/.
  2. Send a connect frame (t: "a") with uid, actid, source, and accesstoken.
  3. Wait for the connect acknowledgment (t: "ak") and check s is "Ok" before subscribing to anything.
  4. Send subscribe frames for touchline and/or order updates.
  5. Handle incoming ticks; respond to server pings to keep the session alive.

Connect request (t: 'a')

json
{
  "t": "a",
  "uid": "AB1234",
  "actid": "AB1234",
  "source": "API",
  "accesstoken": "Acesstoken"
}
FieldPossible valueDescription
taRepresents the connect task.
uidUser ID.
actidAccount ID.
sourceWEB / MOB / APIMust match the source used at login.
accesstokenUser access token from login/OAuth.

Connect acknowledgment (t: 'ak')

json
{ "t": "ak", "uid": "AB1234", "s": "Ok" }
FieldPossible valueDescription
takRepresents the connect acknowledgment.
uidUser ID.
sOk / Not_OkNot_Ok means an invalid user ID or session/access token — do not proceed to subscribe.
Don't confuse this with the touchline ackt: "ak" is the connect handshake response only. The touchline subscribe acknowledgment is a different message with t: "tk" — see Subscribe to Market Feed. Mixing the two up is a common source of parsing bugs since both arrive as JSON with a t field early in the connection.

Request example

import websocket, json

def on_open(ws):
    ws.send(json.dumps({
        "t": "a",
        "uid": UID,
        "actid": ACTID,
        "source": "API",
        "accesstoken": Acesstoken,
    }))

def on_message(ws, message):
    print(json.loads(message))

ws = websocket.WebSocketApp(
    "wss://api.shoonya.com/NorenWSAPI/",
    on_open=on_open, on_message=on_message,
)
ws.run_forever()
const ws = new WebSocket("wss://api.shoonya.com/NorenWSAPI/");

ws.onopen = () => ws.send(JSON.stringify({
  t: "a", uid, actid, source: "API", accesstoken: Acesstoken,
}));
ws.onmessage = (event) => console.log(JSON.parse(event.data));
# WebSocket connections aren't expressible in cURL —
# use `websocat` for a quick command-line test:
websocat wss://api.shoonya.com/NorenWSAPI/

Error handling

DisconnectsThe gateway will drop idle connections. Implement exponential-backoff reconnect logic, re-send the connect frame, and re-send every subscription after every reconnect — nothing persists across a dropped socket.

Best practices

  • Run one WebSocket connection per process; multiplex symbols over it rather than opening one socket per instrument.
  • Process incoming ticks on a separate thread/queue from your order-placement logic so a slow strategy calculation never blocks the read loop.
  • Always check s: "Ok" on the connect ack before subscribing — subscribing on a failed connect silently produces no data.

Python example

python
from shoonya_api import ShoonyaFeed

feed = ShoonyaFeed(uid=UID, actid=ACTID, session_token=Acesstoken)
feed.on_tick = lambda tick: print(tick.token, tick.ltp)
feed.connect()
feed.subscribe(["NSE|2885"])

Notes

See Subscribe to Market Feed and Order Update Feed for the exact frame formats of each subscription type.