SAHI DOCS

API reference

Funds

Your available balances per order kind, and the margin an order would need before you place it.

Available balances#

GET /v1/funds

Scope funds.read

What your account can fund right now, and the components behind it. Reflects the live balance on your trading account.

There is no single "available balance" to report. The OMS holds one risk snapshot per account, but funds an order from a different formula depending on what the order is: pledge collateral is spendable against an intraday position and not against a delivery buy, and option premium received is spendable only in the exchange group it was received in. So available carries one figure per order kind, and balance, utilised and option_premium carry the components those figures are built from.

Size an order against the figure for the order you are about to place. POST /v1/margins/order picks the same branch for you, for one specific order.

Response — 200 OK#

Every figure is integer paise. The account above holds ₹1,05,000 of cash, ₹20,000 of pledge collateral, ₹10,000 of margin blocked on an F&O position, and has received ₹5,000 of equity option premium — which is why its four balances differ.

available — the balance the OMS will check an order of that kind against. Can be negative when the account is in debit.

stocks_delivery integer
Paise. For delivery orders (product: "C"). Pledge collateral is not spendable here.
intraday_and_fno_selling integer
Paise. For everything that is neither a delivery order nor an option buy — stocks intraday, futures, option selling. Pledge collateral is spendable here.
options_buying object
Paise per premium pool, see below.

available.options_buying — RMS keeps option premium in three pools that must not cross-fund. Premium received is spending power only inside its own pool; in the other pools it may offset charges, but nothing more. Size an option buy against the pool its exchange_segment belongs to — using another pool's figure over-orders, and the OMS rejects the order.

equity_fno
Equity and index options.
mcx
MCX commodity options.
ncom
NSE commodity options.

All three are always present. A figure for a segment the account is not activated for is not tradable.

balance — the money in the account, before anything is blocked against it.

opening_balance integer
Paise. Cash carried into the trading day.
payin integer
Paise. Funds added today.
payout integer
Paise, positive. Funds withdrawn today.
collateral integer
Paise. Margin available from pledged holdings.
delivery_sell_credit integer
Paise, positive. Credit from today's delivery sells.

utilised — what is blocked against that money.

span integer
Paise. SPAN margin on derivative positions.
exposure integer
Paise. Exposure margin on derivative positions.
delivery_margin integer
Paise. Physical-delivery margin, levied near expiry on physically settled contracts.
intraday_margin integer
Paise. Margin blocked by today's intraday positions.
delivery_buy integer
Paise. Cash blocked by today's delivery buys.
charges integer
Paise. Brokerage and regulatory charges accrued today — the OMS reports them as one figure.
mtm_loss integer
Paise, positive. Today's net mark-to-market loss (realised + unrealised); 0 when the account is in profit. Only a net loss blocks funds.

option_premium — premium held today. paid and received are the account-level net, so at most one of them is non-zero; the per-pool figures are in by_pool.

paid integer
Paise, positive. Net premium paid across all pools. 0 whenever the account received more premium than it paid overall — including when it did pay premium in one of the pools.
received integer
Paise, positive. Net premium received across all pools.
by_pool object
Paise per pool, signed: positive is net premium paid in that pool, negative is net premium received. Keys are equity_fno, mcx, ncom, as under available.options_buying.

Premium actually paid is the sum of the positive by_pool entries, not paid — and it is deducted from every option-buying pool, wherever it was paid. An account that received ₹4,000 of premium on equity F&O and ₹5,000 on NCOM while paying ₹2,000 on MCX reports paid: 0 and received: 700000 — the ₹9,000 received net of the ₹2,000 paid — and all three figures under available.options_buying are ₹2,000 lower for that MCX premium. Reconcile a pool balance against by_pool; paid and received are what the delivery and intraday balances use, where only the net matters.

How the balances are computed#

The four figures under available are exact functions of the other three blocks, so any of them can be reconciled field by field. Writing

the delivery and intraday figures are

Collateral is the difference between them: in the delivery formula it can only offset the margin block (and never turns into spendable cash, hence the outer max(…, 0)), while in the intraday formula it is added outright.

Each option-buying pool uses its own premium, and only the other pools' received premium against charges:

Premium paid is deducted from every pool wherever it was paid; premium received is added back only in the pool that received it.

404 NOT_FOUND if the account behind the token has no trading account yet.


Order margin#

POST /v1/margins/order

Scope funds.read

What an order would cost before you place it: the margin the OMS would block for it, and the balance you have to fund it. Nothing is placed, and the call is not IP-checked.

The body is the one you would send to POST /v1/orders, so one order object serves both calls. It is validated the same way, and a MKT / SL-MKT order is quoted at the protected limit price it would be placed at (see Market protection) — the figure is for the order as it would actually reach the exchange, not for an unprotected fill at LTP. Fields that do not affect margin (validity, disclosed_qty, variant) are accepted and checked for shape, but do not change the answer. One rule from place order is deliberately not applied: qty is not capped at the instrument's freeze quantity, so you can quote a full position before slicing it into placeable orders.

Request#

exchange_segment string Required
NSE | NFO | BSE | BFO.
symbol string Required
The scrip master's symbol column (e.g. RELIANCE, NIFTY29DEC26C24500, SENSEX26NOVFUT). Look it up rather than building it: NFO and BFO contracts follow different exchange formats.
txn_type string Required
B | S.
qty integer Required
Total quantity in units.
order_type string Required
LMT | MKT | SL-LMT | SL-MKT.
product string Required
C | I | M | F.
validity string Required
DAY | IOC. Required for parity with place order; does not affect margin.
price integer Required
Paise. Use 0 for MKT / SL-MKT. Must be a multiple of tick size for LMT / SL-LMT.
trigger_price integer conditional
Paise. Required for SL-LMT / SL-MKT.
disclosed_qty integer Optional
Accepted; does not affect margin.
market_protection number Optional
As on place order: sets the protected price a MKT / SL-MKT order is quoted at. Ignored for LMT / SL-LMT.
variant string Optional
REGULAR (default) | AMO. Validated as on place order (a MKT / SL-MKT AMO is rejected); does not affect margin.

Response — 200 OK#

required_margin integer
Paise. The margin the OMS would block for this order right now — the same figure a placement is checked against.
available_margin integer
Paise. The balance available to fund this order, computed the way the OMS funds this kind of order (delivery, option buy, or intraday / F&O) — the same branch GET /v1/funds reports under available, picked for this order's segment and product.

The order is affordable when available_margin is at least required_margin. Both figures are a snapshot: prices, positions and other open orders move them, and a placement is checked afresh by the OMS, so a passing margin check does not guarantee acceptance.

An unknown symbol for the exchange_segment is refused with 422 VALIDATION_FAILED; malformed fields with 400 VALIDATION_FAILED, exactly as on place order. 404 NOT_FOUND if the account behind the token has no trading account yet — the same answer GET /v1/funds gives. Between 04:45 and 07:00 IST, while the OMS runs its beginning-of-day processing, the request is refused with 503 UNDER_MAINTENANCE; retry after 07:00.


Basket margin#

POST /v1/margins/basket

Scope funds.read

What a basket of orders would cost together. The answer is for the basket as a whole: the OMS nets the legs against each other and against your existing positions, so a hedged basket needs less than the sum of its legs' individual Order margin figures — the difference is the margin benefit. Nothing is placed, and the call is not IP-checked.

Each leg is the exact POST /v1/orders body, treated exactly as on the single-order check: validated the same way, with MKT / SL-MKT legs quoted at their protected limit prices. One call costs one unit of the margin budget whatever the leg count, and up to 10 legs are accepted.

Request#

legs object[] Required
1 to 10 orders, each the exact POST /v1/orders body, validated as on POST /v1/margins/order. One bad leg refuses the whole request, and the error message names the leg by its zero-based index.

Response — 200 OK#

required_margin integer
Paise. The margin the OMS would block for the basket as a whole, right now — legs netted against each other and your existing positions.
available_margin integer
Paise. As on POST /v1/margins/order: the balance available to fund these orders, computed the way the OMS funds them.

When every leg draws on the same margin pool, the basket is affordable when available_margin is at least required_margin. For a basket that mixes pools (say an equity delivery leg alongside a commodity option), available_margin is still quoted from a single pool, so that comparison can overstate what the account can fund across all the legs. Both figures are a snapshot, and a placement is checked afresh by the OMS — a passing check does not guarantee acceptance.

For a basket where every leg buys options, the figures are the OMS quote as-is: the OMS nets option premium received into required_margin while also counting it in available_margin, so the quoted requirement can understate what the placement will actually block.

Errors are as on POST /v1/margins/order: an unknown symbol is 422 VALIDATION_FAILED, malformed fields are 400 VALIDATION_FAILED (naming the leg), 404 NOT_FOUND means the account behind the token has no trading account yet, and 503 UNDER_MAINTENANCE is the 04:45–07:00 IST maintenance window. Two refusals are this endpoint's own: an empty legs array is 400 VALIDATION_FAILED, and a basket over the 10-leg cap is 422 VALIDATION_FAILED — the same code an unknown symbol gets, so tell them apart by the message, which names the cap.