jData=<JSON payload>&jKey=<AccessToken> — requires a valid AccessToken from Login.
Overview
Place Order is the core trading endpoint: every supported order type (LMT, SL-LMT) and every product (intraday, delivery, margin) routes through this one call, differentiated by parameters. Call it from your strategy engine whenever a signal needs to hit the exchange, and pair it with Order Book and the Order Update Feed to track state.
Not supportedMKT orders are rejected — only LMT and SL-LMT are accepted. Cover Order (CO) and Bracket Order (BO) are also not available as prd values.
Rate Limits
10 orders/second (OPS) per client, enforced at the OMS layer per SEBI's algo-trading OPS threshold framework.
Need more than 10 OPS?Submit your strategy to the exchange for approval and obtain an Algo ID. Once empanelled, higher OPS thresholds apply under the exchange's Algo ID framework.
Unique id of contract on which order to be placed. (Use the results from Search Script to get the trading symbol & use URL encoding to avoid special-char errors for symbols like M&M.)
Trigger price. Mandatory when prctyp is set to SL-LMT.
> 0; omit when prctyp = LMT
dscqty
integer
Optional
Disclosed quantity visible to the market.
0 to qty
remarks
string
Optional
User-defined remarks for order tracking and identification.
Free text
ordersource
string
Required
Order source identifier.
API
algo_id
string
Conditional
Exchange-approved Algo ID. Mandatory for orders placed under a registered algo strategy per SEBI's algo trading framework; omit for manual/non-algo orders.
Exchange-issued
Request Examples
import requests
import json
payload = {
"uid": "AB1234",
"actid": "AB1234",
"exch": "NSE",
"tsym": "RELIANCE-EQ",
"qty": "1",
"dscqty": "0",
"prc": "180.0",
"prd": "C", # C, M, I only — CO/BO not accepted"trantype": "B",
"prctyp": "LMT", # LMT or SL-LMT only — MKT is rejected"ret": "DAY",
"ordersource": "API",
}
data = f"jData={json.dumps(payload)}&jKey={accessToken}"
response = requests.post(
"https://api.shoonya.com/NorenWClientAPI/PlaceOrder",
data=data,
)
result = response.json()
if result.get("stat") == "Ok":
print("Order placed:", result["norenordno"])
else:
print("Order rejected:", result.get("emsg"))
const payload = {
uid: "AB1234",
actid: "AB1234",
exch: "NSE",
tsym: "RELIANCE-EQ",
qty: "1",
dscqty: "0",
prc: "180.0",
prd: "C", // C, M, I only — CO/BO not accepted
trantype: "B",
prctyp: "LMT", // LMT or SL-LMT only — MKT is rejected
ret: "DAY",
ordersource: "API",
};
const data = `jData=${JSON.stringify(payload)}&jKey=${accessToken}`;
try {
const res = awaitfetch("https://api.shoonya.com/NorenWClientAPI/PlaceOrder", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: data,
});
const result = await res.json();
if (result.stat === "Ok") {
console.log("Order placed:", result.norenordno);
} else {
console.error("Order rejected:", result.emsg);
}
} catch (err) {
console.error("Network/timeout error placing order:", err);
}
curl-X POST https://api.shoonya.com/NorenWClientAPI/PlaceOrder \
-H"Content-Type: application/x-www-form-urlencoded" \
--data-urlencode'jData={"uid":"AB1234","actid":"AB1234","exch":"NSE","tsym":"RELIANCE-EQ","qty":"1","dscqty":"0","prc":"180.0","prd":"C","trantype":"B","prctyp":"LMT","ret":"DAY","ordersource":"API"}' \
--data-urlencode"jKey=$ACCESS_TOKEN"
HTTP status alone isn't enoughThe OMS returns HTTP 200 for both accepted and rejected orders — rejection is signalled in the JSON body via stat, not the HTTP status code. Always parse stat; never treat a 200 as confirmation of order placement. Track via Order Book and the Order Update Feed.
Field
Description
stat
Ok or Not_Ok — always check before trusting norenordno.
Reached exchange but rejected there (no liquidity for IOC, halted, etc).
Inspect the exchange-side reason in emsg.
Order Lifecycle
Strategy → Place Order API → Shoonya OMS → RMS Check → Exchange → Order Update WebSocket → Filled / Rejected / Cancelled
State
Meaning
Pending Validation → Open
Order validated, passed RMS, resting at the exchange.
Trigger Pending
SL-LMT waiting for trgprc to be touched.
Partially Filled → Complete
Quantity matching in progress, then fully filled.
Rejected
Failed validation, RMS, or exchange check — see emsg.
Cancelled
Cancelled by client, session logout, or EOD (for DAY orders).
Best Practices
Always check stat before trusting norenordno — the OMS returns HTTP 200 for both accepted and rejected orders, so a successful HTTP call is not confirmation of a placed order.
Since MKT isn't supported, price LMT orders with a small buffer beyond the current LTP for reliable fills on liquid symbols.
On a network timeout, don't assume the order failed. Shoonya has no dedicated idempotency/client-order-ID field, so tag every order with a unique remarks value at send time, then reconcile against Order Book by matching tsym + qty + remarks before deciding whether to resend.
Enforce your own client-side risk checks (max qty, max notional per order) — don't rely on RMS as your only guardrail, since RMS rejections happen after the order has already left your system.
Respect the 10 OPS rate limit with a client-side token-bucket limiter; if a strategy needs sustained throughput above that, get it registered for an Algo ID rather than working around the limit.
Validate tsym against a freshly-fetched Symbol Master immediately before placing F&O orders — don't cache symbols across expiries.
API Endpoint
POSThttps://api.shoonya.com/NorenWClientAPI/PlaceOrderapplication/x-www-form-urlencodedjData=<JSON payload>&jKey=<AccessToken>— requires a validAccessTokenfrom Login.Overview
Place Order is the core trading endpoint: every supported order type (
LMT,SL-LMT) and every product (intraday, delivery, margin) routes through this one call, differentiated by parameters. Call it from your strategy engine whenever a signal needs to hit the exchange, and pair it with Order Book and the Order Update Feed to track state.MKTorders are rejected — onlyLMTandSL-LMTare accepted. Cover Order (CO) and Bracket Order (BO) are also not available asprdvalues.Rate Limits
10 orders/second (OPS) per client, enforced at the OMS layer per SEBI's algo-trading OPS threshold framework.
Parameters
NSE,BSE,NFO,BFO,CDS,MCXM&M.)LMTandSL-LMTorders.COandBOare not supported.C(CNC),M(NRML),I(MIS)MKTorders are not supported.LMT,SL-LMTB(Buy),S(Sell)DAY,IOCprctypis set toSL-LMT.prctyp = LMTqtyAPIRequest Examples
Response
HTTP 200for both accepted and rejected orders — rejection is signalled in the JSON body viastat, not the HTTP status code. Always parsestat; never treat a 200 as confirmation of order placement. Track via Order Book and the Order Update Feed.OkorNot_Ok— always check before trustingnorenordno.Common Error Responses
tsymnot found in Instrument Master, or malformed expiry/option suffix.qtyis zero, negative, or not a lot-size multiple.prcoutside the exchange circuit band.qtyexceeds the per-order freeze limit.jKey/AccessTokeninvalid or expired.emsg.Order Lifecycle
SL-LMTwaiting fortrgprcto be touched.emsg.Best Practices
statbefore trustingnorenordno— the OMS returnsHTTP 200for both accepted and rejected orders, so a successful HTTP call is not confirmation of a placed order.MKTisn't supported, priceLMTorders with a small buffer beyond the current LTP for reliable fills on liquid symbols.remarksvalue at send time, then reconcile against Order Book by matchingtsym+qty+remarksbefore deciding whether to resend.tsymagainst a freshly-fetched Symbol Master immediately before placing F&O orders — don't cache symbols across expiries.