Realtime Market Data (WebSocket)¶
This section documents Nubra's WebSocket streams for real-time market data in the REST API. Use these streams for low-latency updates on indexes, instruments, order books, option chains, and Greeks.
Method: WebSocket
Endpoint: /apibatch/ws
WebSocket URLs¶
| Environment | WebSocket URL |
|---|---|
| UAT | wss://uatapi.nubra.io/apibatch/ws |
| Production | wss://api.nubra.io/apibatch/ws |
Available WebSocket Streams¶
| Stream | Channel | Description |
|---|---|---|
| Index Data | index |
Live index and instrument ticks including LTP, volume, and percentage change. |
| Index Bucket (OHLCV) | index_bucket |
Time-bucketed OHLCV data for indexes and instruments. |
| Order Book | orderbook |
Market depth with bid/ask levels, LTP, LTQ, and volume. |
| Greeks | greeks |
Tick-level option Greeks for option instruments. |
| Option Chain | option |
Full option chain updates by asset and expiry. |
WebSocket Stream Controls¶
These commands modify stream behavior across channels.
| Feature | Command | Scope | Description |
|---|---|---|---|
| Stream Interval | socket_interval |
Per channel | Controls the update frequency of WebSocket streams. |
| Post Market Data | post_market |
Connection-level | Enables static post-market data for testing and validation after market hours. |
| Order Book Depth | orderbook_depth |
Per connection | Controls the number of order-book levels streamed. |
Message Envelope (GenericData)¶
All WebSocket payloads are wrapped in a common envelope.
message GenericData {
string key = 1;
google.protobuf.Any data = 2;
}
keyidentifies the message type.datacontains one of the stream payloads defined below.
1. Index Data¶
Channel: index
Subscribe / Unsubscribe¶
SUBSCRIBE: batch_subscribe [token] index {"indexes":["BANKNIFTY","TCS","RELIANCE"]} NSE
UNSUBSCRIBE: batch_unsubscribe [token] index {"indexes":["BANKNIFTY","TCS","RELIANCE"]} NSE
Notes:
- exchange is sent at the message level, for example NSE or BSE.
- Both index symbols and instrument symbols are sent in the indexes array.
- The response separates them into indexes and instruments.
- The JSON object must not contain spaces.
Payload (Proto)¶
message BatchWebSocketIndexMessage {
int64 timestamp = 1;
repeated WebSocketMsgIndex indexes = 2;
repeated WebSocketMsgIndex instruments = 3;
}
message WebSocketMsgIndex {
string indexname = 1;
int64 timestamp = 2;
int64 index_value = 3;
int64 high_index_value = 4;
int64 low_index_value = 5;
int64 volume = 6;
float changepercent = 7;
int64 tick_volume = 8;
int64 prev_close = 9;
string exchange = 10;
int64 volume_oi = 11;
}
2. Index Bucket (OHLCV)¶
Channel: index_bucket
Subscribe / Unsubscribe¶
SUBSCRIBE: batch_subscribe [token] index_bucket {"indexes":["BANKNIFTY","TCS","RELIANCE"]} 2m NSE
UNSUBSCRIBE: batch_unsubscribe [token] index_bucket {"indexes":["BANKNIFTY","TCS","RELIANCE"]} 2m NSE
Notes:
- interval and exchange are sent at the message level.
- Both index symbols and instrument symbols are sent in the indexes array.
- The response separates them into indexes and instruments.
- The JSON object must not contain spaces.
- Interval values are returned in the payload as an Interval enum.
Supported Intervals¶
The server accepts the following interval strings in the subscribe command:
1s,5s,10s,30s1m,2m,3m,5m,10m,15m,30m1h,2h,4h1d1w1mt1yr
Important: Although the
Intervalenum includes values fromINTERVAL_INVALID = 0throughINTERVAL_1_YEAR = 16, the following enum values are currently not available forindex_bucket: -INTERVAL_INVALID = 0-INTERVAL_1_SECOND = 1-INTERVAL_10_SECOND = 2-INTERVAL_1_YEAR = 16
Payload (Proto)¶
message BatchWebSocketIndexBucketMessage {
int64 timestamp = 1;
repeated WebSocketMsgIndexBucket indexes = 2;
repeated WebSocketMsgIndexBucket instruments = 3;
}
message WebSocketMsgIndexBucket {
string indexname = 1;
string exchange = 2;
Interval interval = 3;
int64 timestamp = 4;
int64 open = 5;
int64 high = 6;
int64 low = 7;
int64 close = 8;
int64 bucket_volume = 9;
int64 tick_volume = 10;
int64 cumulative_volume = 11;
int64 bucket_timestamp = 12;
}
Interval Enum (Proto)¶
enum Interval {
INTERVAL_INVALID = 0;
INTERVAL_1_SECOND = 1;
INTERVAL_10_SECOND = 2;
INTERVAL_1_MINUTE = 3;
INTERVAL_2_MINUTE = 4;
INTERVAL_3_MINUTE = 5;
INTERVAL_5_MINUTE = 6;
INTERVAL_10_MINUTE = 7;
INTERVAL_15_MINUTE = 8;
INTERVAL_30_MINUTE = 9;
INTERVAL_1_HOUR = 10;
INTERVAL_2_HOUR = 11;
INTERVAL_4_HOUR = 12;
INTERVAL_1_DAY = 13;
INTERVAL_1_WEEK = 14;
INTERVAL_1_MONTH = 15;
INTERVAL_1_YEAR = 16;
INTERVAL_5_SECOND = 17;
}
Interval Mapping (Subscribe String -> Enum)¶
Use these mappings to interpret WebSocketMsgIndexBucket.interval:
1m->INTERVAL_1_MINUTE (3)2m->INTERVAL_2_MINUTE (4)3m->INTERVAL_3_MINUTE (5)5m->INTERVAL_5_MINUTE (6)10m->INTERVAL_10_MINUTE (7)15m->INTERVAL_15_MINUTE (8)30m->INTERVAL_30_MINUTE (9)1h->INTERVAL_1_HOUR (10)2h->INTERVAL_2_HOUR (11)4h->INTERVAL_4_HOUR (12)1d->INTERVAL_1_DAY (13)1w->INTERVAL_1_WEEK (14)1mt->INTERVAL_1_MONTH (15)5s->INTERVAL_5_SECOND (17)
Note: Even if the subscribe command allows
1s,5s,10s,30s, the payload enum set shown above does not include30svalues.
3. Order Book¶
Channel: orderbook
Provides real-time market depth, LTP, LTQ, and traded volume for subscribed instruments.
Subscribe / Unsubscribe¶
SUBSCRIBE: batch_subscribe [token] orderbook {"instruments":[1120031,73009]}
UNSUBSCRIBE: batch_unsubscribe [token] orderbook {"instruments":[1120031,73009]}
By default, the order book stream sends up to 20 bid and ask levels per instrument.
Order Book Depth (Selective Levels)¶
Users can subscribe to a specific depth level from 1 to 20 instead of receiving all 20 levels.
MESSAGE: batch_subscribe [token] orderbook_depth 4
Notes:
- This setting applies to the orderbook channel.
- orderbook_depth 4 streams the top 4 bid and ask levels only.
- If not specified, the default depth is 20.
Payload (Proto)¶
message BatchWebSocketOrderbookMessage {
int64 timestamp = 1;
repeated WebSocketMsgOrderBook instruments = 2;
}
message WebSocketMsgOrderBook {
uint32 inst_id = 1;
int64 timestamp = 2;
repeated OrderBookLevel bids = 3;
repeated OrderBookLevel asks = 4;
int64 ltp = 5;
int64 ltq = 6;
int64 volume = 7;
int64 ref_id = 8;
}
message OrderBookLevel {
int64 price = 1;
int64 quantity = 2;
int64 orders = 3;
}
Notes¶
- The number of
bidsandasksentries depends on the subscribed order-book depth. bids[0]andasks[0]represent the best bid and best ask respectively.
4. Greeks¶
Channel: greeks
Subscribe / Unsubscribe¶
SUBSCRIBE: batch_subscribe [token] greeks {"instruments":[1120031,1120032]}
UNSUBSCRIBE: batch_unsubscribe [token] greeks {"instruments":[1120031,1120032]}
Payload (Proto)¶
message BatchWebSocketGreeksMessage {
int64 timestamp = 1;
repeated WebSocketMsgOptionChainItem instruments = 2;
}
message WebSocketMsgOptionChainItem {
int64 inst_id = 1;
int64 ts = 2;
int64 sp = 3;
int32 ls = 4;
int64 ltp = 5;
float ltpchg = 6;
float iv = 7;
float delta = 8;
float gamma = 9;
float theta = 10;
float vega = 11;
int64 oi = 12;
int64 volume = 13;
int64 ref_id = 14;
int64 prev_oi = 15;
int64 price_pcp = 16;
}
5. Option Chain¶
Channel: option
Subscribe / Unsubscribe¶
SUBSCRIBE: batch_subscribe [token] option [{"exchange":"NSE","asset":"RELIANCE","expiry":"20260224"},{"exchange":"BSE","asset":"SENSEX","expiry":"20260205"},{"exchange":"NSE","asset":"NIFTY","expiry":"20260203"}]
UNSUBSCRIBE: batch_unsubscribe [token] option [{"exchange":"NSE","asset":"RELIANCE","expiry":"20260224"},{"exchange":"BSE","asset":"SENSEX","expiry":"20260205"},{"exchange":"NSE","asset":"NIFTY","expiry":"20260203"}]
Notes: - The JSON array must not contain spaces. - Option chain updates are received in the older format: one packet per subscribed chain (not batched together).
Payload (Proto)¶
message WebSocketMsgOptionChainUpdate {
string asset = 1;
string expiry = 2;
repeated WebSocketMsgOptionChainItem ce = 3;
repeated WebSocketMsgOptionChainItem pe = 4;
int64 atm = 5;
int64 currentprice = 6;
string exchange = 7;
}
Stream Interval Control¶
Users can control the update frequency of WebSocket streams by subscribing to a stream interval.
Set Stream Interval¶
MESSAGE: batch_subscribe [token] socket_interval option 1m
Notes:
- The stream interval applies to the specified channel, for example option, index, orderbook, greeks, or index_bucket.
- Interval settings are connection-level and affect subsequent subscriptions on that channel unless changed.
- If no interval is specified, the default behavior is tick-level streaming.
Supported Stream Intervals¶
The following interval strings are supported:
1s5s10s30s1m5m10m
Subscription Limits by Interval¶
Second-Based Intervals (Limited)¶
The following intervals have standard subscription limits:
1s5s10s30s
Notes: - These intervals are subject to per-connection and per-channel subscription limits. - Recommended for latency-sensitive strategies requiring near real-time updates.
Minute-Based Intervals (Unlimited)¶
The following intervals currently have no subscription limits:
1m5m10m
Notes: - You can subscribe to any number of instruments when using these intervals. - Ideal for strategies focused on candle-based logic, scans, or lower-frequency signals. - Significantly reduces bandwidth and processing overhead compared to second-level streams.
Example¶
Subscribe to the option chain stream with 1-minute updates:
MESSAGE: batch_subscribe [token] socket_interval option 1m
MESSAGE: batch_subscribe [token] option [{"exchange":"NSE","asset":"NIFTY","expiry":"20260203"}]
Best Practices¶
- Use second-based intervals only when necessary for execution or market-making strategies.
- Prefer minute-based intervals for monitoring, analytics, and signal generation.
- Combine
socket_intervalwith features like order book depth control to further optimize performance.
Post Market Data¶
Post-market data is available for testing and validation. This data represents an end-of-day static market snapshot and does not stream live updates.
Enable Post Market Mode¶
MESSAGE: batch_subscribe [token] post_market true
Notes: - When enabled, WebSocket streams return static post-market data instead of live ticks. - Data remains unchanged for the duration of the session. - This mode is intended for strategy testing, validation, and integration development. - Post-market data is available only after the market has closed.
Key Characteristics¶
- Static data with no live updates
- Same payload structures as live streams
- Useful for non-market-hour testing and demos
Example Workflow¶
Enable post-market mode and subscribe to an index stream:
MESSAGE: batch_subscribe [token] post_market true
MESSAGE: batch_subscribe [token] index {"indexes":["NIFTY","BANKNIFTY"]} NSE
Notes¶
- Post-market mode applies at the connection level.
- To resume live data, reconnect without enabling
post_market.