Build create-order payload
Perps Execution
Build Create-Order Payload
Build a signed canonical payload to open a new perpetual position on Gains Network or Lighter. The response is submitted as-is to /2/perp/execute-v2.
POST
Build create-order payload
Builds the canonical order payload used by
/2/perp/execute-v2. The signer recovered from the signature field becomes the order’s user.
Request Body
Base token address, symbol, or Mobula asset id.
Quote token of the market. Semantics differ per DEX:
- Lighter — pass the ERC-20 collateral symbol (
USDC). - Gains — pass the synthetic quote (
USD). SendingUSDCreturns"No market matching base/quote".
marketId (e.g. gains-btc-usd, lighter-btc-usd) and the field is derived server-side.Leverage multiplier (e.g.,
10).true for long, false for short.true if the order must only reduce an existing position.Collateral in
quote units (e.g., USDC).One of
market, limit, stop_limit. Default market.Trigger/limit price. Required for
limit and stop_limit.Take-profit price.
Stop-loss price.
Raw position size in base-token units. If omitted, derived from
collateralAmount * leverage.Max slippage in percent.
Routing hint, not a strict filter. The router prefers the requested chains but may fall back to another supported chain if the requested market is not deployed on any of them. Example: passing
chainIds: ['evm:42161'] for a market that only exists on Base will silently return chainId: 'evm:8453'. Always trust the response chainId when broadcasting.Pass an explicit marketId (or rely on the response) for unambiguous routing.Restrict routing to
gains and/or lighter.0 = cross, 1 = isolated (DEX-specific).Referrer wallet address for fee sharing.
Force a specific Mobula market instead of routing.
Authentication
Every/2/perp/payloads/<action> endpoint verifies the caller by requiring two extra fields in the request body alongside the action parameters:
Unix timestamp in milliseconds. Must be within 30 seconds of server time. Older timestamps are rejected to prevent replay.
Hex signature (EIP-191
personal_sign) of the message `${endpoint}-${timestamp}`, where endpoint is the path of this endpoint without the leading slash (e.g., for this page: api/2/perp/payloads/<this-action>). The recovered signer address becomes the user for the request. Single-use — replay returns 403 signature already used.Authentication errors
| Status | message |
|---|---|
| 403 | timestamp expired — timestamp older than 30s |
| 403 | signature already used — replay attempt |
| 400 | zod validation failed — timestamp/signature shape invalid |
Response envelope
Every/2/perp/payloads/<action> endpoint returns the same envelope shape. You pass these fields verbatim into POST /2/perp/execute-v2 to execute the action.
Top-level shape. Successful (2xx) responses return
{ data: { ... } }. A success: true flag is only present inside the body of execute-v2’s response, not on the payload-build endpoints. Parse defensively: read body.data, then check for the action-specific fields you need (e.g. data.payloadStr).Endpoint-specific errors
| Status | message |
|---|---|
| 500 | could not build create-order payload — no DEX could build a payload for the given parameters |
Full flow — open a position end-to-end
Single example covering both DEXes (Lighter offchain-api, Gains evm-tx). The flow branches ondata.transport.
Body
application/json
Available options:
market, limit, stop_limit Available options:
gains, lighter