Skip to main content

The official Python client for the NEBSL B2C REST API

Project description

pycloudrestapi — Complete Guide

Northeast B2C Trading API — Python Client


What Is This?

pycloudrestapi is a Python library that connects your code to the Northeast B2C REST API — a trading system used by IBT and NEBSL brokers, powered by the Odin/Wave trading engine.

Think of it as a remote control for your trading account. Instead of logging into a trading app manually, you write Python code that logs in, places orders, checks your portfolio, and receives live prices — all automatically.


What Can You Do With It?

  • Account — Login, validate your session, check your balance and margins, and logout.
  • Orders — Place fresh buy or sell orders, modify pending orders (change price or quantity), and cancel orders you no longer want.
  • Order Types — Regular limit (RL), market (RL-MKT), stop loss limit (SL), stop loss market (SL-MKT).
  • Advanced Orders — Cover orders, bracket orders, and multileg orders.
  • Reports — Fetch your full order book (all orders placed today), trade book (all executed trades), and order history (status timeline of a single order).
  • Portfolio — View your open positions, convert positions from intraday to delivery (or vice versa), and check your demat holdings.
  • Live Data — Subscribe to touchline (LTP) and best-five (market depth) data via WebSocket.

Official Documentation ( Recommended )

Full API reference with all endpoints, request schemas, and response structures:

🔗 https://b2c-api-docs.northeastltd.in/docs/B2CAPI/nebsl-b2c-api-docs.html



Installation

pip install nebsl-b2c-api

Credentials You Need

Your broker provides these when they onboard you:

Credential Description
Base URL The server address where all API calls go. Looks like a long AWS or cloud URL.
API Key Your application's identity key. Sent in the login request body.
x-api-key Sent as a header (x-api-key) on every request for authentication.
Second AUTH A PAN number sent in the login request body to authenticate your app.
User ID (UCC) Your Unique Client Code / broker account number. Example: NE2247

⚠️ Never share these credentials or put them in your code directly. Store them in environment variables or a .env file.


Quick Start

from pycloudrestapi import IBTConnect

client = IBTConnect({
    "baseurl": "<your_base_url>",
    "api_key": "<your_api_key>",
    "x-api-key": "<your_x_api_key>",
    "second_auth": "<your_pan_number>",
    "debug": True
})

How Login Works

Every API call (except login itself) requires an access token. You get this token by logging in. The library stores it automatically and sends it with every subsequent request.

  • User ID — Your Unique Client Code
  • Password — Your normal password
# Login
user = client.login({
    "userId": "<your_user_id>",
    "password": "<your_password>"
})
print(user)

Session Management

# Validate session (keep alive) — call periodically
client.validateSession()

# Check available margins
client.balance()

# Logout when done
client.logout()

Understanding Orders

scrip_token — What Is It?

Every stock, futures contract, or options contract on an exchange has a unique number called a scrip token. The API uses this number to identify what you want to trade. For example, RELIANCE on NSE_EQ has token 2885, and IDEA has token 14366.

You get the token from your broker's scrip master file.

exchange — Which Market?

Value Description
NSE_EQ NSE Equity (stocks on NSE)
BSE_EQ BSE Equity (stocks on BSE)
NSE_FO NSE Futures & Options
BSE_FO BSE Futures & Options
MCX_FO MCX Futures (commodities)
NSE_COMM NSE Commodity Derivatives
BSE_COMM BSE Commodity Derivatives

product_type — How Long You Hold It?

Value Description
INTRADAY Also called MIS. Must close before market closes (~3:20 PM for NSE equity). Lower margin required.
DELIVERY Also called CNC. Stock goes into your demat account. Hold as long as you want. Full margin required.
BTST Buy Today Sell Tomorrow.
MTF Margin Trading Facility.

order_type — How Does It Execute?

Value Description
RL Regular Limit — Order sits at your specified price. Executes only when market reaches your price.
RL-MKT Market Order — Executes immediately at the best available market price. Set price to 0.
SL Stop Loss Limit — Set a trigger price and a limit price. When market hits trigger, order activates at limit price.
SL-MKT Stop Loss Market — Like SL but executes at market price once triggered.

validity — How Long Is the Order Active?

Value Description
DAY Valid only for today. Automatically cancelled if not filled by end of day.
IOC Immediate or Cancel.
GTD Good Till Date.
GTC Good Till Cancelled.

trigger_price — When to Use It?

Only needed for SL and SL-MKT order types. For all other orders, always set trigger_price to 0.

strike_price — Important Note for Options

When placing options orders, strike_price must be in paise, not rupees. Multiply the rupee value by 100.

Example: ₹56,000 strike → 5600000 in the API (56000 × 100 = 5600000)


Placing Orders

Equity Order

res = client.place_order({
    "scrip_info": {
        "exchange": "NSE_EQ",
        "scrip_token": 14366,
        "symbol": "",
        "series": "EQ"
    },
    "transaction_type": "BUY",
    "product_type": "DELIVERY",
    "order_type": "RL",
    "quantity": 1,
    "price": 8.59,
    "trigger_price": 0,
    "disclosed_quantity": 0,
    "validity": "DAY",
    "validity_days": 0,
    "is_amo": False,
    "order_identifier": "",
    "part_code": "",
    "algo_id": "",
    "strategy_id": "",
    "vender_code": ""
})

order_id = res["data"]["orderId"]
print("Order ID:", order_id)

Futures Order

res = client.place_order({
    "scrip_info": {
        "exchange": "NSE_FO",
        "scrip_token": 66688,
        "symbol": "BANKNIFTY",
        "expiry_date": "2025-10-31",
        "strike_price": 0,
        "option_type": ""
    },
    "transaction_type": "BUY",
    "product_type": "INTRADAY",
    "order_type": "RL",
    "quantity": 50,
    "price": 56000.00,
    "trigger_price": 0,
    "validity": "DAY"
})

Options Order

res = client.place_order({
    "scrip_info": {
        "exchange": "NSE_FO",
        "scrip_token": 67528,
        "symbol": "BANKNIFTY",
        "expiry_date": "2026-06-30",
        "strike_price": 5600000,   # In paise: ₹56000 × 100 = 5600000
        "option_type": "CE"        # CE = Call, PE = Put
    },
    "transaction_type": "SELL",
    "product_type": "INTRADAY",
    "order_type": "RL",
    "quantity": 30,
    "price": 120.00,
    "trigger_price": 0,
    "validity": "DAY"
})

Modify Order

⚠️ The API requires you to send all fields, not just the ones you want to change. Fetch the order from get_order_book() first to get current values. The traded_quantity field must be fresh from the order book every time.

res = client.modify_order({
    "exchange": "NSE_EQ",
    "order_id": "NXHCO00006A4",
    "order_type": "RL",
    "quantity": 1,
    "traded_quantity": 0,       # Required — get fresh from order book
    "price": 9.00,              # New price
    "trigger_price": 0,
    "disclosed_quantity": 0,
    "validity": "DAY",
    "validity_days": 0
})

Cancel Order

res = client.cancel_order({
    "exchange": "NSE_EQ",
    "order_id": "NXHCO00006A4"
})

Cover Orders

# Place cover order
res = client.place_cover_order({...})

# Modify cover order
res = client.modify_cover_order({
    "exchange": "NSE_EQ",
    "order_id": "NXHCO00006A4",
    ...
})

# Cancel cover order
res = client.cancel_cover_order({
    "exchange": "NSE_EQ",
    "order_id": "NXHCO00006A4"
})

Bracket Orders

# Place bracket order
res = client.place_bracket_order({...})

# Modify bracket order
res = client.modify_bracket_order({
    "exchange": "NSE_EQ",
    "order_id": "NXHCO00006A4",
    ...
})

# Delete bracket order
res = client.delete_bracket_order({
    "exchange": "NSE_EQ",
    "order_id": "NXHCO00006A4"
})

Multileg Orders

# Place multileg order
res = client.place_multileg_order({...})

# Cancel multileg order
res = client.cancel_multileg_order({
    "order_flag": "<order_flag>",
    "gateway_order_no": "<gateway_order_no>",
    ...
})

Reports

Order Book

Shows every order you placed today, regardless of status. Supports pagination and filtering.

res = client.get_order_book({
    "offset": "1",
    "limit": "20",
    "orderStatus": None,
    "order_id": None
})

if res and "data" in res:
    for o in res["data"]:
        print(
            o["order_id"],
            o["symbol"],
            o["exchange"],
            o["transaction_type"],
            o["status"],
            o["order_type"],
            o["product_type"],
            o["total_quantity"],
            o["traded_quantity"],
            o["pending_quantity"],
            o["order_price"],
            o["trigger_price"],
            o["order_timestamp"],
            o["exchange_timestamp"],
            o["error_reason"],
        )
    print("Total orders:", res["metadata"]["total_records"])

Trade Book

Shows all executed trades for the day.

res = client.get_trade_book({
    "offset": "1",
    "limit": "20"
})

Order History

Shows the complete status timeline of a single order. Useful for debugging rejected or stuck orders.

res = client.get_order_history({"orderId": "NXHCO00002A4"})

if res and "data" in res:
    for h in res["data"]:
        print(
            h["order_id"],
            h["status"],
            h["order_timestamp"],
            h["exchange_timestamp"],
            h["traded_quantity"],
            h["pending_quantity"],
            h["order_price"],
        )

Portfolio

Positions

# type: "NET" or "DAY"
res = client.get_positions({"type": "NET"})

Position Conversion

Convert positions from intraday to delivery or vice versa.

res = client.position_conversion({...})

Holdings

res = client.get_holdings()

Order Lifecycle

When you place an order, it goes through several stages. Track these using get_order_history().

Status Description
OMS_XMITTED Order reached the OMS and is being processed. Not yet sent to exchange.
EXCHANGE_XMITTED OMS sent your order to the exchange. Waiting for confirmation.
PENDING Exchange confirmed. Sitting in order book waiting to be matched.
EXECUTED Fully matched and filled. Trade is complete.
CANCELLED Cancelled by you or automatically at end of day.
OMS_REJECT OMS rejected before reaching exchange. Check error_reason.
ORDER_ERROR Exchange rejected. Common reasons: insufficient margin, invalid symbol, market closed.
ADMIN_REJECT Broker admin rejected the order.

You can only modify or cancel orders in PENDING or OMS_XMITTED status. Executed or cancelled orders cannot be changed.


Order Book — Field Reference

Field Description
order_id Unique ID like NXHCO00003A4
exchange Segment like NSE_EQ
scrip_token Instrument token number
symbol Stock symbol like IDEA
series Series like EQ
transaction_type BUY or SELL
product_type INTRADAY, DELIVERY, etc.
order_type RL, RL-MKT, SL, SL-MKT
status EXECUTED, PENDING, etc.
total_quantity Total shares ordered
traded_quantity Shares filled so far
pending_quantity Shares still waiting
disclosed_quantity Shares visible in market
order_price Price as string like "9.56"
trigger_price SL trigger price as string like "0.00"
validity DAY, IOC, etc.
validity_days Number of days for GTD orders
order_timestamp When placed, e.g. "2026-04-17 12:46:34"
exchange_timestamp When exchange confirmed, e.g. "2026-04-17 12:46:33"
error_reason Blank if no error, filled if rejected
is_amo_order True if after market order
exchange_order_no Exchange's own order number
client_id Your UCC like NE1234
bracket_details Nested object with bracket/cover order details

WebSocket — Live Market Data

Broadcast Socket (Touchline & Market Depth)

import asyncio

async def main():
    # ... login first ...

    async def on_open_broadcast_socket(message):
        print("Broadcast socket opened:", message)
        await client.touchline_subscription([
            {"MktSegId": "1", "token": "26009"}
        ])

    async def on_touchline(message):
        print("Touchline:", message)

    async def on_bestfive(message):
        print("Best Five:", message)

    async def on_close_broadcast_socket(close_msg):
        print("Broadcast socket closed:", close_msg)

    async def on_error_broadcast_socket(error):
        print("Broadcast socket error:", error)

    client.on_open_broadcast_socket = on_open_broadcast_socket
    client.on_close_broadcast_socket = on_close_broadcast_socket
    client.on_error_broadcast_socket = on_error_broadcast_socket
    client.on_touchline = on_touchline
    client.on_bestfive = on_bestfive

    await client.connect_broadcast_socket()

asyncio.run(main())

Touchline Subscription / Unsubscription

# Subscribe
await client.touchline_subscription([
    {"MktSegId": "1", "token": "26009"}
])

# Unsubscribe
await client.touchline_unsubscription([
    {"MktSegId": "1", "token": "26009"}
])

Best Five (Market Depth) Subscription / Unsubscription

# Subscribe
await client.bestfive_subscription({"MktSegId": "1", "token": "22"})

# Unsubscribe
await client.bestfive_unsubscription({"MktSegId": "1", "token": "22"})

Message Socket (Order Updates)

async def on_ready_message_socket(response):
    print("Message socket ready:", response)

async def on_msg_message_socket(response):
    print("Order update:", response)

async def on_close_message_socket(close_msg):
    print("Message socket closed:", close_msg)

async def on_error_message_socket(error):
    print("Message socket error:", error)

client.on_ready_message_socket = on_ready_message_socket
client.on_msg_message_socket = on_msg_message_socket
client.on_close_message_socket = on_close_message_socket
client.on_error_message_socket = on_error_message_socket

await client.connect_message_socket()

Running Both Sockets Together

await asyncio.gather(
    client.connect_broadcast_socket(),
    client.connect_message_socket(),
)

Scrip Master (Token Repository)

Get scrip tokens from the scrip master files:

Exchange URL
NSE Equity https://odinscripmaster.s3.ap-south-1.amazonaws.com/scripfiles/NSE_EQ.json
NSE F&O https://odinscripmaster.s3.ap-south-1.amazonaws.com/scripfiles/NSE_FO.json
BSE Equity https://odinscripmaster.s3.ap-south-1.amazonaws.com/scripfiles/BSE_EQ.json
BSE F&O https://odinscripmaster.s3.ap-south-1.amazonaws.com/scripfiles/BSE_FO.json

v2 URLs (alternate version):

Replace the path with /scripfiles/v2/<EXCHANGE>.json, e.g.: https://odinscripmaster.s3.ap-south-1.amazonaws.com/scripfiles/v2/NSE_FO.json

Complete API Reference

Method Description
client.login({...}) Login and get access token
client.validateSession() Keep session alive
client.balance() Check available margins
client.logout() End session
client.place_order({...}) Place a regular order
client.modify_order({...}) Modify a pending order
client.cancel_order({...}) Cancel a pending order
client.place_cover_order({...}) Place a cover order
client.modify_cover_order({...}) Modify a cover order
client.cancel_cover_order({...}) Cancel a cover order
client.place_bracket_order({...}) Place a bracket order
client.modify_bracket_order({...}) Modify a bracket order
client.delete_bracket_order({...}) Delete a bracket order
client.place_multileg_order({...}) Place a multileg order
client.cancel_multileg_order({...}) Cancel a multileg order
client.get_order_book({...}) Fetch order book
client.get_trade_book({...}) Fetch trade book
client.get_order_history({...}) Fetch order status timeline
client.get_positions({...}) Fetch open positions
client.position_conversion({...}) Convert position type
client.get_holdings() Fetch demat holdings
client.connect_broadcast_socket() Connect to live data WebSocket
client.connect_message_socket() Connect to order updates WebSocket
client.touchline_subscription([...]) Subscribe to LTP data
client.touchline_unsubscription([...]) Unsubscribe from LTP data
client.bestfive_subscription({...}) Subscribe to market depth
client.bestfive_unsubscription({...}) Unsubscribe from market depth

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nebsl_b2c_api-1.0.2.tar.gz (23.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nebsl_b2c_api-1.0.2-py3-none-any.whl (24.8 kB view details)

Uploaded Python 3

File details

Details for the file nebsl_b2c_api-1.0.2.tar.gz.

File metadata

  • Download URL: nebsl_b2c_api-1.0.2.tar.gz
  • Upload date:
  • Size: 23.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.20

File hashes

Hashes for nebsl_b2c_api-1.0.2.tar.gz
Algorithm Hash digest
SHA256 d666288292caa5cb382e8850b1961dd7d968889df931f85870b17fd3b32caf89
MD5 012483ad2acb455fe048c3b1d088e78f
BLAKE2b-256 04f1bfa8adb5f0bbc6661fa70fb944f49162bd285e805ec4e329f46a395bc103

See more details on using hashes here.

File details

Details for the file nebsl_b2c_api-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: nebsl_b2c_api-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 24.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.20

File hashes

Hashes for nebsl_b2c_api-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 11e33583c6df87e5c065be2a87da2c65fe57bc782c5c02821edd8c0ab01d3d16
MD5 de27b5639437b228ff85996d4d8886f6
BLAKE2b-256 59fde45ea0ea62d4e57f978185c10b4dfbf8314a838ab26ac90802d4d36ae80f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page