Smart Order APIs (GTT)¶
This section outlines the APIs for placing, modifying, and canceling multi-leg "Good Till Triggered" (GTT) orders, which include simultaneous stop-loss and target legs, as well as Trigger orders.
Supported Segments
Smart Orders (GTT) and Trigger Orders are supported for both Equity and Derivative instruments.
How Smart Orders Work¶
When you place a smart order via /smart/order, the system creates two linked orders:
- Parent Order — The primary order (MARKET, LIMIT, or TRIGGER) that gets sent to the exchange first (except if the entered limit price is outside the circuit bounds, then parent order is placed as a GTT order instead).
- Child Order — A GTT (Good Till Triggered) order containing the stop-loss and/or target legs. It is linked to the parent and only activates once the parent order is successfully executed.
Order ID Prefixes¶
Each order ID carries a prefix that indicates its type:
| Prefix | Meaning | Used For |
|---|---|---|
EQ- | Equity order | Parent orders in the EQUITY segment |
DRV- | Derivative order | Parent orders in the DERIVATIVE segment |
GTT- | Good Till Triggered | Child orders (always), and parent orders when the limit price falls outside the circuit range |
- A parent order normally receives an
EQ-orDRV-prefix depending on the segment. - If the entered limit price is outside the circuit bounds, the parent order is placed as a GTT order instead and receives a
GTT-prefix. - Child orders always carry a
GTT-prefix.
Placement Response¶
The API response returns both order IDs in a single payload:
{
"status": "success",
"data": {
"order_data": [
{
"order_id": "DRV-28131451",
"order_status": "CREATED",
"child_order_details": {
"order_id": "GTT-2914581",
"order_status": "CREATED"
}
}
]
}
}
Modification and Cancellation¶
Parent and child orders are independent entities. To modify or cancel a smart order, you must operate on each order separately using its own order_id:
- Use
/smart/order/modifywith the parentorder_id(e.g.DRV-28131451) to modify the parent. - Use
/smart/order/modifywith the childorder_id(e.g.GTT-2914581) to modify the child. - The same applies to
/smart/order/cancel— each order must be cancelled individually.
Child Order Lifecycle
The child order will not activate until the parent order is successfully executed. If the parent order is cancelled, rejected, or fails, the linked child order remains inactive.
| Request Type | Path | Description |
|---|---|---|
| POST | /smart/order | Place a new multi-leg smart order |
| POST | /smart/order/modify | Modify a pending smart order |
| POST | /smart/order/cancel | Cancel a pending smart order |
Place Smart Order¶
This API allows you to place a new multi-leg smart order (GTT).
Endpoint
Request Body
| Parameter | Type | Mandatory | Description |
|---|---|---|---|
txn_type | string | ✅ | The transaction type. Enum: "BUY", "SELL" |
exchange | string | ✅ | The exchange to place the order on. Enum: "NSE" |
segment | string | ✅ | The market segment. Enum: "EQUITY", "DERIVATIVE" |
product | string | ✅ | The product type. For Equity: "CNC", "INTRADAY". For Derivative: "MARGIN", "INTRADAY" |
order_type | string | ✅ | The type of order. Enum: "LIMIT", "MARKET", "TRIGGER". Note: MARKET orders are automatically converted to LIMIT at the live price (see note below). |
validity | string | ✅ | The order validity. Enum: "DAY" |
security_id | string | ✅ | The unique identifier for the instrument. |
qty | integer | ✅ | The quantity of the instrument to trade. |
algo_id | string | ✅ | Algo identifier for the smart order. Use "99999" for NSE, "9999999999999999" for BSE orders. |
limit_price | number | ❌ | The price for the main LIMIT order. Required if order_type is "LIMIT". For MARKET orders the live market price is used. Not used for "TRIGGER" orders — omit it (it is not currently rejected there; see the warning below). |
trigger_price | number | ❌ | The trigger price for the order. Required if order_type is "TRIGGER". Must be a multiple of the instrument's tick size. For BUY: must be strictly greater than CMP. For SELL: must be strictly less than CMP. |
trigger_limit_price | number | ❌ | Optional limit price for a trigger-limit order. If provided alongside trigger_price, the order executes as trigger-limit; otherwise it executes as trigger-market. If omitted, trigger_limit_price is automatically set equal to trigger_price. Must be a multiple of the instrument's tick size. |
sl_trigger_price | number | ❌ | The trigger price for the stop-loss leg. Must sit below the entry price on a BUY, above it on a SELL. If set, sl_limit_price must also be provided or the order is rejected. |
tgt_trigger_price | number | ❌ | The trigger price for the target (profit) leg. Must sit above the entry price on a BUY, below it on a SELL. If set, tgt_limit_price must also be provided or the order is rejected. |
sl_limit_price | number | ❌ | The limit price for the stop-loss order once triggered. Required when sl_trigger_price is set. |
tgt_limit_price | number | ❌ | The limit price for the target order once triggered. Required when tgt_trigger_price is set. |
is_tsl | boolean | ❌ | Currently ignored — TSL is not live. Intended: set to true to make the stop-loss leg a trailing stop-loss. Requires a stop-loss leg and tsl_step_size. Not supported when order_type is "TRIGGER". See Trailing Stop Loss. |
tsl_step_size | number | ❌ | Currently ignored — TSL is not live. Intended: the trailing step, in rupees. Must be greater than zero and a multiple of the instrument's tick size. Required when is_tsl is true, and must be omitted (or zero) when is_tsl is false. |
remarks | string | ❌ | Your own free-text tag for the order — a strategy name, a signal id, anything you want to reconcile against later. Carried onto every leg, including the live order created when a stop-loss or target leg triggers. Max 100 characters, silently truncated beyond that; cannot be changed on modify. See Order Remarks. |
Example Request — LIMIT order (Derivative)
curl --location 'https://api.indstocks.com/smart/order' \
--header 'Authorization: YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"txn_type": "BUY",
"exchange": "NSE",
"segment": "DERIVATIVE",
"product": "MARGIN",
"order_type": "LIMIT",
"validity": "DAY",
"security_id": "51011",
"qty": 75,
"limit_price": 37,
"sl_trigger_price": 34,
"tgt_trigger_price": 41,
"sl_limit_price": 33,
"tgt_limit_price": 38,
"algo_id": "99999",
"remarks": "momentum-v2/sig-4471"
}'
Example Request — Trigger-Market order (Equity)
curl --location 'https://api.indstocks.com/smart/order' \
--header 'Authorization: YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"txn_type": "BUY",
"exchange": "NSE",
"segment": "EQUITY",
"product": "CNC",
"order_type": "TRIGGER",
"validity": "DAY",
"security_id": "3045",
"qty": 10,
"trigger_price": 1520.00,
"algo_id": "99999"
}'
Example Request — Trigger-Limit order (Derivative)
curl --location 'https://api.indstocks.com/smart/order' \
--header 'Authorization: YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"txn_type": "BUY",
"exchange": "NSE",
"segment": "DERIVATIVE",
"product": "MARGIN",
"order_type": "TRIGGER",
"validity": "DAY",
"security_id": "51011",
"qty": 75,
"trigger_price": 38.50,
"trigger_limit_price": 38.75,
"algo_id": "99999"
}'
Example Request — Trigger order with stop-loss and target legs (Derivative)
curl --location 'https://api.indstocks.com/smart/order' \
--header 'Authorization: YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"txn_type": "BUY",
"exchange": "NSE",
"segment": "DERIVATIVE",
"product": "MARGIN",
"order_type": "TRIGGER",
"validity": "DAY",
"security_id": "46997",
"qty": 65,
"trigger_price": 318.75,
"trigger_limit_price": 319,
"sl_trigger_price": 316.65,
"sl_limit_price": 316.40,
"tgt_trigger_price": 328.65,
"tgt_limit_price": 328.90,
"algo_id": "99999"
}'
Here the legs are checked against an entry price of 319 — the trigger_limit_price — rather than limit_price, which plays no part in a TRIGGER order's execution.
Validations
- QtyMustBeAboveZero: Qty must be specified and greater than zero
- LimitPriceMustBeAboveZero: Limit price must be specified and greater than zero (applies to
LIMITorders) - QtyWithinFreezeQty: Qty should be less than freeze qty
- MaxValueOfOption: Max Value of option allowed is enforced
- QtyMultipleOfLotSize: Qty should be multiple of lot size
- MaxSlTriggerPrice / MinSlTriggerPrice: the stop-loss trigger must sit below the entry price on a BUY, above it on a SELL
- MaxSlLimitPrice / MinSlLimitPrice: the stop-loss limit must sit below the stop-loss trigger on a BUY, above it on a SELL
- MinTgtTriggerPrice / MaxTgtTriggerPrice: the target trigger must sit above the entry price on a BUY, below it on a SELL
- MinTgtLimitPrice / MaxTgtLimitPrice: the target limit must sit above the target trigger on a BUY, below it on a SELL
- TriggerPriceMustBeAboveZero:
trigger_pricemust be present and greater than zero whenorder_typeis"TRIGGER" - TriggerPriceTickSize:
trigger_pricemust be a multiple of the instrument's tick size - TriggerLimitPriceTickSize:
trigger_limit_price(if provided) must be a multiple of the instrument's tick size - TriggerPriceVsCMP (BUY):
trigger_pricemust be strictly greater than the current market price - TriggerPriceVsCMP (SELL):
trigger_pricemust be strictly less than the current market price - The five
Tsl*rules below are not currently enforced — TSL is not live and both fields are ignored. See Trailing Stop Loss. - TslStepSizeRequiredWhenEnabled:
tsl_step_sizemust be specified and greater than zero whenis_tslistrue - TslFlagRequiredWithStepSize:
is_tslmust betruewhentsl_step_sizeis provided - TslRequiresStopLoss: a trailing stop loss requires a stop-loss leg (
sl_trigger_priceandsl_limit_price) - TslNotAllowedForTriggerOrder: a trailing stop loss is not supported for
order_type: "TRIGGER" - TslStepSizeMultipleOfTickSize:
tsl_step_sizemust be a multiple of the instrument's tick size - ReservedRemarks:
remarksmust not use a value reserved for INDstocks' internal channel tags (see Order Remarks)
Market Orders Are Converted to Limit Orders
API trading does not support pure MARKET orders. If you submit order_type: "MARKET", the order is automatically converted to a LIMIT order priced at the current live market price before being sent to the exchange.
Similarly, for TRIGGER orders, if trigger_limit_price is omitted it is automatically set equal to trigger_price, so the order executes as a trigger-limit order at the trigger price.
Stop-Loss and Target Legs Require a Limit Price
If you provide sl_trigger_price, you must also provide sl_limit_price. Likewise, if you provide tgt_trigger_price, you must also provide tgt_limit_price. Submitting a stop-loss or target leg without its corresponding limit price will cause the order to be rejected.
Where the Stop-Loss and Target Legs Must Sit
Both legs are validated against the parent order's entry price, which depends on order_type:
order_type | Entry price |
|---|---|
LIMIT | limit_price |
MARKET | the live market price |
TRIGGER | trigger_limit_price, or trigger_price when that is omitted |
On a BUY the stop-loss must sit below the entry price and the target above it. On a SELL it is the mirror image — stop-loss above, target below. A leg on the wrong side is rejected.
Do Not Send limit_price on a TRIGGER Order
A trigger order's entry price comes from trigger_limit_price (or trigger_price); limit_price plays no part in it.
Sending limit_price anyway is not currently rejected — the request succeeds — but it is unsupported on a TRIGGER order and can change how the order is handled internally. Omit the field.
Trailing Stop Loss (TSL)¶
Trailing Stop Loss Is Not Yet Available
is_tsl and tsl_step_size are not live. They are accepted and then silently ignored — the request succeeds and your order is placed with an ordinary, non-trailing stop-loss. You will not receive an error.
Do not rely on trailing behaviour until this notice is removed. The rest of this section describes the intended behaviour once the feature ships.
A trailing stop loss is a stop-loss leg whose trigger price follows the market in your favour. As the price moves favourably, the stop-loss trigger is stepped along behind it by tsl_step_size; when the price moves against you, the trigger stays where it is. It only ever ratchets one way, which is what locks in gains.
TSL is not a separate order type — it is a modifier on the stop-loss leg of a smart order. You enable it with two fields:
| Field | Meaning |
|---|---|
is_tsl | true turns the stop-loss leg into a trailing stop-loss |
tsl_step_size | How far, in rupees, the trigger trails behind the price |
Example Request — Trailing stop loss (Equity)
curl --location 'https://api.indstocks.com/smart/order' \
--header 'Authorization: YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"txn_type": "BUY",
"exchange": "NSE",
"segment": "EQUITY",
"product": "CNC",
"order_type": "LIMIT",
"validity": "DAY",
"security_id": "2885",
"qty": 1,
"limit_price": 1400.05,
"sl_trigger_price": 1375.00,
"sl_limit_price": 1374.50,
"is_tsl": true,
"tsl_step_size": 0.05,
"algo_id": "99999"
}'
In this example the stop-loss starts at ₹1375.00. If the price climbs, the trigger is trailed upward in ₹0.05 steps; if the price falls back, the trigger holds at the highest level it reached.
Requirements¶
- A stop-loss leg is mandatory: send both
sl_trigger_priceandsl_limit_price. TSL rides on the stop-loss leg, so a request withis_tsl: trueand no stop-loss is rejected. is_tslandtsl_step_sizemust agree —is_tsl: truerequirestsl_step_size > 0, and sending atsl_step_sizewithoutis_tsl: trueis rejected.tsl_step_sizemust be a multiple of the instrument's tick size.- Not supported for
order_type: "TRIGGER". A trigger order can carry an ordinary stop-loss leg, but that leg cannot trail. - Supported on
/smart/orderonly.is_tslsent to the plain/orderendpoint is ignored.
The Trail Starts Only After the Parent Order Executes
Like every child leg (see Child Order Lifecycle), the trailing stop-loss becomes active only once the parent order is successfully executed. Until the parent fills, the stop-loss is recorded against the order but is not yet trailing. If the parent is cancelled or rejected, the trail never starts.
Reading the trailed price¶
On /order and /order-book, a trailing stop-loss order carries two extra fields:
| Field | Type | Description |
|---|---|---|
is_tsl | boolean | true when the order has an active trailing stop-loss |
tsl_step_size | number | The trailing step in rupees |
For a TSL order, sl_trigger_price reflects the live trailed trigger — the current, stepped-up value — not the price you originally submitted. sl_limit_price moves with it, preserving your original trigger-to-limit gap.
Changing a trailing stop loss¶
The Step Size Is Fixed Once the Order Is Placed
tsl_step_size cannot be changed, and TSL cannot be switched off, through /smart/order/modify — those fields are not accepted on modify. To use a different step size, cancel the order and place a new one.
You can still modify the other attributes of a trailing order (for example sl_trigger_price, sl_limit_price, or qty) in the normal way. Simply omit the TSL fields and the trail is preserved.
Modify Smart Order¶
This API allows you to modify a pending smart order.
Endpoint
Request Body
| Parameter | Type | Mandatory | Description |
|---|---|---|---|
order_id | string | ✅ | The unique ID of the order to be modified |
segment | string | ✅ | The market segment. Enum: "EQUITY", "DERIVATIVE" |
algo_id | string | ✅ | Algo identifier. Use "99999" for NSE orders. |
order_type | string | ❌ | The type of order. Enum: "LIMIT", "MARKET", "TRIGGER". Must match the existing order type. |
qty | integer | ❌ | The quantity of the instrument to trade |
limit_price | number | ❌ | The price for the main LIMIT order (applies to LIMIT orders only) |
trigger_price | number | ❌ | The trigger price for the order. Required when modifying a TRIGGER order. Must be a multiple of tick size. For BUY: must be strictly greater than CMP. For SELL: must be strictly less than CMP. |
trigger_limit_price | number | ❌ | Optional limit price for a trigger-limit order. Must be a multiple of tick size. |
sl_trigger_price | number | ❌ | The trigger price for the stop-loss leg |
tgt_trigger_price | number | ❌ | The trigger price for the target (profit) leg |
sl_limit_price | number | ❌ | The limit price for the stop-loss order |
tgt_limit_price | number | ❌ | The limit price for the target order |
remarks cannot be changed
This endpoint does not accept remarks. The order keeps the remark it was placed with. See Order Remarks.
Example Request — Modify LIMIT order
curl --location 'https://api.indstocks.com/smart/order/modify' \
--header 'Authorization: YOUR_ACCESS_TOKEN' \
--data '{
"order_id": "DRV-123",
"segment": "DERIVATIVE",
"algo_id": "99999",
"order_type": "LIMIT",
"qty": 20,
"limit_price": 0.35,
"sl_trigger_price": 0.15,
"tgt_trigger_price": 41,
"sl_limit_price": 0.1,
"tgt_limit_price": 42
}'
Example Request — Modify Trigger order
curl --location 'https://api.indstocks.com/smart/order/modify' \
--header 'Authorization: YOUR_ACCESS_TOKEN' \
--data '{
"order_id": "EQ-456",
"segment": "EQUITY",
"algo_id": "99999",
"order_type": "TRIGGER",
"qty": 10,
"trigger_price": 1530.00,
"trigger_limit_price": 1532.00
}'
Order Type Mismatch
The order_type in the modify request must match the type of the existing order. Sending order_type: "TRIGGER" for a LIMIT order (or vice versa) will be rejected.
Trailing Stop Loss on Modify
is_tsl and tsl_step_size are not accepted on modify. Modifying any other field of a trailing order leaves the trail running with its original step size — see Changing a trailing stop loss.
Cancel Smart Order¶
This API allows you to cancel a pending smart order.
Endpoint
Request Body
| Parameter | Type | Mandatory | Description |
|---|---|---|---|
order_id | string | ✅ | The unique ID of the order to be cancelled. |
segment | string | ✅ | The market segment. Enum: "EQUITY", "DERIVATIVE" |
Example Request
curl --location 'https://api.indstocks.com/smart/order/cancel' \
--header 'Authorization: YOUR_ACCESS_TOKEN' \
--data '{
"segment": "DERIVATIVE",
"order_id": "123456789"
}'
Validations
- OrderIdMissing: Order ID is missing or invalid
- OrderCannotBeCancelled: Order is not eligible for cancellation
See Also¶
- Orders — standard (non-GTT) order placement and management
- Margin Calculator — check required margin before placing an order
- Glossary & Constants —
EQ-/DRV-/GTT-ID prefixes and shared enums - Error Bucket — RMS rejection messages and
OrderExceptionhandling