> ## Documentation Index
> Fetch the complete documentation index at: https://docs.myfundedperpetuals.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Trading with the 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.

## 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 `lighter`. Use their current
`market_id` values from `GET /v1/markets`. The historical `fpx`
provider is retired and has 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 (the mark price adjusted by
the size-based slippage tier), the applied slippage in basis points, notional,
fee, and whether the requested size is valid at the market's precision. The
eventual order still executes against newer authoritative market data after the
anti-arbitrage delay, 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 fee and slippage schedules are
published in the
[Trading Guide](/guides/trading-guide#how-market-orders-fill).

For Lighter forex, the projected and eventual market fills use the venue mark
plus the published slippage tier. The quote's `bid`, `ask`, and `mid` fields
continue to describe the order book; `mid` is not the fill reference for these
markets. Execution requires a fresh mark from a newer generation than the one
observed after the order was committed.

## 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.

## 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.

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 partial fill shrinks
that leg and a full fill cancels it. Manually canceling one leg leaves the
other leg active and unlinked.

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](/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.

`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](/market-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.
