Intermediate5-8 min readTopic 7 of 20

    Broker APIs in India — How Access Works

    Rohit Singh

    Mr. Chartist · SEBI RA

    Module Progress
    0/20
    Module

    A broker API is a permissioned doorway into the same account you already log into by hand. It does not give your program a faster exchange, a private order book or a special queue. It gives it the ability to read prices and send orders without a human touching a screen — under an authentication scheme that expires, a rate limit you can exhaust, and an order state machine that will hand you outcomes your code has to be written to expect. Most of what goes wrong in a live system goes wrong in that plumbing, not in the strategy.

    The three things you do by hand, the three calls that replace them, and the hops every one of them makes on the way to the NSE or BSE order book.On the left, three things a trader does by hand: watch the price, type a quantity and tap buy, open the positions tab. On the right, the same three as programmatic calls to a quote endpoint, an orders endpoint and a positions endpoint. Below, every call travels the same chain: your program, then the broker's API server, then the exchange order book, with prices, order updates and fills returning along the same path.WHAT YOU DO BY HANDWHAT YOUR CODE SENDS INSTEADWatch the price on screenGET /quoteType the quantity, tap BUYPOST /ordersOpen the positions tabGET /positionsEVERY CALL TAKES THE SAME THREE HOPSYour programyour laptop or VPSBroker API serverauth, risk checks, throttleExchangeNSE / BSE order bookPrices, order updates and fills come back down the same chainNothing new is unlocked. What changes is that no human presses the button.
    The three things you do by hand, the three calls that replace them, and the hops every one of them makes on the way to the NSE or BSE order book.

    What is a broker API, and what does it not give you?

    Several SEBI-registered brokers in India publish a programmatic interface to a retail trading account — Zerodha, Dhan, Fyers, Angel One and Upstox among them. They are named here only as examples of who offers one; this page does not compare, rank or recommend any broker, and choosing one is your decision to take on your own terms.

    What every one of them exposes is roughly the same set of capabilities: read a quote, read historical candles, subscribe to a live feed, place an order, modify or cancel an order, and read back positions, holdings, orders and funds. Names and shapes differ. The set does not.

    What none of them gives you is worth stating just as plainly. No API makes you faster than the co-located institutional flow. No API removes exchange risk checks, margin requirements or circuit limits. No API lets you place an order your account could not have placed manually. And no API turns an unprofitable idea into a profitable one — it only lets you be wrong faster and without supervision.

    Note — Automated order placement by a retail account sits inside SEBI's algorithmic trading framework, and the obligations there rest on you as much as on the broker. The framework topic in this module covers that separately. Nothing on this page is a statement about what you are permitted to run — check the current SEBI circulars and your broker's own terms.

    How does authentication and the session lifecycle actually work?

    This is the part beginners underestimate, and it is the single most common cause of a system that worked yesterday and is silent this morning.

    A broker cannot simply hand your program a permanent password-equivalent, because a leaked one would be a live trading account in a stranger's hands. So the flow is almost always two-tier: a long-lived credential that identifies your application, and a short-lived token that authorises today's session and dies on its own.

    1. 1

      Register the application

      You create an app on the broker's developer console and receive an identifier and a secret. The secret is the thing an attacker wants. It belongs in an environment variable or a secrets store, never in the source file and never in a repository.

    2. 2

      Log in through the broker's own page

      The user — you — authenticates on a page the broker controls, usually with a second factor. Your program never sees the account password. That is the entire point of the design.

    3. 3

      Exchange the redirect for a session token

      The broker sends back a short-lived request token. Your program exchanges it, signed with the app secret, for the access token that every subsequent call carries.

    4. 4

      Attach the token to every call

      Usually as an authorisation header. A call without it, or with an expired one, comes back as an authentication error — not as an empty result. Your code must distinguish those two.

    5. 5

      Expect the token to die, and plan for it

      Many Indian brokers expire the session daily, commonly around the start of the trading day, and require a fresh interactive login. Some issue longer-lived tokens for specific use cases. Treat expiry as a scheduled event you handle, not an incident you discover.

    Watch out — Daily expiry has a nasty property: it can land while you hold a position. The failure is not that you cannot enter — it is that you cannot exit. Any system that can open a position must be able to prove, before it opens one, that it still holds a valid session and can place the closing order.

    Which parts of a broker API change, and which stay stable?

    The practical consequence is architectural. Write your strategy against your own small interface — `get_quote`, `place_order`, `get_positions` — and let one adapter translate that into whatever a particular broker currently calls those things. Then a broker change, or a broker switch, is one file.

    Part of the interfaceHow stable is it?What that means for your code
    The capability set — quotes, orders, positions, fundsVery stable across brokers and yearsSafe to design your own interface around. This is what you abstract.
    Field names and payload shapesBroker-specific, and revised between versionsIsolate them in one adapter file so a rename touches one place, not fifty.
    Rate limits and throttling rulesChange without much noticeNever hard-code a number from a blog post. Read the broker's current docs.
    Instrument identifiers and the master contract listRefreshed daily; identifiers get reused over timeDownload the master list every morning. Never cache an identifier across expiries.
    Charges, plan limits and API pricingCommercial, and changed at the broker's discretionOut of scope for any article. Check the broker's current published terms.

    REST or WebSocket — when do you need each?

    There are two fundamentally different ways to get data out of a broker, and the choice is not a preference.

    A REST call is a question. Your program asks, the server answers, the connection ends. Everything that happened between two questions is invisible to you. A WebSocket is a subscription. You connect once, tell the broker which instruments you care about, and it pushes updates to you as they occur.

    The same stretch of price seen two ways. Polling on a timer sees only the ticks that happened to fall on a poll; a pushed stream sees each one, and spends no request asking whether anything changed.The same twenty-four price ticks are drawn twice. In the upper lane the program polls on a timer and sees only six of them, so the price it works with is a coarse zigzag and every move between two polls is invisible. In the lower lane the broker pushes each tick as it happens, so all twenty-four arrive as messages and no request was spent asking whether anything had changed.REST — YOU ASK, ON A TIMER6 requests, 6 prices. The 18 moves in between never happened, as far as your code knows.WEBSOCKET — THE BROKER PUSHES24 ticks arrive as 24 messages, and not one request was spent asking.Illustrative. Below roughly a 5-minute decision, the difference stops being cosmetic.
    The same stretch of price seen two ways. Polling on a timer sees only the ticks that happened to fall on a poll; a pushed stream sees each one, and spends no request asking whether anything changed.

    What does each transport suit?

    Most retail systems need both. A REST call fetches the state of the world at start-up and after any reconnect; the socket keeps that state current while everything is healthy. The mistake is using only one: a poll-only system is blind between polls, and a socket-only system has no way to recover what it missed.

    REST (you ask)WebSocket (the broker pushes)
    ShapeRequest, response, doneOne long-lived connection carrying many messages
    Good forHistorical candles, funds, positions, holdings, order placement and modificationLive quotes, depth, and order-update streams
    Cost of frequencyEvery poll spends part of your rate budgetSubscribing costs one connection, not one call per update
    What it missesEverything between two pollsEverything sent while you were disconnected
    Fails byTiming out, or being throttledGoing quiet without an error — the connection is open, nothing is arriving
    Reasonable useDecisions taken on candle closes, at low frequencyAnything reacting inside a candle, and every live order-status feed

    What happens after you send an order?

    An order is not an event. It is a state machine, and your code has to model every state it can land in — including the ones that are neither a clean fill nor a clean rejection.

    The request returning HTTP 200 means the broker accepted the message. It does not mean anything traded. Treating the acknowledgement as a fill is the single most expensive beginner error in live systems, because a position tracker built on acknowledgements drifts away from the real one within minutes.

    Placed, open, partially filled, filled — plus the two branches that end an order early. A cancelled order that was partly done still left you holding that quantity.An order moves from placed, to open in the exchange order book, to partially filled, to filled. Two branches end it before that: rejected, which happens straight after placement and leaves nothing traded, and cancelled, which can happen from open or from partially filled and leaves any quantity already filled with you. The position tracker must therefore add up fills rather than orders.THE HAPPY PATH — NOTHING HAS TRADED UNTIL THE THIRD BOXPLACEDsent and acceptedOPENlive in the bookPART FILLEDsome quantity doneFILLEDall quantity doneREJECTEDnothing tradedCANCELLEDpart-filled quantity staysYour position is the running sum of fills. It is never the sum of orders you sent.A cancelled order that was 36 per cent done still left you 36 per cent long.
    Placed, open, partially filled, filled — plus the two branches that end an order early. A cancelled order that was partly done still left you holding that quantity.

    Why does a partial fill break naive position tracking?

    Suppose your rule wants 400 shares and you send one market-adjacent limit order for the full quantity. The book takes 150 at your price, then price moves away and the rest sits unfilled. You cancel.

    A system that recorded 'ordered 400, cancelled, therefore flat' is now 150 shares long and does not know it. Its next signal will size from a position of zero. Its stop logic will protect nothing. Its end-of-day reconciliation will disagree with the broker's contract note, and the disagreement will be discovered after the damage.

    Net position = Σ (filled quantity × side) — never Σ (orders sent)
    • Filled quantity — the quantity the exchange actually traded, read from the order or trade feed, not from the placement response.
    • Side — +1 for a buy, −1 for a sell.
    • Orders sent — deliberately absent from the right-hand side. An order is an intention; a fill is a fact.

    Example — Illustrative arithmetic with round numbers, not a real order in a real stock on a real session. The point is the accounting rule, not the quantities.

    What does one complete round trip look like?

    Put the pieces in order. This is the loop a live system runs, and every step in it is a place where the previous section's failure modes appear.

    1. 1

      Establish the session

      Log in, exchange the request token, hold the access token in memory. Never write it to a file that gets committed. Confirm it works with a cheap read call before doing anything else.

    2. 2

      Load the master contract list

      Download today's instrument list and map your symbols to the identifiers the broker expects. Doing this once per day, at start-up, removes an entire class of rejection.

    3. 3

      Reconcile before you decide

      Fetch positions, open orders and available funds over REST. Your in-memory state must start as a copy of the broker's, never as an assumption of flat.

    4. 4

      Subscribe, then wait for the first tick

      Open the socket, subscribe to your instruments, and do not evaluate a single rule until data has actually arrived. A subscription that silently failed looks identical to a quiet market.

    5. 5

      Evaluate on a defined boundary

      Decide on candle closes or on an explicit clock, not on every tick, unless the strategy genuinely requires it. Fewer decision points means fewer calls, fewer duplicates and a system you can reconstruct from logs.

    6. 6

      Place with an identifier, then confirm by reading

      Send the order with your own tag attached, then learn its fate from the order-update stream — falling back to a status read. The placement response is the beginning of the story, not the end of it.

    7. 7

      Update position only from fills

      Every fill message adjusts the position. Nothing else does. At the close, reconcile once more against the broker and log any disagreement as an incident to investigate before the next session.

    What is different about pulling historical data?

    Historical candles come over REST, and they carry their own traps that live quotes do not.

    Brokers cap how much history one request may return, so a long series arrives as pages you stitch together — and stitching is where duplicated or missing candles creep in. The available depth is limited too, and it is usually shorter for finer intervals than for daily bars. Most importantly, the series you receive may or may not be adjusted for splits, bonuses and other corporate actions, and an unadjusted series contains price jumps that were never trades. Market Data, Corporate Actions and Bias covers that specifically.

    Pro tip — Fetch history once, store it locally, and update incrementally. Re-downloading the same five years on every run wastes your rate budget, makes start-up slow, and means a broker outage takes your research offline as well as your trading.

    How do rate limits and throttling actually bite?

    Every broker caps how often you may call, typically as a per-second ceiling with separate, tighter ceilings for order-related endpoints than for read endpoints. Exceed it and you get a throttling error rather than data.

    The numbers are broker-specific and revised — do not take any figure you read in an article, including this one, as current. Read your broker's own documentation and design to whatever it says today. What generalises is the behaviour, not the number.

    • Throttling arrives at the worst moment. Volatility is exactly when your loop tries to do the most and when the broker is serving the most callers.
    • A throttled order request is not a placed order. But a throttled response to a status check tells you nothing about an order that may already be live.
    • Retrying immediately makes it worse. Back off — wait, then wait longer — and cap the number of attempts.
    • Never retry an order placement blindly. A timed-out request may have succeeded at the exchange. Query the order book by your own client-side order identifier first, then decide.
    • Poll status on a schedule, not in a tight loop. Subscribe to the order-update stream and use REST only to reconcile.
    • Batch what can be batched. One quote call for forty instruments is one call; forty calls for one instrument each is forty.

    Watch out — Idempotency is the defence. Generate your own unique identifier per intended order and attach it if the broker supports it. Without one, you cannot distinguish 'my request never arrived' from 'my request arrived and the response was lost' — and those two require opposite responses.

    What is sandbox mode good for, and what does it hide?

    Most brokers offer a paper or sandbox environment. It is genuinely useful for one thing and misleading about several.

    Use it to prove your plumbing: that authentication works, that your payloads are shaped correctly, that your order state machine handles a rejection, that your reconnect logic runs. That is real value, and it costs nothing.

    The honest ladder is therefore sandbox for correctness, then the smallest live size you can trade for realism, then size. Skipping the middle rung is how systems that passed every test lose money for reasons nobody wrote a test for. That move from a validated model to live orders is covered in From Backtest to Live Trading.

    What sandbox tests honestlyWhat it cannot tell you
    Whether your request payload is validWhether you would have been filled at that price
    Whether your token and session handling workHow much slippage a real book would impose
    Whether you handle a rejection without crashingHow the order queue behaves at an opening or a circuit
    Whether your reconnect and reconciliation runWhether a real feed would have stalled at that moment
    Whether your logging captures enough to debugHow you behave when real money is moving against you

    What actually goes wrong in production?

    These are the failure modes that show up in real systems, in rough order of how often they cause damage. Every one of them is a plumbing failure, not a strategy failure.

    The token expired mid-session
    Reads keep working from cache, or fail quietly, and the first thing you notice is that an exit never went out. Detect authentication errors as a distinct class, refresh, and if refresh is impossible, alert loudly and stop opening anything new.
    The socket is connected but silent
    TCP holds the connection open while nothing arrives. Your last-known price freezes and your logic acts on a stale number. The fix is a heartbeat: if no message has arrived for longer than the market's quietest realistic gap, treat the feed as dead and reconnect.
    The reconnect gap
    A pushed stream sends what happens while you are attached. Everything during a 40-second reconnect is simply gone. After every reconnect, re-fetch positions, orders and funds over REST before acting on a single tick.
    Partial fills accumulating into a phantom position
    Covered above. Reconcile against the broker's own position and order book at start-up, after every reconnect, and at least once near the close.
    Duplicate orders from a retry
    A request times out, your code resends, both arrive. You are now twice the intended size with half the intended risk budget. Idempotency keys and a mandatory status check before any resend.
    A stale instrument identifier
    Contract identifiers change and are reused, most visibly around derivative expiries. An order routed on yesterday's identifier can be rejected, or worse, accepted for an instrument you did not mean. Refresh the master list daily.
    The clock drifted
    Candle boundaries, session windows and square-off timers all depend on your machine's time being right. Run NTP. A few seconds of drift near a session boundary produces decisions nobody can reconstruct afterwards.

    What does a defensible integration look like?

    Before any of this touches real money

    • Secrets live in environment variables or a secrets manager — never in code, never committed, and rotated if they were ever pasted anywhere.
    • The session is validated at start-up and the system refuses to open a position it could not currently close.
    • One adapter file holds every broker-specific field name; the strategy never sees them.
    • Position and order state are reconciled against the broker at start-up, after every reconnect and before the close.
    • Every order carries a client-side identifier, and no placement is ever retried without a status check first.
    • The feed has a heartbeat, and a stale feed halts new decisions rather than trading a frozen price.
    • Rate-limit errors trigger exponential back-off with a cap, not an immediate retry.
    • Every request, response and state transition is logged with a timestamp — you cannot debug a live session you did not record.
    • A kill switch exists that flattens or halts, and you have tested it during market hours, not just read the code.

    Note — This page is education, not advice, and it is not a recommendation of any broker or any automated system. Automating order placement adds engineering risk on top of market risk, and the losses from a plumbing bug are as real as the losses from a bad idea.

    Key points

    A broker API automates the account you already have. It gives no speed, no priority and no permission you did not already hold.
    Authentication is two-tier: a long-lived app secret plus a short-lived session token that commonly expires daily.
    Never let the system open a position it could not currently close — validate the session before entry, not after.
    REST is a question and is blind between questions; a WebSocket is a subscription and is blind while disconnected. Real systems use both.
    An accepted order request is not a fill. Model the full state machine, including partial fills and cancellations.
    Position is the running sum of fills, never the sum of orders sent.
    Rate limits are broker-specific and revised — read the current docs, back off exponentially, and batch what you can.
    Never retry an order placement blindly. Query by your own client-side identifier first.
    A silent socket is worse than a broken one, because a frozen price still looks like a price. Use a heartbeat.
    After every reconnect, re-fetch positions and orders over REST before acting on a single tick.
    Sandbox proves correctness. Only live size — starting at the smallest you can trade — proves realism.

    Pro tip — Before your system is allowed to place its first order of the day, make it run one self-check: is the session valid, does the broker's reported position match mine, is the master contract list from today, and has a tick arrived in the last few seconds? If any answer is no, it logs and stands down. Almost every expensive live-trading story starts with a system that skipped this and traded on a stale assumption.

    Frequently asked questions

    Which brokers in India offer a trading API?

    Several SEBI-registered brokers publish one, including Zerodha, Dhan, Fyers, Angel One and Upstox. We do not rank or recommend brokers, and access terms, charges and technical limits differ and change — check each broker's own current documentation and terms before building anything against it.

    Do I need a paid subscription to use a broker API in India?

    Commercial terms vary by broker and change at their discretion, so any figure quoted in an article is likely to be stale. Look at the broker's current published terms directly. Note that data access and order-placement access are sometimes billed separately.

    What is the difference between REST and WebSocket for market data?

    REST is request-and-response: your program asks and gets one answer, and everything between two requests is invisible to it. A WebSocket is a persistent subscription the broker pushes updates down as they happen. Use REST for historical candles, account state and order placement; use a WebSocket for live prices and order updates. Most systems need both, because REST is also how you recover state after a socket drops.

    Why does my broker API token expire every day?

    Because a permanent token would be a permanent key to a live trading account. Most Indian brokers require a fresh interactive login, typically at the start of the trading day, which means your system must handle expiry as a planned event. The dangerous case is expiry while a position is open — the risk is not that you cannot enter, it is that you cannot exit.

    Does an order API response mean my order was executed?

    No. A successful response means the broker accepted the message. The order can still be rejected by risk checks or the exchange, sit unfilled, fill partially, or be cancelled with part of the quantity already traded. Your position must be computed as the running sum of fills read from the order or trade feed, never from placement responses.

    What happens if I hit the broker's API rate limit?

    You get a throttling error instead of data, and it usually arrives during volatility — exactly when your system is trying hardest and the broker is busiest. Back off exponentially rather than retrying immediately, batch quote requests, and prefer a pushed order-update stream over polling status. The specific limits are broker-specific and revised, so read the current documentation rather than a number from an article.

    Is paper trading through a broker sandbox enough before going live?

    It is enough to prove your plumbing — authentication, payload shapes, rejection handling, reconnect logic. It cannot tell you whether you would have been filled, what slippage a real order book would have imposed, or how the queue behaves at an opening or a circuit. Sandbox for correctness, then the smallest live size for realism, then size.