Angel One SmartAPI Algo Trading: Python Setup for 2026
Get an Angel One SmartAPI key, register your static IP, log in with TOTP and place an order in Python. Plus the real rate limits and error codes.
Angel One’s SmartAPI is free, historical data included, and placing NSE orders with it from Python takes four pieces: TOTP switched on for your account, an app on the SmartAPI dashboard with a registered static IP, a daily login with your client code, PIN and a TOTP code, and the right instrument token from Angel One’s scrip master file. Below is each piece with the field names as they appear today, code checked against the current SDK, and the error codes you’re likely to hit.
Last updated: November 2026.
Turn on TOTP first
SmartAPI’s login doesn’t take an SMS OTP. It wants a time-based code, so set that up before anything else. Go to smartapi.angelone.in/enable-totp, enter your client ID and PIN, then the OTP Angel One sends to your registered email and mobile. You’ll see a QR code and, under it, a line that says “Can’t Scan? Copy the key”.
Copy that key. You can scan the QR into Google Authenticator as well, but the key is what your script needs: the pyotp library turns it into the same six-digit code your phone shows.
Treat the key like your PIN. With your client code, your PIN and that key, anyone can log in to SmartAPI as you without touching your phone. Keep it in an environment variable or a secrets manager, never in a file you push to GitHub. And keep the server’s clock synced, because a TOTP code generated on a machine whose clock has drifted gets rejected even though it looks right.
How do you get an Angel One API key?
Log in to the SmartAPI dashboard at smartapi.angelone.in with your Angel One client ID and PIN (and the one-time code, if it asks for one). The page you want is called “My Smart API & Apps”. Click + ADD APP and you get five fields:
- App Name. Anything, 20 characters at most.
- Redirect URL. Required. The current form rejects localhost, 127.0.0.1 and private network addresses, even though SmartAPI’s own FAQ still tells you to use http://127.0.0.1. It’s only used in the browser-based publisher login, so if you log in from a script, any https address you own will do.
- Post back URL. Optional. Angel One pushes order status updates to it, and only over HTTPS on port 443. Leave it empty unless you run a web server for it.
- Primary Static IP. Required. The public IPv4 address your orders will leave from.
- Secondary Static IP. Optional, for a backup machine.
The API key appears on that page once you’ve added an app. The dashboard allows five apps.
The static IP rule, Angel One’s version
Since 1 April 2026, Angel One executes API orders only if they come from your registered static IP (Angel One’s notice). The docs are specific about what gets checked: the source IP of place, modify and cancel order requests, plus GTT create, modify and cancel. Login, quotes, historical candles and the WebSocket feed work from any IP. So you can research on your laptop and keep only the order-sending machine on the fixed address.
The details that catch people:
- You can change the IP once per calendar week, no more. Don’t register a “temporary” address.
- One static IP maps to one client. Family members (as SEBI defines family) can share one after a written request and 2FA validation.
- Angel One’s SmartAPI team said on its forum that only IPv4 is supported for now.
- The notice suggests getting the IP from your ISP or “a secure VPN service”. Be careful with the second option: ordinary VPNs share exit IPs between customers. Our static IP guide compares ISPs and cloud servers, with prices.
One oddity in the SDK. smartapi-python sends an X-ClientPublicIP header with every request, and in version 1.5.5 that header is filled with a hardcoded placeholder address, not yours. Ignore it. Per the docs, what’s validated is the source IP of the request. If orders still get rejected after you’ve registered the IP, check first that your script uses the API key of the app that has the IP on it.
Logging in: client code, PIN and TOTP
The login endpoint is called loginByPassword, but the password field takes your PIN. A successful login gives you three tokens:
- jwtToken goes in the Authorization header of every call. The SDK handles this for you.
- refreshToken lets you mint a fresh jwtToken during the same day with
generateToken(). - feedToken is only for the WebSocket market data feed.
All three are valid until 12 midnight, per the SmartAPI FAQ, and Angel One logs every API user out at midnight. Plan on one login each morning before the open, which matches the once-a-day 2FA login brokers now enforce under the SEBI algo rules. Don’t put the login inside a retry loop: the endpoint allows one request per second, and there’s no reason to call it more than once a day unless a token error tells you to.
How to find symbol tokens in the scrip master
Every order needs a symboltoken alongside the tradingsymbol, and both come from the scrip master:
https://margincalculator.angelbroking.com/OpenAPI_File/files/OpenAPIScripMaster.json
When I pulled it in November 2026 it was a 36 MB JSON file with about 1.53 lakh rows covering every exchange and segment Angel One supports. A few things you only learn by opening it:
- Strikes are multiplied by 100. The NIFTY 20,850 strike is stored as
"2085000.000000". Tick size works the same way:"5.000000"means ₹0.05. Divide by 100 before you compare anything to a price, or your strike filter quietly returns nothing. - Numbers are stored as strings, lot size included.
- Symbol formats differ by instrument.
SBIN-EQfor cash,NIFTY01DEC2620850CEfor an index option (name, expiry date, strike, CE/PE),NIFTY29DEC26FUTfor a future. Cash rows useexch_seg“NSE”; F&O rows use “NFO”. - Expired contracts disappear. The file is rebuilt daily and only lists live instruments. Keep each day’s copy if you’ll ever need an expired contract’s token; Angel One doesn’t document whether candles stay available for expired tokens.
Download it once each morning and look tokens up locally:
import requests
URL = "https://margincalculator.angelbroking.com/OpenAPI_File/files/OpenAPIScripMaster.json"
rows = requests.get(URL, timeout=60).json()
def lookup(exch_seg, symbol):
return next(r for r in rows if r["exch_seg"] == exch_seg and r["symbol"] == symbol)
sbin = lookup("NSE", "SBIN-EQ")
print(sbin["token"]) # 3045
For an occasional lookup there’s also a searchScrip call, but it’s limited to one request a second, so don’t use it inside a strategy loop.
How to place an order with SmartAPI in Python
The official package is smartapi-python, and the import name is SmartApi. The latest release on PyPI is 1.5.5, from February 2025. Installing it alone isn’t enough: it declares only three dependencies but imports logzero and websocket the moment you load it. In a clean environment, from SmartApi import SmartConnect fails with No module named 'logzero'. Install everything in one go:
pip install smartapi-python pyotp logzero websocket-client
Then, with your secrets in environment variables:
import os
import pyotp
from SmartApi import SmartConnect
api = SmartConnect(api_key=os.environ["ANGEL_API_KEY"])
totp = pyotp.TOTP(os.environ["ANGEL_TOTP_KEY"]).now()
session = api.generateSession(os.environ["ANGEL_CLIENT_CODE"], os.environ["ANGEL_PIN"], totp)
if not session.get("status"):
raise SystemExit(f"Login failed: {session.get('errorcode')} {session.get('message')}")
order = {
"variety": "NORMAL",
"tradingsymbol": "SBIN-EQ",
"symboltoken": "3045",
"transactiontype": "BUY",
"exchange": "NSE",
"ordertype": "LIMIT",
"producttype": "INTRADAY",
"duration": "DAY",
"price": "500",
"quantity": "1",
}
resp = api.placeOrderFullResponse(order)
print(resp)
A few notes on why it looks like this.
It’s a limit order on purpose. Angel One’s April 2026 notice says market orders and IOC orders are “strictly prohibited for algorithmic trading”. For a first test, set the price well away from the market so the order sits in the book, confirm it in the Angel One app, then cancel it with api.cancelOrder(order_id, "NORMAL").
I call placeOrderFullResponse rather than placeOrder. When an order fails, placeOrder logs the error and returns None instead of raising, which is easy to miss. The full-response version hands back status, message and errorcode.
Quantity is in units, not lots. NIFTY’s lot size is 65 (as of 2026; NSE revises lot sizes periodically), so one lot of a NIFTY option is "65". Product types are INTRADAY (MIS), DELIVERY (CNC) and CARRYFORWARD (NRML for F&O).
And one harmless surprise: the SDK creates a logs/<date>/app.log folder in whatever directory you run it from.
The rate limit to design around is 9
These are from the SmartAPI rate limit page as of November 2026:
| Endpoint | Per second | Per minute | Per hour |
|---|---|---|---|
Login (loginByPassword) | 1 | – | – |
Refresh (generateTokens) | 1 | – | 1,000 |
| Place, modify, cancel order | 9 combined | 500 each | 1,000 each |
| Order book, positions, trade book | 1 | – | – |
| Market quote | 10 | 500 | 5,000 |
Historical candles (getCandleData) | 2 | 80 | 5,000 |
searchScrip | 1 | – | – |
Go over and the request fails with a 403 “Access denied because of exceeding access rate”. Limits are counted per client code, so two scripts on one account share the budget. Older forum posts and tutorials quote 20 orders a second for placeOrder; that number is out of date.
The 9 sits just under the 10-orders-per-second line above which SEBI’s framework requires a strategy to be registered with the exchange. Whatever the reason, it means a self-coded strategy on SmartAPI stays under the threshold by construction.
The hourly cap is where trailing-stop code runs into trouble. Say you trail stops on 5 open positions and modify each one every 10 seconds. That’s 5 × 6 = 30 modifications a minute, or 1,800 an hour, against a cap of 1,000. Your modifications would start failing after about 33 minutes. Trail on candle closes instead.
Does SmartAPI cost anything?
No. The SmartAPI FAQ says the service is “entirely free of cost, even for historical data”. You pay normal brokerage and statutory charges on each trade, same as manual orders; our Angel One brokerage calculator shows the full stack per trade. Compare that with Zerodha, where live data and historical candles through Kite Connect cost ₹500 a month.
SmartAPI error codes and what they mean
From the SmartAPI error table and FAQ:
- AG8001, AG8002, AG8003 (invalid, expired or missing token). Your session ended at midnight, or the token belongs to a different login. Log in again rather than retrying the call.
- AB8050, AB8051 (invalid or expired refresh token). Same fix: a fresh login.
- AB1000 (“Invalid Email Or Password”). The credentials in the login call are wrong; check the client code and PIN.
- AB1010, AB1011 (“AMX Session Expired”, “Client not login”). The broker-side session is gone. Log in again.
- AB1009, AB1018 (“Symbol Not Found”, “Failed to get symbol details”). The trading symbol and token don’t match, or you used yesterday’s token for a contract that has since expired.
- AB1012 (“Invalid Product Type”). Check the product fits the segment:
DELIVERYis for cash,CARRYFORWARDfor F&O. - AB4008. Your
ordertagis 20 characters or longer. - AB1006 (“Client Is Block For Trading”). Not an API problem. Angel One’s FAQ says to call customer care on 022-33551111.
- “Quantity is not a multiple of Lot Size.” You sent lots instead of units.
- “INTRADAY PRODUCT BLOCKED FOR NON-INTRADAY USER.” Your account isn’t enabled for intraday; that’s an account setting, not code.
- 403 “Access denied because of exceeding access rate.” See the table above.
Skipping the code entirely
If what you want is a strategy running on your Angel One account, not a Python project, a no-code platform does the login, tokens, scrip master and order handling for you. We build INDfolio, so weigh this accordingly: Angel One is one of the seven brokers INDfolio deploys to. You describe the strategy in plain English or build it from blocks, backtest it on NSE history with Indian costs, paper trade it on live prices, then go live with kill switches and position limits.
On the static IP, Angel One’s own notice says clients using no-code platforms hosted on broker servers don’t need to register one, and that for empanelled vendors the IP can be the vendor’s or the client’s. How that works depends on each platform’s integration, so ask any platform, including us, whose IP your orders leave from before you connect. If you’d rather write code against a different broker, our Upstox API guide covers the same ground there.
Frequently asked questions
Is Angel One SmartAPI free? Yes. Angel One’s SmartAPI FAQ says the API is free of cost, including historical data. You still pay brokerage, STT, exchange charges, GST and stamp duty on each trade.
What is the Angel One scrip master URL? It’s https://margincalculator.angelbroking.com/OpenAPI_File/files/OpenAPIScripMaster.json. The file is rebuilt daily and only lists live contracts, so download it each morning and keep old copies if you need expired tokens.
How long is a SmartAPI login valid? Until 12 midnight. The jwtToken, refreshToken and feedToken all stop working then, so log in once each trading morning.
Do I need a static IP for SmartAPI historical data or the WebSocket? No. Angel One checks the static IP only on place, modify and cancel order requests and on GTT rules. Data, quotes, positions and the login itself work from any IP.
Can I place market orders through SmartAPI? Not for algo orders. Angel One’s April 2026 notice says market and IOC orders are prohibited for algorithmic trading, so use limit orders.
Where do I find the TOTP key for SmartAPI?
On smartapi.angelone.in/enable-totp. After you verify the OTP, the page shows a QR code and a “Copy the key” option; that key is what pyotp needs to generate login codes.
Put this into practice
Build and backtest your own strategy free — no coding, no card.
Related guides
Upstox API Algo Trading: Python Setup Guide for 2026
Upstox's API is free to use. How to create the app, get the daily access token, register a static IP and place v3 orders from Python.
11 min
Fyers API for Algo Trading: Complete Setup Guide
How to set up the Fyers API for algo trading — creating an app at myapi.fyers.in, the daily auth flow, connecting a no-code platform and common errors.
8 min
Static IP for Algo Trading in India: Setup by Broker
Since April 2026, API orders must come from a registered static IP. Where to get one (ISP, cloud server, platform) and where each broker wants it entered.
10 min