Skip to main content
The perpetuals trading API provides endpoints for managing cross-margin perpetual futures accounts, placing and canceling orders, monitoring positions, and retrieving trade history. All perpetuals accounts use cross-margin model where collateral is shared across all positions.

GET /perpetual/exchangeInfo

Retrieve exchange information for perpetuals markets including available markets and their details.
Authentication: Not required
maker_fee_rate and taker_fee_rate here are outdated. The values returned in exchangeInfo are static, indicative defaults and do not reflect the fees actually applied to your account (fee tiers, promotions, etc.). For the authoritative, account-specific rates always use GET /perpetual/account/market-fee-rate.
Response:
Response Fields: Status Codes:
  • 200 - Exchange information retrieved successfully
  • 500 - Internal server error

Perpetuals Calculation Formulas

For frontend display (margin ratio, break-even price, ROI %, etc.), see perpetuals-frontend-formulas-from-code.md. Key formulas:
  • Cross margin ratio: margin_ratio = total_account_equity / total_maintenance_margin (from GET /perpetual/account or GET /perpetual/accounts)
  • Break-even price: Long entry_price - realized_pnl/amount, Short entry_price + realized_pnl/amount (derived, not returned)
  • Liquidation price: Returned by API and WebSocket position_update for cross-margin positions

Historical and current funding rates for perpetual markets.

Per-market history

Retrieve the full funding-rate timeline for a single perpetual symbol. Each entry includes the funding rate, premium index, mark price, and index price at that interval. Supports cursor- or page-based pagination for long histories, with short-lived response caching for high-frequency polling.

Current-rate snapshot

Retrieve the latest funding rate for all active perpetual markets in a single call — useful for dashboards and pre-trade checks.
Endpoints, request parameters, and response schemas follow the same conventions as the rest of the Perpetuals Trading API.

List pagination

Perpetual list endpoints use opaque cursor pagination.
1

First request

Send use_cursor=true (optionally with page_size). The response returns the first page plus a next_cursor token and a has_more flag.
2

Next pages

While has_more is true, send the previous response’s next_cursor value as the cursor query parameter to fetch the following page.
3

End

When has_more is false, next_cursor is empty and there are no more pages.
Query parameters (where noted on each endpoint): Response fields: Errors: Malformed cursor400 with "error": "invalid_cursor".

GET /perpetual/account/market-fee-rate

Retrieve the effective maker/taker fee rate for a single market on a perpetuals app session.
Authentication: Required (read:futures scope)
Query Parameters: Response:
Response Fields: The response is a JSON array containing a single object for the requested market: Status Codes:
  • 200 - Account fee rate retrieved successfully
  • 400 - Missing app_session_id or market parameter
  • 401 - Authentication failed

GET /perpetual/accounts

Retrieve all perpetuals accounts for the authenticated user.
Authentication: Required
Response:
Response Fields: Status Codes:
  • 200 - Accounts retrieved successfully
  • 401 - Authentication failed
  • 500 - Internal server error

POST /perpetual/account

Create a new perpetuals account with a specified app_session_id.
Authentication: Required
> Account creation completes shortly after this call returns 200. The account does not exist immediately; poll GET /perpetual/account until it returns a result (typically a few seconds). Request Body:
Request Parameters: Response:
Response Fields: Status Codes:
  • 200 - Account creation initiated successfully
  • 400 - Invalid request parameters (missing app_session_id, invalid owner address)
  • 401 - Authentication failed
  • 403 - Forbidden (owner mismatch - trying to create account for different wallet)
  • 500 - Internal server error
Notes:
  • The app_session_id should typically match the user’s spot account ID to allow seamless transfers
  • The account becomes available shortly after this request completes
  • Attempting to create an account with an existing app_session_id will return an error

GET /perpetual/account

Retrieve detailed information for a specific perpetuals account including all balances, positions, and account-level metrics.
Authentication: Required
Query Parameters: Request:
Response:
Response Fields: Same as /perpetual/accounts response (single account object), including optional initial_leverages and transferable_balances. Note on available_balance vs transfers: The name appears in two places—(1) at the account root: aggregate balance available for new positions; (2) inside each balances[] element: available for that asset. Both include unrealized PnL (formula: total − allocated/locked + unrealized PnL). For perp→spot transfer limits, use transferable_balances (account root) or balances[].max_transfer_out per asset—these match WebSocket perpetuals_account.account_update and account for closing-fee reserve and cross-margin transfer caps. Status Codes:
  • 200 - Account retrieved successfully
  • 400 - Missing app_session_id parameter
  • 401 - Authentication failed
  • 404 - Account not found
  • 500 - Internal server error

POST /perpetual/warning/mute

Mute this perpetuals account’s liquidation warnings for 24 hours.
Authentication: Required (trade:futures scope)
Request Body:
Request Fields: Response (200):
Response Fields: Status Codes:
  • 200 - Liquidation warnings muted successfully
  • 400 - Invalid request body or missing app_session_id
  • 401 - Authentication failed
  • 404 - Account not found
  • 500 - Internal server error
  • 503 - Service temporarily unavailable

GET /perpetual/balance

Retrieve collateral balances for a specific perpetuals account.
Authentication: Required
Query Parameters: Request:
Response:
Response Fields: Status Codes:
  • 200 - Balances retrieved successfully
  • 400 - Missing app_session_id parameter
  • 401 - Authentication failed
  • 404 - Account not found
  • 500 - Internal server error

GET /perpetual/transfer-assets

Retrieve the system-level perpetual transfer asset configuration. This endpoint returns which assets are configured for spot/perps transfer at the platform level.
Only assets that are both active and marked as stablecoin are returned.
It does not represent user-level transferability (e.g., user balance availability).
Authentication: Not required (public endpoint)
Request:
Response:
Response Fields: Only assets that are both active and stablecoin are included (stablecoin flag is not repeated in the JSON). Status Codes:
  • 200 - Transfer assets retrieved successfully
  • 500 - Internal server error

GET /perpetual/transaction/history

Retrieve unified perpetual transaction history for a wallet + app session. This endpoint aggregates balance-changing events (funding payments, internal transfers, fees, realized PnL, liquidations, ADL, etc.) into a single paginated history from the user’s perspective. Each row is one (transaction_id, asset) pair:
  • Positive amount → balance increase
  • Negative amount → balance decrease
Authentication: Required
Query Parameters: type filter mapping:
  • "" (empty / omitted): User-facing types only (excludes internal order bookkeeping such as ORDER_*, DEPOSIT, WITHDRAWAL, etc.)
  • "funding_fee": Funding payments (maps to FUNDING_FEE_IN, FUNDING_FEE_OUT)
  • "transfer": Internal asset transfers (maps to TRANSFER_IN, TRANSFER_OUT)
  • "fee": Trading fee-related events (maps to FEE, FEE_WAIVER_DISTRESSED_CLOSE, POSITION_OPEN_FEE, POSITION_CLOSE_FEE)
  • "realized_pnl": Realized PnL events (maps to REALIZED_PNL)
  • "liquidation": Liquidation events (maps to LIQUIDATION, LIQUIDATION_COMPLETE)
  • "adl": ADL events (maps to ADL_COUNTERPARTY_CLOSE, ADL_TAKEN_OVER_CLOSE)
  • Compatibility note: ADL events are intentionally separated from the liquidation filter; clients that want all forced-deleveraging events should query both type=liquidation and type=adl.
Time range: start_time and end_time are applied unchanged. When bounds are omitted (or sent as 0), the backend applies a default window of the last 30 days ending at now (UTC): The time window is applied on the transaction time of each event. Request (explicit time range):
Request (default last 30 days — omit start_time and end_time; cursor first page):
Request (cursor page 2):
Response:
Pagination: Cursor only. Send use_cursor=true on the first request, then follow next_cursor while has_more is true (see List pagination). Malformed cursor400 / "error": "invalid_cursor". Response Fields: Status Codes:
  • 200 - Transaction history retrieved successfully
  • 400 - Invalid query parameters (including malformed cursor) (e.g., missing app_session_id, invalid type, malformed cursor)
  • 401 - Authentication failed
  • 500 - Internal server error

GET /perpetual/positions

Retrieve all open positions for a specific perpetuals account. Position mode: Each row’s direction is long or short (stored leg). A market may return two rows (one long, one short), since long and short legs are tracked separately.
Authentication: Required
Query Parameters: Request:
Response:
Response Fields: Status Codes:
  • 200 - Positions retrieved successfully
  • 400 - Missing app_session_id parameter
  • 401 - Authentication failed
  • 404 - Account not found
  • 500 - Internal server error

POST /perpetual/positions/close

Batch-submit market IOC close orders for every open position leg on the account that has available size greater than zero. Each leg uses the same path as POST /perpetual/order.
  • If market is omitted or empty: all matching legs across markets are closed.
  • If market is set: only positions for that market (case-insensitive match; symbol is normalized to uppercase for validation against exchange info).
  • Legs are processed with bounded parallelism (worker pool) for lower latency.
  • Safety cap: at most 50 closable legs are submitted per request; when more legs exist, the response includes remaining_count and partial=true.
Position mode: Each closable leg uses direction long or short with reduce_only: true. A market may have separate long and short legs, which are closed independently.
Authentication: Required (trade scope). Ownership of app_session_id is verified.
Request Body:
Request Fields: Response (200):
Response Fields: When there are no closable legs (all available_amount is zero), the endpoint returns 200 with positions_submitted: 0 and an explanatory message. Status Codes:
  • 200 - Request completed (check failed for partial failures)
  • 400 - Invalid JSON, missing app_session_id, or unknown market (when provided and exchange info is available)
  • 401 - Authentication failed
  • 403 - Permission denied for (wallet_address, app_session_id)
  • 404 - Perpetual account not found
  • 502 - Backend request failed
  • 503 - Service temporarily unavailable

POST /perpetual/leverage

Sets initial leverage per account and market. Order creation does not accept leverage; it is resolved from stored settings when matching orders. Use this endpoint (or the default, typically 10) before trading if you need a specific multiplier. How to read current leverage: GET /perpetual/accounts returns initial_leverages (market → leverage string). Positions and orders also expose an effective leverage field. Restrictions & behavior:
  • Open orders: Changing leverage is rejected while any open order exists for that market (error e.g. order_exists). Cancel or fill those orders first.
  • Open positions: Changing leverage is allowed. The new leverage is applied atomically: position allocated_margin is recalculated from notional ÷ leverage, and locked balance is adjusted. The call may still fail if the account does not have enough free collateral for a higher required margin, or if the new margin would fall below maintenance for a position (set_leverage_failed or a similar message).
  • Validation: leverage >= 1 is required, and leverage <= max_allowed_leverage for that market (leverage_exceeds_max).
Authentication: Required (JWT or API Key). The wallet address must be present in the auth context; ownership of app_session_id is verified.
Request Body:
Request Fields: Response (200):
Response Fields: Error responses (non-exhaustive; success is false when HTTP status is not 200): Error body (400 from business rules):
Status Codes:
  • 200 - Leverage set successfully
  • 400 - Validation or business rule failure (see table)
  • 401 - Not authenticated or missing wallet in context
  • 503 - Service temporarily unavailable
  • 500 - Internal server error

GET /perpetual/position-history

Retrieve closed position history with pagination. Only returns positions that have been fully closed. Default ordering matches sort_by=closed_at and sort_dir=desc with a stable secondary sort on internal row id.
Authentication: Required
Query Parameters: Request:
Response:
Pagination: Cursor only (see List pagination). Malformed cursor400 / invalid_cursor. Response Fields: Note: for legacy closed positions created before these fields were persisted, max_held and initial_margin can be 0, which means historical values are unavailable rather than actual zero exposure.
Note: for positions that were already open when max-held/initial-margin persistence was introduced, initial_margin reflects migration-time/live-update value rather than the original open-time margin.
Status Codes:
  • 200 - Position history retrieved successfully
  • 400 - Invalid query parameters (including malformed cursor) (e.g. unparsable time strings, opened_from after opened_to, closed_from after closed_to, invalid sort_by / sort_dir, or page_size out of 1–100 when supplied)
  • 401 - Authentication failed or missing wallet in context
  • 403 - Permission denied (authenticated wallet is not the owner of app_session_id)
  • 404 - Account not found
  • 500 - Internal server error

GET /perpetual/position-history/

Retrieve fill-level history for a single closed position (one UUID from GET /perpetual/position-history). Results are cursor-paginated over the underlying trade fills for that position (chronological order). Summary fields for the position itself are available on the list endpoint item with the same id.
Authentication: Required (JWT or API Key, read:futures scope). Owner is the authenticated wallet; must match the perpetuals account for app_session_id.
Path Parameters: Query Parameters: Pagination (cursor / next_cursor):
  • The server advances in trade execution order (executed_at ascending, then stable id tie-break).
  • next_cursor is a tuple string: <RFC3339Nano>|<uint64 trade row id> (UTC in the timestamp part). Pass it back as cursor to fetch the next window.
  • has_more is true when more trades exist after this page; when false, next_cursor is typically empty.
Request (first page):
Request (next page):
Response:
Response Fields: Status Codes:
  • 200 - Position history detail retrieved successfully
  • 400 - Missing app_session_id, missing path id, invalid page_size (non-positive when supplied), or invalid position UUID
  • 401 - Authentication failed or missing wallet in context
  • 403 - Permission denied (wallet not owner of app_session_id, or position belongs to another account)
  • 404 - Position not found (or no history payload)
  • 409 - Position is not closed (failed_precondition — open positions have no fill history on this route)
  • 500 - Internal server error (including malformed cursor in some deployments)

POST /perpetual/order

Create a new perpetuals order.
Authentication: Required
Request Body (direction is long or short):
> Position legs: Long and short legs are tracked separately. Set direction to the leg you are trading and use reduce_only to close. Request Parameters: Leverage: Also configured via POST /perpetual/leverage before the first order. Inspect GET /perpetual/accounts (initial_leverages) for current settings. > Margin mode: All perpetual positions use cross margin. Passing margin_mode in the order request is not accepted. Response:
Response Fields: Status Codes:
  • 200 - Order created successfully
  • 400 - Invalid request parameters, validation failed, or the order was rejected (e.g. insufficient margin)
  • 401 - Authentication failed
  • 500 - Internal server error
Error response (typical for 400 — validation or rejection, same family as other trading routes):
  • error: Machine-readable code (snake_case), e.g. insufficient_margin, lock_funds_rejected, validation_failed.
  • message: Human-readable detail.

DELETE /perpetual/order

Cancel an existing perpetuals order. > Known Issue: The API returns 200 with success message, but the order may remain in wait state. Cancel functionality is not reliably working.
Authentication: Required
Request Body:
Request Parameters: Response:
Status Codes:
  • 200 - Cancellation request sent successfully
  • 400 - Invalid request or missing parameters
  • 401 - Authentication failed
  • 500 - Internal server error

DELETE /perpetual/orders

Cancel all open perpetuals orders for an account, optionally limited to one market.
Authentication: Required
Request Body:
Request Fields: Behavior: The server lists open orders, then dispatches a cancellation for each one. Trigger orders in trigger_wait / trigger_triggered are also cancelled (same pattern as DELETE /perpetual/order). Response (200):
When there are no open orders:
Response Fields: Status Codes:
  • 200 - Listing and dispatch completed (check failed_count for partial publish failures)
  • 400 - Invalid JSON or missing app_session_id
  • 401 - Authentication failed
  • 500 - Failed to list open orders

GET /perpetual/orders

Retrieve perpetuals order history with pagination. Each order’s direction is stored as returned (long or short) — same idea as GET /perpetual/open_orders.
Authentication: Required
Query Parameters: Request:
Response:
Response Fields: Status Codes:
  • 200 - Orders retrieved successfully
  • 400 - Invalid query parameters (including malformed cursor)
  • 401 - Authentication failed
  • 500 - Internal server error

GET /perpetual/open_orders

Retrieve open (unfilled) perpetuals orders. Returns only orders that are currently active in the order book. direction on each row is long or short.
Authentication: Required
Query Parameters: Request:
Response:
Response Fields: Note: This endpoint only returns orders with open states (wait, pending). For complete order history including filled and cancelled orders, use /perpetual/orders. Status Codes:
  • 200 - Open orders retrieved successfully
  • 400 - Invalid query parameters (including malformed cursor)
  • 401 - Authentication failed
  • 500 - Internal server error

GET /perpetual/trades

Retrieve perpetuals trade history with pagination. Returns only the user’s own trades with privacy-focused response format.
Authentication: Required
Query Parameters: Request:
Response:
Response Fields: Note: The API response only exposes the user’s own order UUID and does not expose counterparty information for privacy reasons. User-relative flags (is_buyer, is_maker) indicate the user’s role in the trade. Status Codes:
  • 200 - Trades retrieved successfully
  • 400 - Invalid query parameters (including malformed cursor)
  • 401 - Authentication failed
  • 500 - Internal server error

GET /perpetual/funding-rate/:symbol

Retrieve the current funding rate for a specific perpetuals market, plus the previous funding interval when available.
Authentication: Not required (public endpoint)
Path Parameters: Request:
Response:
Response Fields: Status Codes:
  • 200 - Funding rate retrieved successfully
  • 400 - Invalid symbol or validation failed
  • 500 - Internal server error

GET /perpetual/funding-rates

Retrieve funding rate history with pagination.
Authentication: Not required (public endpoint)
Query Parameters: Request (cursor first page):
Request (next page):
Response:
Response Fields: Status Codes:
  • 200 - Funding rates retrieved successfully
  • 400 - Invalid query parameters (including malformed cursor)
  • 500 - Internal server error

GET /perpetual/account/funding-payments

Retrieve funding payment history for the specified app session with pagination.
Authentication: Required
Query Parameters: Request:
Response:
Response Fields: Status Codes:
  • 200 - Funding payments retrieved successfully
  • 400 - Invalid query parameters (including malformed cursor) or missing app_session_id
  • 401 - Authentication failed
  • 500 - Internal server error

GET /perpetual/position/funding-payments

Retrieve funding payment history for a specific position within the specified app session, with pagination.
Authentication: Required
Query Parameters: Request:
Response: Same format as /perpetual/account/funding-payments (array of funding payment objects with pagination metadata) Status Codes:
  • 200 - Funding payments retrieved successfully
  • 400 - Invalid query parameters (including malformed cursor) or missing position_id/app_session_id
  • 401 - Authentication failed
  • 500 - Internal server error