VERSION HISTORY
Trading with the API
Fetches the article and compares it with Version 6.
▸Version 6October 19, 2026, 4:45 PM+5−0
Changes shown against Version 5.
including unrealized P\&L, reaches the profit target, so track
risk.remaining_profit_equity. When it reaches zero, the evaluation passes and
open positions are closed. risk.remaining_profit counts realized profit only
and can stay above zero while open profit already covers the target. Both are
null when the account has no profit target, and remaining_profit_equity is
also null when marks are incomplete.
Copy groups and scheduled execution
Before submitting a lead order through the API, ensure the credential covers
the lead and every follower. The same boundary applies to modifications,
cancellations, and protective exits. A scope failure rejects the complete
native order operation, preserving the copy group's behavior rather than
silently dropping a follower. See Authentication.
+ Competition accounts cannot lead or follow in a copy group, because the
+ Competition Rules prohibit copying trades into or out of them.
+ POST /v1/copy-trading rejects an enabled group that includes one. A group
+ saved before this rule does not copy lead orders to or from a competition
+ account; disable it with POST /v1/copy-trading/{config_id}/disable.
Accepted TWAP/VWAP and scaled orders retain the environment and account scope
that authorized them. Revoking the key blocks new requests but does not revoke
that accepted schedule. Each later slice or rung checks the current copy group
against its retained scope. If the group now includes an inaccessible account,
TWAP/VWAP stops with completion_reason: "api_account_scope_changed"; scaled
orders reject the remaining unplaced rungs with that reject_reason. Previously
accepted child orders are not canceled, and filled positions are not closed.
Older API schedules created before scope was retained can recover their
boundary while the original key still exists. If that key has been deleted,
only the schedule's own account can be established: an enabled copy group
causes future slices or rungs to stop rather than assume broader access. Finish
or recreate an older copied schedule before deleting its original key.
SHA-256 e5c2777202d310e3347108c8b0a243a6de3f75fe4a3571942bc7e7b675172094
▸Version 5October 18, 2026, 3:45 AM+4−3
Changes shown against Version 4.
that account's position. Long and short notional
add together. An opening fill that would exceed the cap is rejected with
exposure_cap, without resizing. Reductions and closes remain allowed, and
freed capacity becomes available at the next refresh, approximately 10 seconds
later. See Asset Exposure Limits.
Standard and advanced orders
Send orders to POST /v1/orders. If type is omitted, the request is treated
as a market order for compatibility with existing clients.
| type | Required price fields | Important options |
|---|
| limit | limit_price | attached TP/SL, IOC, FOK, or GTD time in force |
−
stop_limit trigger_price, limit_price opening conditional order
| type | Required price fields | Important options |
|---|---|---|
| stop_market | trigger_price | optional reduce-only protection |
+
stop_limit trigger_price, limit_price opening conditional order, attached TP/SL
| type | Required price fields | Important options |
|---|---|---|
| stop_market | trigger_price | attached TP/SL, or reduce-only protection |
| take_market | trigger_price | opening conditional order |
| take_profit | trigger_price, reduce_only: true | position protection |
The server resolves provider, symbol, and venue coin from market_id. Do not
send those fields. expected_price records what your client observed, but it
never controls the execution price, margin calculation, or slippage reference.
FX markets trade on veranta. Use their current market_id values from
GET /v1/markets. The previous hyperliquid EUR/USD and USD/JPY markets are
retiring: they accept only orders that reduce or close existing positions
there. The historical fpx and lighter providers are retired and have no
markets available for new trades.
copy uses the leverage you send, lowered to the follower's own maximum for
that market when needed, and keeps the margin mode of any position the
follower already holds in that market. See
Copy Trading.
Use GET /v1/orders?client_order_id=... to resolve your caller-assigned order
identity when the placement response or server id is unavailable. This lookup
survives API key rotation and returns the normal order-page shape with zero or
one result.
If the server cannot prove the snapshot is complete inside the active-order
bound, it returns 503 with Retry-After instead of returning truncated data.
- PATCH /v1/orders/{order_id} changes price and optionally size.
- PUT /v1/orders/{order_id}/attached-exits sets or removes TP/SL attached to
− a resting limit entry. Send null to remove a leg.
+ a resting limit, stop_market, or stop_limit entry. Send null to remove
+ a leg.
- DELETE /v1/orders/{order_id} cancels a working order or queues cancellation
when execution already owns the row.
To cancel the complete ordinary-order snapshot for an account, send
POST /v1/accounts/{account_id}/cancel-all-orders with an Idempotency-Key.
It includes resting orders and armed trigger orders. An in-flight market order
can still settle, and active TWAP, VWAP, or scaled parents must be canceled
through their own endpoints. Each request advances at most five source orders,
with every source cancellation isolated in its own transaction. A 202
response includes progress and Retry-After; repeat the same request until the
operation reports completed.
Chase orders cannot be modified. Cancel the chase and place a replacement with
new offset or cap settings.
SHA-256 26ae751f183b347261c4521652863e27e29b05747bee3bc1da87b6f66cdc7ad8
▸Version 4October 15, 2026, 4:45 PM+6−0
Changes shown against Version 3.
Trading with the API
Source: https://docs.myfundedperpetuals.com/trading-with-api
Place and manage every order type available in the trading terminal.
The REST API uses the same order books, trading rules, fees, margin checks, and
paper execution engine as the trading terminal. Every create request requires
an Idempotency-Key header. Standard orders and position closes may also carry
a caller-assigned client_order_id for durable reconciliation.
+ Close notifications in the trading terminal also cover orders placed through
+ the API. A full close reports the whole trade's settled net PnL, including
+ entry and exit fees, earlier partial closes, and swap payments. Partial-close
+ notifications distinguish a closed portion from a legacy fill-only result.
+ See PnL Display for the calculation scopes.
+ Order history continues to report each fill's own realized PnL and fee.
Exposure caps
API orders share the same per-user market exposure allowance as orders placed
in the terminal. Your own accounts of the same product and size share one cap
for each market; other users have separate allowances. Elite accounts are the
exception: each Elite account has its own cap for each market, counting only
that account's position. Long and short notional
add together. An opening fill that would exceed the cap is rejected with
exposure_cap, without resizing. Reductions and closes remain allowed, and
freed capacity becomes available at the next refresh, approximately 10 seconds
later. See Asset Exposure Limits.
Standard and advanced orders
Send orders to POST /v1/orders. If type is omitted, the request is treated
SHA-256 65c59919eab5e6af4534fe423d4634595be8f2c0ac5ba3c5b75f829df44a325b
▸Version 3October 14, 2026, 4:45 PM+5−3
Changes shown against Version 2.
| market | expected_price | slippage_tolerance_bps, attached TP/SL |
|---|
The server resolves provider, symbol, and venue coin from market_id. Do not
send those fields. expected_price records what your client observed, but it
never controls the execution price, margin calculation, or slippage reference.
− FX markets are EUR/USD and USD/JPY, both on hyperliquid. Use their current
− market_id values from GET /v1/markets. The historical fpx and lighter
− providers are retired and have no markets available for new trades.
+ FX markets trade on veranta. Use their current market_id values from
+ GET /v1/markets. The previous hyperliquid EUR/USD and USD/JPY markets are
+ retiring: they accept only orders that reduce or close existing positions
+ there. The historical fpx and lighter providers are retired and have no
+ markets available for new trades.
Before placing a market order, request
GET /v1/markets/{market_id}/quote?side=buy&size=... to estimate the fill. A
size-aware quote returns the projected fill price (top-of-book bounded by the
mark-based slippage cap), the maximum adverse slippage tier in basis points
(slippage_bps), notional,
fee, and whether the requested size is valid at the market's precision. The
eventual order still executes against newer authoritative market data, so
treat the quote as an estimate rather than a reserved price. The fee rate follows the market's asset category, regardless of its
source venue or venue ticker format. The quote is not tied to an account, so
its fee uses the standard rate; an
Elite account is charged its reduced rate when
the order fills. The fee and slippage schedules are published in the
SHA-256 76c5fc9dd9d063b3da9be2c11067fd7365aba4cf0d57195b1cf281d36ef0c8cd
▸Version 2October 13, 2026, 4:45 PM+27−6
Changes shown against Version 1.
Trading with the API
Source: https://docs.myfundedperpetuals.com/trading-with-api
Place and manage every order type available in the trading terminal.
The REST API uses the same order books, trading rules, fees, margin checks, and
paper execution engine as the trading terminal. Every create request requires
an Idempotency-Key header. Standard orders and position closes may also carry
a caller-assigned client_order_id for durable reconciliation.
Exposure caps
API orders share the same per-user market exposure allowance as orders placed
in the terminal. Your own accounts of the same product and size share one cap
− for each market; other users have separate allowances. Long and short notional
+ for each market; other users have separate allowances. Elite accounts are the
+ exception: each Elite account has its own cap for each market, counting only
+ that account's position. Long and short notional
add together. An opening fill that would exceed the cap is rejected with
exposure_cap, without resizing. Reductions and closes remain allowed, and
freed capacity becomes available at the next refresh, approximately 10 seconds
later. See Asset Exposure Limits.
Standard and advanced orders
Send orders to POST /v1/orders. If type is omitted, the request is treated
as a market order for compatibility with existing clients.
| type | Required price fields | Important options |
|---|
of pending and resting orders. This view is safer for reconciliation than
searching recent history.
At an hourly swap boundary, ready charges are applied before order settlement
and its balance and margin checks, without waiting for the scheduled hourly
processing window. Incomplete charge data can keep the order pending while it
is recovered. This also applies to reduce-only closes: closing after a boundary
does not remove the charge for exposure held at that boundary. See
Commissions and Fees.
For an enabled copy group, copied market orders stay pending until the lead
market order fills. If the lead rejects or expires without filling, its pending
market copies are canceled without opening follower positions or charging
trading fees. Resting limit and trigger copies, including attached TP/SL,
− execute independently on each account. See
+ execute independently on each account. Copies open on the same venue as the
+ lead order, including an alternate venue you chose for the market, and a
+ trading halt blocks new follower exposure even while a copy is in flight. A
+ copy uses the leverage you send, lowered to the follower's own maximum for
+ that market when needed, and keeps the margin mode of any position the
+ follower already holds in that market. See
Copy Trading.
Use GET /v1/orders?client_order_id=... to resolve your caller-assigned order
identity when the placement response or server id is unavailable. This lookup
survives API key rotation and returns the normal order-page shape with zero or
one result.
If the server cannot prove the snapshot is complete inside the active-order
bound, it returns 503 with Retry-After instead of returning truncated data.
- PATCH /v1/orders/{order_id} changes price and optionally size.
- PUT /v1/orders/{order_id}/attached-exits sets or removes TP/SL attached to
a resting limit entry. Send null to remove a leg.
- DELETE /v1/orders/{order_id} cancels a working order or queues cancellation
when execution already owns the row.
fill and trading rules.
GET /v1/scaled-orders/{id} returns every rung's price, size, child order ID,
and placement rejection when applicable. DELETE fences unplaced rungs and
cancels every working child.
Reconcile fills and closed positions
GET /v1/fills?account_id=... returns filled orders in settlement order with
fees, realized P\&L, notional, liquidity role, and partial-fill lineage. Use
GET /v1/positions?account_id=...&status=closed for cursor-paginated closed
position records.
Treat all cursors as opaque. Order and strategy state can continue changing
after a response, so reconcile by resource ID until it reaches a terminal
status.
+ Track evaluation progress
+ GET /v1/accounts/{account_id} returns a risk snapshot with equity, loss-limit room,
+ and the profit still needed to pass. An evaluation passes when equity,
+ including unrealized P\&L, reaches the profit target, so track
+ risk.remaining_profit_equity. When it reaches zero, the evaluation passes and
+ open positions are closed. risk.remaining_profit counts realized profit only
+ and can stay above zero while open profit already covers the target. Both are
+ null when the account has no profit target, and remaining_profit_equity is
+ also null when marks are incomplete.
Copy groups and scheduled execution
Before submitting a lead order through the API, ensure the credential covers
the lead and every follower. The same boundary applies to modifications,
cancellations, and protective exits. A scope failure rejects the complete
native order operation, preserving the copy group's behavior rather than
silently dropping a follower. See Authentication.
Accepted TWAP/VWAP and scaled orders retain the environment and account scope
that authorized them. Revoking the key blocks new requests but does not revoke
that accepted schedule. Each later slice or rung checks the current copy group
against its retained scope. If the group now includes an inaccessible account,
TWAP/VWAP stops with completion_reason: "api_account_scope_changed"; scaled
orders reject the remaining unplaced rungs with that reject_reason. Previously
parent_order_id.
A canceled order carries cancel_reason:
| cancel_reason | Meaning |
|---|
user | You canceled it, including a cancel requested while it was executing.
| oco | Its paired TP or SL filled and retired the remaining size. |
|---|
reduce_only | The position it protected closed, reversed, or became too small for it.
| replaced | A new attached TP or SL took over the size it covered. |
|---|
trading_restricted | A trading restriction on your profile canceled opening orders.
| venue_policy | The market stopped accepting new positions on this venue. |
|---|
− copy | A copy-trading lead order changed or ended, or the copy stopped applying.
+ copy | A copy-trading lead order changed or ended, the copy stopped applying, or the account started following a lead.
Treat unknown values as a generic cancellation: new reasons may be added.
Orders canceled before this field existed omit it. A closed position carries
close_reason: user, take_profit, stop_loss, liquidation, reversal,
or system.
+ A copied follower order that was still executing when its group stopped
+ because the lead account passed, failed, or closed is rejected with
+ reject_reason copy_lead_stopped; the follower's positions are then closed
+ by the copy-trading stop.
Every fill also records position_side_after (long, short, or flat) and
position_size_after, the account's position in that market immediately
after the fill. Fills from before these fields existed omit them.
GET /v1/twap-orders?account_id=... continues to return active TWAP and VWAP
parents. To discover terminal parents without retaining their IDs, request
status=completed or status=canceled. History is ordered by creation time,
newest first, within the selected status, and accepts limit (1 to 100,
default 50) and cursor. Follow next_cursor while has_more is true, keeping
account_id and status unchanged. Query both terminal statuses for a complete
history. The strategy field distinguishes TWAP from VWAP; completion_reason
explains why a completed schedule stopped. Pagination is not accepted for the
active listing.
Live market data
Use market data streaming for live prices, books, trades,
− and candles. It is public and uses a dedicated WebSocket endpoint. Continue
− using REST for account balances, positions, order state, and fills; private
− account streaming is not available.
+ and candles. It is public and uses a dedicated WebSocket endpoint. For order,
+ fill, position, and balance changes on your own accounts, use
+ account streaming, an authenticated WebSocket that pushes
+ each change as it happens. REST remains available for snapshots and lookups.
SHA-256 ec01790efd83f87ba6e7d3d73643d625f9c02e018115931787f5c0d05e1b735a
▸Version 1October 11, 2026, 2:36 PM
First archived version.
Trading with the API
Source: https://docs.myfundedperpetuals.com/trading-with-api
Place and manage every order type available in the trading terminal.
The REST API uses the same order books, trading rules, fees, margin checks, and
paper execution engine as the trading terminal. Every create request requires
an Idempotency-Key header. Standard orders and position closes may also carry
a caller-assigned client_order_id for durable reconciliation.
Exposure caps
API orders share the same per-user market exposure allowance as orders placed
in the terminal. Your own accounts of the same product and size share one cap
for each market; other users have separate allowances. Long and short notional
add together. An opening fill that would exceed the cap is rejected with
exposure_cap, without resizing. Reductions and closes remain allowed, and
freed capacity becomes available at the next refresh, approximately 10 seconds
later. See Asset Exposure Limits.
Standard and advanced orders
Send orders to POST /v1/orders. If type is omitted, the request is treated
as a market order for compatibility with existing clients.
| type | Required price fields | Important options |
|---|
| market | expected_price | slippage_tolerance_bps, attached TP/SL |
| limit | limit_price | attached TP/SL, IOC, FOK, or GTD time in force |
| chase | chase_offset | optional chase_cap_price |
| stop_market | trigger_price | optional reduce-only protection |
| stop_limit | trigger_price, limit_price | opening conditional order |
| take_market | trigger_price | opening conditional order |
| take_limit | trigger_price, limit_price | opening conditional order |
| take_profit | trigger_price, reduce_only: true | position protection |
| conditional | trigger_price, trigger_market_id, trigger_direction | observe one market and execute on another |
The server resolves provider, symbol, and venue coin from market_id. Do not
send those fields. expected_price records what your client observed, but it
never controls the execution price, margin calculation, or slippage reference.
FX markets are EUR/USD and USD/JPY, both on hyperliquid. Use their current
market_id values from GET /v1/markets. The historical fpx and lighter
providers are retired and have no markets available for new trades.
Before placing a market order, request
GET /v1/markets/{market_id}/quote?side=buy&size=... to estimate the fill. A
size-aware quote returns the projected fill price (top-of-book bounded by the
mark-based slippage cap), the maximum adverse slippage tier in basis points
(slippage_bps), notional,
fee, and whether the requested size is valid at the market's precision. The
eventual order still executes against newer authoritative market data, so
treat the quote as an estimate rather than a reserved price. The fee rate follows the market's asset category, regardless of its
source venue or venue ticker format. The quote is not tied to an account, so
its fee uses the standard rate; an
Elite account is charged its reduced rate when
the order fills. The fee and slippage schedules are published in the
Trading Guide.
Forex markets quote and fill like every other Hyperliquid market: top-of-book
bounded by the mark-based slippage cap, with the forex slippage tier as the
cap. The quote's reference_price, reference_kind, and reference_time
identify its execution reference. An estimate does not reserve a price.
Conditional trigger policy
New TP/SL and other conditional orders use Last Price on Binance, Bybit and
Hyperliquid. This is selected by the server; no new request parameter is
required. An external condition follows its trigger
market's source, while execution uses its order market's book.
Existing orders keep their original trigger policy when their price or size is
modified. Canceling and replacing an order adopts the current policy. Copied
orders, partial fills and attached TP/SL inherit the originating order's policy,
including when they are created after this update. A trigger does not guarantee
its fill price. See TP/SL behavior.
Eligible protective stop-market and take-profit market orders can use the first
recorded bid or ask at or after their touch. The accepted price stays fixed during
processing. Recent order or position changes, unavailable quote history, or a
spread outside the slippage cap retain ordinary current-quote execution. Fees,
funding charges, loss limits, and liquidation rules still apply.
This first recorded quote can be up to one second after the touch on Hyperliquid
and up to half a second on Binance and Bybit. If the gap in quote history exceeds
the venue's limit, the order uses ordinary current-quote execution.
Limit order example
bash theme={null}
curl https://developers.myfundedperpetuals.com/v1/orders
-X POST
-H "Authorization: Bearer $FP_API_KEY"
-H "Content-Type: application/json"
-H "Idempotency-Key: $(uuidgen)"
-d '{
"client_order_id": "strategy-7:entry-42",
"type": "limit",
"account_id": "YOUR_ACCOUNT_ID",
"market_id": "binance|BTCUSDT",
"side": "buy",
"size": 0.001,
"limit_price": 115000,
"leverage": 2,
"margin_mode": "cross",
"take_profit_price": 120000,
"stop_loss_price": 112000
}'
For a GTD limit, set time_in_force to gtd and provide
gtd_expires_at as a Unix timestamp in milliseconds. IOC and FOK limits use
time_in_force without an expiry.
When an order with take_profit_price or stop_loss_price adds to a position
you already hold, each attached exit is sized to the full resulting position.
Exits that already protect that position overlap it, and the fill is rejected
with rule_violation and rule exit-allocation unless the request sets
replace_overlapping_exits to true. With that flag, the fill cancels the
overlapping resting exits in the same group (stop losses for a stop loss, take
profits for a take profit) and places the new full-size exit in the same
transaction. Exits that are currently executing are never replaced; the fill
is still rejected until they settle. See
Add Take Profit and Stop Loss Orders.
A limit placed at or through the current market (a buy at or above the best
ask, a sell at or below the best bid) does not rest. It fills right away as a
standard market order, at the best opposing price under the mark-based slippage
cap and never worse than limit_price. The server rejects such an order unless
the request sets marketable_limit_acknowledged to true. A limit that rests
fills its whole size at exactly limit_price after two consecutive crossing
book checks. If the confirming check misses, the order stays open. Its first
miss can retry sooner; repeated misses wait longer between attempts. Where
faster confirmation is enabled, a fresh book showing the market strictly
beyond the resting limit can fill it immediately at limit_price. If that
book is too old, the order uses the usual confirmation checks. Exact touches
can start confirmation immediately after triggering, but still require a
newer crossing book. An interrupted attempt can return to waiting and retry;
an earlier touch alone does not authorize a fill. See
How limit orders fill.
Manage working orders
Use GET /v1/orders?account_id=...&status=working for the complete bounded set
of pending and resting orders. This view is safer for reconciliation than
searching recent history.
At an hourly swap boundary, ready charges are applied before order settlement
and its balance and margin checks, without waiting for the scheduled hourly
processing window. Incomplete charge data can keep the order pending while it
is recovered. This also applies to reduce-only closes: closing after a boundary
does not remove the charge for exposure held at that boundary. See
Commissions and Fees.
For an enabled copy group, copied market orders stay pending until the lead
market order fills. If the lead rejects or expires without filling, its pending
market copies are canceled without opening follower positions or charging
trading fees. Resting limit and trigger copies, including attached TP/SL,
execute independently on each account. See
Copy Trading.
Use GET /v1/orders?client_order_id=... to resolve your caller-assigned order
identity when the placement response or server id is unavailable. This lookup
survives API key rotation and returns the normal order-page shape with zero or
one result.
If the server cannot prove the snapshot is complete inside the active-order
bound, it returns 503 with Retry-After instead of returning truncated data.
- PATCH /v1/orders/{order_id} changes price and optionally size.
- PUT /v1/orders/{order_id}/attached-exits sets or removes TP/SL attached to
a resting limit entry. Send null to remove a leg.
- DELETE /v1/orders/{order_id} cancels a working order or queues cancellation
when execution already owns the row.
To cancel the complete ordinary-order snapshot for an account, send
POST /v1/accounts/{account_id}/cancel-all-orders with an Idempotency-Key.
It includes resting orders and armed trigger orders. An in-flight market order
can still settle, and active TWAP, VWAP, or scaled parents must be canceled
through their own endpoints. Each request advances at most five source orders,
with every source cancellation isolated in its own transaction. A 202
response includes progress and Retry-After; repeat the same request until the
operation reports completed.
Chase orders cannot be modified. Cancel the chase and place a replacement with
new offset or cap settings.
Close and protect positions
POST /v1/positions/{position_id}/close derives the closing side, leverage,
margin mode, and reduce-only flag from the current position. It supports market,
limit, and external conditional closes. Omit size for a full close. Provide
client_order_id to reconcile the resulting close order in the same way as a
standard order.
To flatten one account, send
POST /v1/accounts/{account_id}/close-all-positions with an
Idempotency-Key. The server snapshots at most 100 open positions and submits
one reduce-only market close per target, paced through the account's order
cooldown. These closes use the trading terminal's 2.5% maximum-slippage policy.
Each request advances one position and never sleeps through the account
cooldown inside the HTTP action. A 202 response includes current progress and
Retry-After; repeat the same request until the operation reports completed.
The final result contains the submitted order or rejection for every
snapshotted position.
Both account-wide endpoints persist their original target snapshot. A retry
with the same idempotency key resumes unfinished targets or returns the
completed result, even if the account state has changed. A concurrent retry
returns 409 operation_in_progress with Retry-After; wait and retry with the
same key. A different account or action cannot reuse that key.
Use PUT /v1/positions/{position_id}/exit-orders to atomically place, modify,
and cancel multiple TP/SL levels. The request includes the position size and
current exit-order snapshot you observed. A concurrent position or order change
returns 409, so fetch fresh state and rebuild the operation.
New TP and SL operations can reference each other by operation index to form an
OCO pair. A fill retires the same quantity from the paired leg: a smaller leg's
fill shrinks the larger leg, and a fill that covers the paired leg cancels it.
Manually canceling one leg leaves the other leg active and unlinked.
When a fill adds to a position, resting TP/SL orders on it grow to cover the
same share of the new size, rounded down to the market's size step. This
follows the account owner's Resize TP/SL With Position Trading setting,
which is on by default. A group is not resized when the adding order carries
its own attached exit for it. After an add, read the updated sizes from the
working-order snapshot before you build an expected_orders list.
For an isolated position, PUT /v1/positions/{position_id}/isolated-margin
sets the desired total extra_margin. Repeating the same target is safe. A
reduction uses a fresh authoritative book and rejects when it would create
unsafe liquidation risk.
TP/SL batch example
For a long position of size 0.01 with no existing protective exits, this
request creates a paired market TP and SL. Replace the prices with valid
levels above and below the current market respectively.
json theme={null}
{
"expected_position_size": 0.01,
"expected_orders": [],
"operations": [
{
"kind": "place",
"group": "tp",
"execution_type": "market",
"price": 120000,
"size": 0.01,
"oco_pair_with_operation_index": 1
},
{
"kind": "place",
"group": "sl",
"execution_type": "market",
"price": 110000,
"size": 0.01,
"oco_pair_with_operation_index": 0
}
]
}
Send this body to PUT /v1/positions/{position_id}/exit-orders. For MCP, call
replace-position-exit-orders with the same fields plus position_id.
If protective exits already exist, populate expected_orders from the current
working-order snapshot with each exit's order_id, execution_type, price,
and size. Do not send an empty snapshot for an already-protected position.
Use execution_type: "limit" for price-capped protective exits through this
batch endpoint; the ordinary create-order endpoint rejects reduce-only
stop_limit and take_limit requests.
TWAP and VWAP
Create both strategies with POST /v1/twap-orders. Set strategy to twap
or vwap, then provide the duration, slice interval, and optional randomized
timing. Optional trigger and termination prices use the same behavior as the
terminal.
The slice interval must be a whole number from 30 seconds through the smaller
of 12 hours or half the selected duration. Every schedule therefore has at
least two slices.
Read active schedules with GET /v1/twap-orders?account_id=..., inspect one
parent with GET /v1/twap-orders/{id}, and stop future slices with DELETE on
that resource. An in-flight child may still settle after cancellation begins.
Retain the parent ID returned at creation to inspect that schedule directly
throughout its lifecycle.
Scaled orders
Create a ladder with POST /v1/scaled-orders. Provide a start price, end
price, 2 to 10 rungs, and a flat, ascending, or descending distribution.
Every rung is an ordinary limit order and independently follows the platform's
fill and trading rules.
GET /v1/scaled-orders/{id} returns every rung's price, size, child order ID,
and placement rejection when applicable. DELETE fences unplaced rungs and
cancels every working child.
Reconcile fills and closed positions
GET /v1/fills?account_id=... returns filled orders in settlement order with
fees, realized P\&L, notional, liquidity role, and partial-fill lineage. Use
GET /v1/positions?account_id=...&status=closed for cursor-paginated closed
position records.
Treat all cursors as opaque. Order and strategy state can continue changing
after a response, so reconcile by resource ID until it reaches a terminal
status.
Copy groups and scheduled execution
Before submitting a lead order through the API, ensure the credential covers
the lead and every follower. The same boundary applies to modifications,
cancellations, and protective exits. A scope failure rejects the complete
native order operation, preserving the copy group's behavior rather than
silently dropping a follower. See Authentication.
Accepted TWAP/VWAP and scaled orders retain the environment and account scope
that authorized them. Revoking the key blocks new requests but does not revoke
that accepted schedule. Each later slice or rung checks the current copy group
against its retained scope. If the group now includes an inaccessible account,
TWAP/VWAP stops with completion_reason: "api_account_scope_changed"; scaled
orders reject the remaining unplaced rungs with that reject_reason. Previously
accepted child orders are not canceled, and filled positions are not closed.
Older API schedules created before scope was retained can recover their
boundary while the original key still exists. If that key has been deleted,
only the schedule's own account can be established: an enabled copy group
causes future slices or rungs to stop rather than assume broader access. Finish
or recreate an older copied schedule before deleting its original key.
Reconcile conditional orders and scheduled history
Order responses expose stop_triggered_at once a conditional limit has entered
its limit leg. Before that timestamp exists, its trigger remains armed.
triggered_at records the latest execution attempt and may change on retry.
cancel_requested_at records cancellation intent while execution can still be
in flight: reconcile the final status because a fill can win that race.
oco_sibling_order_id identifies the paired exit. Fills retire matching size
from its sibling; canceling one leg explicitly unlinks the surviving leg.
Attached TP/SL orders are linked in both directions. Once an entry fills, its
take_profit_order_id and stop_loss_order_id name the exit orders the fill
created. Each of those exits carries parent_order_id (the entry) and
bracket_role (take_profit or stop_loss). When a later fill grows an
existing exit instead of creating a new one, that exit keeps its original
parent_order_id.
A canceled order carries cancel_reason:
| cancel_reason | Meaning |
|---|
user | You canceled it, including a cancel requested while it was executing.
| oco | Its paired TP or SL filled and retired the remaining size. |
|---|
reduce_only | The position it protected closed, reversed, or became too small for it.
| replaced | A new attached TP or SL took over the size it covered. |
|---|
| liquidation | A liquidation closed the position it protected. |
| expired | Its GTD time passed while it was executing. |
| account_closed | The account passed, failed, or closed. |
trading_restricted | A trading restriction on your profile canceled opening orders.
| venue_policy | The market stopped accepting new positions on this venue. |
|---|
copy | A copy-trading lead order changed or ended, or the copy stopped applying.
Treat unknown values as a generic cancellation: new reasons may be added.
Orders canceled before this field existed omit it. A closed position carries
close_reason: user, take_profit, stop_loss, liquidation, reversal,
or system.
Every fill also records position_side_after (long, short, or flat) and
position_size_after, the account's position in that market immediately
after the fill. Fills from before these fields existed omit them.
GET /v1/twap-orders?account_id=... continues to return active TWAP and VWAP
parents. To discover terminal parents without retaining their IDs, request
status=completed or status=canceled. History is ordered by creation time,
newest first, within the selected status, and accepts limit (1 to 100,
default 50) and cursor. Follow next_cursor while has_more is true, keeping
account_id and status unchanged. Query both terminal statuses for a complete
history. The strategy field distinguishes TWAP from VWAP; completion_reason
explains why a completed schedule stopped. Pagination is not accepted for the
active listing.
Live market data
Use market data streaming for live prices, books, trades,
and candles. It is public and uses a dedicated WebSocket endpoint. Continue
using REST for account balances, positions, order state, and fills; private
account streaming is not available.
SHA-256 ef61786d9c8d34b59f529597624164c866d0d4ad502d5e5078adae3238cbbe01