Glossary & Constants¶
Order ID Prefixes¶
| Prefix | Meaning | Used For |
|---|---|---|
EQ- | Equity order | Standard and smart-order parent orders in the EQUITY segment. |
DRV- | Derivative order | Standard and smart-order parent orders in the DERIVATIVE segment. |
COM- | Commodity order | Standard and smart-order parent orders in the COMMODITY segment. |
GTT- | Good Till Triggered | Smart order child legs (always), TRIGGER smart order parents, and EQUITY/DERIVATIVE smart order parents when the limit price falls outside the circuit range. |
See Smart Orders (GTT) for the parent/child relationship these prefixes describe.
Core Request Enums¶
| Field | Values | Used In |
|---|---|---|
txn_type | BUY, SELL | Orders, Smart Orders, Margin |
exchange | NSE, BSE, MCX | Orders, Smart Orders, Margin |
segment | EQUITY, DERIVATIVE, COMMODITY | Orders, Smart Orders, Margin, Order/Trade lookups, Portfolio Positions |
segment | INDEX, EQUITY (uppercase) | Option Chain query parameter only |
product | CNC, INTRADAY, MARGIN | Orders, Smart Orders, Margin, Portfolio Positions |
order_type | LIMIT, MARKET (Orders); LIMIT, MARKET, TRIGGER (Smart Orders) | Orders, Smart Orders |
validity | DAY | Orders, Smart Orders |
algo_id | 99999 (NSE, MCX), 9999999999999999 (BSE). Optional | Orders, Smart Orders |
source | equity, fno, index | Instruments CSV download |
exchange and segment are not freely combinable: COMMODITY is only valid with MCX, and MCX is only valid with COMMODITY. product is per segment — EQUITY takes CNC/INTRADAY, DERIVATIVE and COMMODITY take MARGIN/INTRADAY.
The segment and product query parameters on Portfolio Positions are case-insensitive — commodity and COMMODITY are both accepted, as are margin and MARGIN.
segment does not take the same values everywhere
The accepted value set differs by endpoint — they are not interchangeable:
- Orders / Smart Orders / Margin / lookups / Portfolio Positions:
EQUITY,DERIVATIVEorCOMMODITY - Option Chain: uppercase
INDEXorEQUITY— here it describes the underlying's segment, soDERIVATIVEis not a valid value even though the chain returns derivative contracts
Commodity (MCX) Trading¶
Everything specific to MCX commodity trading, in one place: the account and contract checks, the trading sessions, the off-market queue, and the size, value and price rules. The endpoints themselves are documented under Order Management and Smart Orders; this section covers only what differs for segment: "COMMODITY" with exchange: "MCX".
Commodity orders use the same endpoints with segment: "COMMODITY" and exchange: "MCX". Order ids come back with the COM- prefix. Smart orders on MCX are described under Commodity (MCX) Smart Orders.
| Field | Commodity value |
|---|---|
exchange | "MCX" only |
segment | "COMMODITY" |
product | "MARGIN" (carry-forward) or "INTRADAY" |
order_type | "LIMIT" or "MARKET". Do not send limit_price with MARKET. |
validity | "DAY" only |
security_id | The MCX contract's scrip code. |
qty | In units, not lots, and a whole multiple of the contract lot size. For a contract with a lot size of 100, qty: 100 is one lot. |
algo_id | Optional. Defaults to "99999". |
is_amo | Ignored. See Orders placed while MCX is shut. |
Example Request
curl --location 'https://api.indstocks.com/order' \
--header 'Authorization: YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"txn_type": "BUY",
"exchange": "MCX",
"segment": "COMMODITY",
"product": "MARGIN",
"order_type": "LIMIT",
"limit_price": 8632,
"validity": "DAY",
"security_id": "565899",
"qty": 100,
"algo_id": "99999",
"remarks": "crude-breakout/sig-118"
}'
Here 565899 is a CRUDEOIL futures contract with a lot size of 100 and a tick size of ₹1, so qty: 100 is one lot.
Response Payload (Success)
order_status is the order's state when the response is built — for example INITIATED, PENDING, or O-PENDING for an order queued while MCX is shut. An order that the exchange or RMS rejects during placement still returns HTTP 200, with order_status: "FAILED" and the reason:
{
"status": "success",
"data": {
"order_id": "COM-2016",
"order_status": "FAILED",
"reason": "Your order value exceeds the maximum limit set by the exchange. Please reduce the order quantity and try again."
}
}
Account and Contract Checks¶
These checks run before the order is placed. A failed check returns 400 with error_type: RequestValidationException and the message shown.
| Check | Message |
|---|---|
segment and exchange must be a valid pair. COMMODITY takes only MCX, and MCX takes only COMMODITY. This check runs first. | Exchange is missing or invalid; allowed values: MCX |
| Your account must have the commodity (MCX) segment activated. | user is not onboarded on the requested segment and exchange |
| The contract must be active and have a live price. | security 565899 is not tradeable on MCX or market data unavailable for security 565899 |
| Your commodity kill switch must be off. | order placement is paused because your kill switch is active |
MCX Trading Sessions¶
MCX runs two sessions on a trading day: a morning session 09:00–17:00 IST and an evening session 17:00–23:55 IST (23:30 IST while US daylight saving is in effect). Either session can be absent on a given day.
While a session is open, INTRADAY orders are refused once the intraday cutoff has passed — 23:45 IST (23:20 IST under US DST), or 16:50 IST on a day that has no evening session. The message is intraday order not allowed after cut-off time. The same cutoff applies to modifying an INTRADAY order. After the session closes, INTRADAY orders are accepted again and queued for the next session.
Orders Placed While MCX Is Shut¶
An order placed while MCX is shut is accepted and saved in INDstocks' own queue with status O-PENDING. This includes the 15-minute pre-open window before a session starts. INDstocks releases the order to the exchange after the next session opens. It is never sent to the exchange as a broker AMO.
- At release the order goes through the normal margin and order-rate checks. It can still end as
FAILED— for example on a margin shortfall. Check the result with Get Order Details or Get Order Book. - A
MARKETorder is priced when you place it: the last traded price at that moment plus or minus the protection buffer (see Market Orders Are Converted to Limit Orders). It is released at that limit price, even if the market opens away from it. We advise placing aLIMITorder instead, so you control the price the order is released at.
Order Size and Value¶
/order places exactly one exchange order for the whole qty:
qtymust be a whole multiple of the lot size —Qty should be multiple of 100.qtymust not exceed the contract's freeze quantity —Qty should be less than freeze qty 10000.- The order value must not exceed ₹3.5 crore, the exchange's per-order cap. Value is
qty × price × general factor, where the general factor converts the quoted price into the contract's rupee value. The price is the limit price, or for aMARKETorder the converted limit price. Over the cap:Order value 36000000.00 exceeds maximum allowed commodity order value of 35000000.00.
The value is checked again at the final price, after MARKET conversion; for an option, that check adds the strike price to the premium. A request that would then need more than one exchange order is refused with Qty requires slicing; use the smart order endpoint with slice_order=true. To place a larger quantity, send it to /smart/order with slice_order: true.
Price Rules¶
limit_pricemust be a multiple of the tick size —Limit Price should be multiple of 1.00.limit_pricemust be inside the contract's circuit limits for the day —Limit price must be within range 8102.00 - 9338.00. An out-of-range limit is rejected.- If the contract's circuit limits are not available, the order is rejected with
commodity live circuit bounds are unavailable. - On an option, the price must not exceed 1,00,000 —
Max Value of option allowed is 100000.
Modifying and Cancelling¶
- Modify Order and Cancel Order with
segment: "COMMODITY"accept onlyCOM-order ids. Any other id is rejected withinvalid order_id <id>. - Only a
PENDINGorO-PENDINGorder can be modified. The newqtyandlimit_pricemust pass the size, value and price rules above. The response carries the order's status after the change. - A
PENDING,O-PENDINGorPARTIALLY FILLEDorder can be cancelled. APARTIALLY FILLEDorder that has a linked stop-loss/target leg is refused, because cancelling it could also remove the protection for the filled part. - Cancelling an order that has a linked smart-order leg also cancels that leg. The response reports the leg in
child_order_details. - The cancel response carries the status read after the request. If the exchange has not yet confirmed the cancellation, the response adds
reason: "Cancellation requested; completion is not confirmed".
{
"status": "success",
"data": {
"order_id": "COM-2014",
"order_status": "CANCELLED",
"child_order_details": {
"order_id": "GTT-91822",
"order_status": "CANCELLED"
}
}
}
Reading Commodity Orders¶
Commodity orders appear in Get Order Book alongside equity and derivative orders, and Get Order Details, Get Trades and Get Trade Book take segment: "COMMODITY". Open commodity positions come from Get Positions with segment=commodity, and margin from the Margin Calculator with segment: "COMMODITY".
Smart Orders¶
Send segment: "COMMODITY" with exchange: "MCX" to /smart/order. The fields, account checks, trading sessions, off-market queue, and the size, value and price rules are the same as for Commodity (MCX) Orders. This section covers what is specific to smart orders.
Example Request — LIMIT order with stop-loss and target (Commodity)
curl --location 'https://api.indstocks.com/smart/order' \
--header 'Authorization: YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"txn_type": "BUY",
"exchange": "MCX",
"segment": "COMMODITY",
"product": "MARGIN",
"order_type": "LIMIT",
"validity": "DAY",
"security_id": "565899",
"qty": 100,
"limit_price": 8632,
"sl_trigger_price": 8550,
"sl_limit_price": 8545,
"tgt_trigger_price": 8750,
"tgt_limit_price": 8755,
"algo_id": "99999"
}'
Response Payload (Success)
{
"status": "success",
"data": {
"order_data": [
{
"order_id": "COM-2017",
"order_status": "CREATED",
"child_order_details": {
"order_id": "GTT-91822",
"order_status": "CREATED"
}
}
]
}
}
Commodity Rules¶
| Field or leg | Rule |
|---|---|
validity | "DAY" only. |
limit_price | Required for LIMIT; rejected with MARKET and with TRIGGER. Must be a multiple of the tick size and inside the contract's circuit limits and execution band. |
trigger_price | Required for TRIGGER. A multiple of the tick size, above the live price for a BUY and below it for a SELL. May sit outside the day's circuit limits — the order waits for it. |
trigger_limit_price | Optional. A multiple of the tick size. Defaults to trigger_price. |
trigger_price or trigger_limit_price on a LIMIT or MARKET order | Rejected — Trigger prices are only allowed for TRIGGER order type. |
| Stop-loss and target legs | Each leg requires both its trigger and its limit price, on the correct side of the entry price (see Place Smart Order). All four prices must be multiples of the tick size and inside the circuit limits and execution band — SL Trigger Price is outside circuit limits or execution band range. Allowed range: 8102.00 - 9338.00. |
| Order value | qty × entry price × general factor must not exceed ₹3.5 crore. The entry price is limit_price, the live price for MARKET, or trigger_limit_price (else trigger_price) for TRIGGER. |
Order IDs in the Response¶
order_type | What order_data contains |
|---|---|
LIMIT or MARKET without legs | One COM- order. |
LIMIT or MARKET with a stop-loss and/or target leg | The COM- parent, with the GTT- leg in child_order_details. The leg becomes active when the parent fills. |
TRIGGER | A GTT- parent. The COM- order is created when the trigger fires. |
order_status | Meaning |
|---|---|
CREATED | The order or leg has been saved. Read its live state with Get Order Details or Get Order Book. |
FAILED on the parent | The parent could not be placed. A reason is returned and the response carries no leg. |
FAILED on the leg | reason: "Trigger creation failed; protection is not active". The parent carries no protection. |
Slicing Large Commodity Orders¶
slice_order: true works the same way on MCX as elsewhere — see Slicing Large Orders for the rules, the split and the validations. Two things are specific to commodity:
- A slice must fit the contract's freeze quantity and ₹3.5 crore of order value. The value cap usually binds first, so the slice is smaller than the freeze quantity alone would allow.
order_dataholds one entry per slice —INITIATEDfor aCOM-slice,CREATEDfor theGTT-slices of aTRIGGERorder. ACOM-slice receives its stop-loss/target leg after the response; read it fromchild_order_idon Get Order Details. TheGTT-slices of aTRIGGERorder carry their leg in the response.
Modifying and Cancelling Commodity Smart Orders¶
Use segment: "COMMODITY" with a COM- or GTT- order id. Any other id, or a GTT- id that does not belong to a commodity order, is rejected with Order ID is missing or invalid.
| Order id | Rules |
|---|---|
GTT- | Modifiable only before it triggers — GTT order triggered, cannot be modified. Send the same kind of prices the order already holds; for a stop-loss-and-target pair, both sl_trigger_price and tgt_trigger_price (see Order Type Mismatch). A trigger price sent without its limit price keeps the saved limit price. New prices must pass the same tick, circuit, execution-band and value rules as placement, and the value is checked at the largest price in the request. |
COM- | Modified as described under Modify Order. |
qtyis optional on both and keeps the current quantity when left out.INTRADAYorders cannot be modified after the intraday cutoff.- Cancelling a
COM-parent also cancels its linkedGTT-leg, reported inchild_order_details. APARTIALLY FILLEDorder cannot be cancelled through this endpoint. - The cancel response carries the status read after the request. If the cancellation is not yet confirmed, it adds
reason: "Cancellation requested; completion is not confirmed".
Instrument Code Formats¶
Two different formats are used depending on whether you're calling REST or WebSocket:
| Context | Format | Separator | Example |
|---|---|---|---|
REST (scrip-codes query param) | SEGMENT_TOKEN | underscore _ | NSE_3045, NFO_51011 |
WebSocket (instruments array) | SEGMENT:TOKEN | colon : | NSE:2885, NFO:51011 |
REST (security_id, underlying-scrip) | bare token, no prefix | — | 2885, 40000001 |
The bare form is used wherever the segment is already given by another parameter — security_id on the order endpoints, and underlying-scrip on the Option Chain, where segment carries that information instead.
Index tokens: take them from the instruments file for the endpoint you are calling
For underlying-scrip, NIFTY 50 is 40000001, as listed by /market/instruments?source=index. Note that the WebSocket documentation uses NIDX:26000 as its NSE index example, so the two surfaces may not share the same index token. Do not carry a token from one to the other — look it up per surface.
WebSocket segment prefixes:
| Prefix | Meaning |
|---|---|
NSE: | NSE Equity |
BSE: | BSE Equity |
NFO: | NSE Derivatives (F&O) |
BFO: | BSE Derivatives (F&O) |
NIDX: | NSE Index |
BIDX: | BSE Index |
The underlying instrument identifier (SECURITY_ID / scrip code / token) is the same number in both formats — only the segment prefix and separator differ. Look up the right SECURITY_ID for a symbol via the Instruments API.
Order Status Values¶
The full list of order statuses (QUEUED, INITIATED, SUCCESS, CANCELLED, etc.) is maintained in one place: Orders — Order Status Types.
WebSocket Message Fields¶
| Field | Values | Feed |
|---|---|---|
action | subscribe, unsubscribe | Price Feed |
action | subscribe | Order Updates Feed |
mode | ltp, quote | Price Feed |
mode | order_update | Order Updates Feed |
See the WebSockets guide for full subscription payloads and response shapes.
TOTP Authentication¶
| Field | Description |
|---|---|
mpin | Your INDstocks account MPIN. |
totp | The current 6-digit TOTP code from your authenticator app. |
x-api-key | Your Client ID — a static, per-account identifier shown on the dashboard after successful TOTP setup. Sent as a header instead of Authorization, and distinct from access_token. |
Limits at a glance
| Rule | Value |
|---|---|
| Minimum gap between token generations | 1 per 60 seconds |
| Wrong TOTP codes before lockout | 5 in a rolling 15 minutes → 15-minute lockout |
| Repeated lockouts | 3 within 1 hour → 1-hour lockout + email alert |
| Time to complete TOTP setup | 5 minutes |
| Concurrent TOTP tokens | 1 — a new token invalidates the previous one |
| Access token validity | 24 hours |
See Getting Your Access Token — Method 2 and TOTP limits and lockouts.