Skip to main content
POST
Execute perp action
Single unified execution endpoint for every perp action. You forward the exact envelope returned by the matching /2/perp/payloads/<action> call plus a signature that proves the caller approved this specific payload at this specific timestamp.
The /2/perp/execute (v1) endpoint is deprecated. All new integrations must use /2/perp/execute-v2.

Flow

  1. Call POST /2/perp/payloads/<action> (see left-hand nav) → receive { action, dex, chainId, marketId?, transport, payloadStr }.
  2. For Gains transport: "evm-tx" only: parse payloadStr, extract payload.data, sign the EVM transaction locally → obtain signedTx.
  3. Sign the execute-v2 authentication message (see Authentication below).
  4. POST /2/perp/execute-v2 with the envelope fields, signature, timestamp, and (when required) signedTx.

Request Body

string
required
Canonical action name. One of withdraw, create-account, deposit, create-order, close-position, cancel-order, update-margin, edit-order. Must match the action inside payloadStr.
string
required
gains or lighter. Must match payloadStr.
string
required
Chain of the action. Must match payloadStr.
string
Mobula market identifier. If provided, must match payloadStr.marketId.
string
required
offchain-api — server submits to the DEX off-chain API using the user’s signature.
evm-tx — server broadcasts the user-signed EVM transaction supplied in signedTx. Must match payloadStr.
string
required
JSON-stringified canonical envelope returned by /2/perp/payloads/<action>.Envelope metadata (action, dex, chainId, transport, marketId) must be forwarded unchanged — it is cross-checked against the request fields.payload sub-fields are action-specific and some flows require mutating them before signing execute-v2:
  • deposit (Lighter route with EVM bridge steps) — sign every tx in payload.steps[].items[].data and write the hex results into payload.signedTxs as an array of strings.
  • withdraw on Lighter — sign payload.MessageToSign, set the hex result on payload.L1Sig, then delete payload.MessageToSign.
In those cases you re-stringify the envelope and use the new string everywhere: as this field, and in the execute-v2 signed message below.
number
required
Unix timestamp in milliseconds, within 30 seconds of server time.
string
required
Hex signature of the message api/2/perp/execute-v2-{timestamp}-{payloadStr}. The recovered signer address must match the payload.data.from address for actions that carry a from (e.g., create-order, close-position). Single-use: a second call with the same signature is rejected.
string
Hex-encoded single signed EVM transaction. Used for Gains single-tx actions (create-order, close-position, cancel-order, edit-order, update-margin) whose response has transport: "evm-tx". The server broadcasts it via eth_sendRawTransaction on chainId.Do not use this field for multi-tx flows (Lighter deposit bridge route) — those inject signed txs into payloadStr under payload.signedTxs instead.

Response

object

Errors

Authentication

The execute-v2 signature binds the exact payloadStr to the exact timestamp:
Rules:
  • payloadStr in the signed message is the same string you put in the request body. If the flow requires injecting fields (deposit signedTxs, Lighter withdraw L1Sig), do the injection + re-stringify before signing — sign the final string, not the original.
  • For actions whose envelope carries payload.data.from (Gains EVM txs, Lighter orders), the signer must equal from. Deposit/withdraw envelopes that don’t expose a from skip this check.
  • Signatures are single-use for 30 seconds after the timestamp.

Transport & signing matrix

The transport returned by /2/perp/payloads/<action> is authoritative — forward it as-is. What the client must sign depends on both the DEX and the action:

Body

application/json
action
enum<string>
required
Available options:
withdraw,
create-account,
deposit,
create-order,
close-position,
cancel-order,
update-margin,
edit-order
dex
enum<string>
required
Available options:
gains,
lighter
chainId
string
required
transport
enum<string>
required
Available options:
offchain-api,
evm-tx
payloadStr
string
required

JSON-stringified canonical envelope. Envelope metadata must match the request fields.

timestamp
number
required
signature
string
required

Hex signature of api/2/perp/execute-v2-{timestamp}-{payloadStr}.

marketId
string
signedTx
string

Hex-encoded single signed EVM transaction (Gains single-tx actions with transport evm-tx).

Response

200 - application/json

Perp execute response

success
boolean
required
data
object
required