Skip to main content
Builds the payload for closing an existing position. Close size is either explicit (amountRaw) or percentage-based (closePercentage).

Request Body

dex
string
required
gains or lighter.
chainId
string
required
Chain of the position (e.g., evm:42161, lighter:301).
marketId
string
required
Mobula market identifier (e.g., lighter-btc-usd).
positionId
string
Gains trade index. Required for Gains. Not used for Lighter.
closePercentage
number
Portion of the position to close, in percent (0 < value ≤ 100). Use 100 for a full close. Mutually exclusive with amountRaw.
amountRaw
number
Raw base-token amount to close. Mutually exclusive with closePercentage.
params
object
Additional DEX-specific parameters. For Gains partial closes, the API transparently injects currentCollateralRaw from the position cache when available, so you do not need to supply it.

Endpoint-specific errors

Statusmessage
400close-position payload generation failed — position not found, invalid close size, or DEX refusal

Example

Close 50% of a Gains BTC-USD long:
const endpoint = 'api/2/perp/payloads/close-position';
const timestamp = Date.now();
const signature = await wallet.signMessage(`${endpoint}-${timestamp}`);

const res = await fetch(`https://api.mobula.io/${endpoint}`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    timestamp,
    signature,
    dex: 'gains',
    chainId: 'evm:42161',
    marketId: 'gains-btc-usd',
    positionId: '12345',
    closePercentage: 50,
  }),
}).then(r => r.json());

// Forward res.data to /2/perp/execute-v2 (see Execute Perp Action)