Skip to main content

Triggers

Triggers are conditional orders held by the exchange and submitted when the market reaches a trigger price. Product behavior is described in Take Profit and Stop Loss.

Add a trigger​

import { Side, TriggerKind } from "@n1xyz/nord-ts";

const { actionId, triggerId } = await user.addTrigger({
marketId: 0,
side: Side.Ask,
kind: TriggerKind.StopLoss, // or TriggerKind.TakeProfit
triggerPrice: 45000,
limitPrice: 44900, // optional; omit for a market-style exit
limitBaseSize: 0.1, // optional
limitQuoteSize: 4490, // optional
accountId, // optional
referrer, // optional referral identifier
});

triggerPrice must be positive. limitPrice, limitBaseSize, and limitQuoteSize limit the order created when the trigger fires. You can set either size limit or both; when both are set, the smaller resulting order applies. With no size limit, the trigger tries to close the full position.

addTrigger returns actionId and the new triggerId as bigint. The trigger ID is the trigger's identity: two triggers can share the same prices and limits. An account can have at most 16 active and pending triggers per market.

Attach TP/SL to an order​

Pass triggers to placeOrder to attach a take-profit and stop-loss to the order.

import { FillMode, Side } from "@n1xyz/nord-ts";

const { orderId, triggerMutations } = await user.placeOrder({
marketId: 0,
side: Side.Bid,
fillMode: FillMode.Limit,
isReduceOnly: false,
size: 0.01,
price: 60000,
triggers: {
Pair: {
take_profit_prices: { trigger: 66000 },
stop_loss_prices: { trigger: 57000, limit: 56900 }, // limit is optional
},
},
});

The pair is one-cancels-other (OCO): when one trigger executes, the other is canceled. To attach a single trigger, use { Single: { kind: "takeProfit" | "stopLoss", prices: { trigger, limit? } } }.

Attached triggers take only prices; their size follows the parent's fills. The parent must not be reduce-only. The triggers stay pending while the parent rests and become active when it fills. placeOrder, cancelOrder, and cancelOrderByClientId report affected triggers in triggerMutations.placed, triggerMutations.activated, and triggerMutations.cancelled.

Replace and remove​

replaceTrigger replaces the trigger's parameters, so pass the full definition — triggerId, marketId, side, kind, triggerPrice, and any limit fields — not just the fields you are changing.

await user.replaceTrigger({
triggerId,
marketId: 0,
side: Side.Ask,
kind: TriggerKind.TakeProfit,
triggerPrice: 72000,
});

await user.removeTrigger({ triggerId });

replaceTrigger takes the same price, size, and referrer fields as addTrigger, but no accountId: the account comes from triggerId. Both calls return { actionId } and work on pending and active triggers.

Triggers in atomic actions​

atomic accepts addTrigger, replaceTrigger, and removeTrigger subactions. The trigger type is triggerKind, because kind names the subaction.

await user.atomic(
[
{ kind: "removeTrigger", triggerId },
{
kind: "addTrigger",
marketId: 0,
side: Side.Ask,
triggerKind: TriggerKind.StopLoss,
triggerPrice: 43000,
},
],
accountId,
);

Per market, cancels and trigger removals go first and placements, trigger additions, and replacements go last. One atomic action can't replace or remove the same trigger twice, or touch a trigger it adds.

Query triggers​

SDK methodEndpointPurpose
getAccountTriggersGET /account/{account_id}/triggersPending and active triggers
getAccountTriggerPlaceHistoryGET /account/{account_id}/triggers/history/placementsPlacement history
getAccountTriggerFinaliseHistoryGET /account/{account_id}/triggers/history/finalisationsFinalization history
const triggers = await nord.getAccountTriggers({ accountId });
const active = triggers.filter((t) => t.orderId == null);

const placements = await nord.getAccountTriggerPlaceHistory({
accountId,
since: "1970-01-01T00:00:00Z",
until: new Date().toISOString(),
pageSize: 50,
});

All three methods require accountId. A trigger with a parent orderId is pending on that order; one without is active. Each trigger also carries marketMode and, for OCO pairs, the sibling trigger ID. Trigger IDs are strings in these responses, so wrap them in BigInt() before passing them to removeTrigger.

History pages return nextStartInclusive; pass it back unchanged as startInclusive to fetch the next page. Finalization rows add status (such as Success, Removed, Cancelled, or Failed) and an optional error.

A trigger stays live until it executes, is canceled, or is removed. Closing or flipping the position, or switching the market from CLOB to RFQ, cancels its triggers, so reconcile against the finalization history rather than assuming a trigger is still live. There is no exchange-wide trigger endpoint.

These materials are provided for informational purposes only and do not constitute financial, investment, legal, or tax advice, or an offer or solicitation to buy or sell any asset. Trading digital assets and derivatives involves substantial risk, including the possible loss of some or all capital. Products may not be available in all jurisdictions. Users are responsible for evaluating suitability and complying with applicable laws.