curl --request GET \
--url https://demo-api.mobula.io/api/2/wallet/positions/perp/openimport requests
url = "https://demo-api.mobula.io/api/2/wallet/positions/perp/open"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://demo-api.mobula.io/api/2/wallet/positions/perp/open', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://demo-api.mobula.io/api/2/wallet/positions/perp/open",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://demo-api.mobula.io/api/2/wallet/positions/perp/open"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://demo-api.mobula.io/api/2/wallet/positions/perp/open")
.asString();require 'uri'
require 'net/http'
url = URI("https://demo-api.mobula.io/api/2/wallet/positions/perp/open")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body{
"data": [
{
"id": "<string>",
"entryPriceQuote": 123,
"currentLeverage": 123,
"amountUSD": 123,
"amountRaw": 123,
"side": "BUY",
"liquidationPriceQuote": 123,
"currentPriceQuote": 123,
"realizedPnlUSD": 123,
"unrealizedPnlUSD": 123,
"realizedPnlPercent": 123,
"unrealizedPnlPercent": 123,
"tp": [
{
"size": 123,
"price": 123,
"id": 123
}
],
"sl": [
{
"size": 123,
"price": 123,
"id": 123
}
],
"marketId": "<string>",
"exchange": "gains",
"feesOpeningUSD": 123,
"feesClosingUSD": 123,
"feesFundingUSD": 123,
"openDate": "<string>",
"lastUpdate": "<string>",
"address": "<string>",
"chainId": "<string>",
"collateralAsset": "<string>"
}
]
}Get Perp Positions
Retrieve all active perpetual positions for a specific wallet.
curl --request GET \
--url https://demo-api.mobula.io/api/2/wallet/positions/perp/openimport requests
url = "https://demo-api.mobula.io/api/2/wallet/positions/perp/open"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://demo-api.mobula.io/api/2/wallet/positions/perp/open', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://demo-api.mobula.io/api/2/wallet/positions/perp/open",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://demo-api.mobula.io/api/2/wallet/positions/perp/open"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://demo-api.mobula.io/api/2/wallet/positions/perp/open")
.asString();require 'uri'
require 'net/http'
url = URI("https://demo-api.mobula.io/api/2/wallet/positions/perp/open")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body{
"data": [
{
"id": "<string>",
"entryPriceQuote": 123,
"currentLeverage": 123,
"amountUSD": 123,
"amountRaw": 123,
"side": "BUY",
"liquidationPriceQuote": 123,
"currentPriceQuote": 123,
"realizedPnlUSD": 123,
"unrealizedPnlUSD": 123,
"realizedPnlPercent": 123,
"unrealizedPnlPercent": 123,
"tp": [
{
"size": 123,
"price": 123,
"id": 123
}
],
"sl": [
{
"size": 123,
"price": 123,
"id": 123
}
],
"marketId": "<string>",
"exchange": "gains",
"feesOpeningUSD": 123,
"feesClosingUSD": 123,
"feesFundingUSD": 123,
"openDate": "<string>",
"lastUpdate": "<string>",
"address": "<string>",
"chainId": "<string>",
"collateralAsset": "<string>"
}
]
}GET /2/wallet/positions/perp/unfilled. The two endpoints share the same response shape; unfilled rows add a type: "STOP" | "LIMIT" discriminator.For live streaming, see the Perp Positions WSS channels (perp-positions-open / perp-positions-unfilled) — REST is useful as a seed before the first WSS frame arrives.Composite id format. Position ids are composite strings of the form pos-<dex>-<base>-<quote>-<collateral>-<wallet>-<tradeIndex> (e.g. pos-gains-inj-usd-usdc-0xaa00...8741-0). When closing a Gains position via /2/perp/payloads/close-position, pass only the trailing trade-index segment as a string (e.g. "0") in positionId, not the composite id.Query Parameters
evm:42161). If omitted, returns positions from all supported chains.gains, lighter. If omitted, returns positions from all supported DEXes.Response
Show PerpsPosition Object
Show PerpsPosition Object
gains, hyperliquid, gte, lighterBUY (Long) or SELL (Short)size (bigint), price (number), id (number)size (bigint), price (number), id (number)Query Parameters
Wallet address
Comma-separated list of chain IDs (e.g., "evm:1,evm:8453,solana:solana"). If omitted, all chains.
Number of positions per page (1-500, default: 100)
1 <= x <= 500Offset for pagination (default: 0)
x >= 0Cursor for cursor-based pagination (takes precedence over offset)
Cursor direction (default: after)
before, after Sort field (default: lastActivity)
lastActivity, realizedPnl Sort order (default: desc)
asc, desc Include fees in PnL calculation (deduct total_fees_paid_usd from PnL)
Include all tokens the wallet holds, not just tokens with trading history
Return only positions still held on-chain (filters out fully closed positions)
Drop positions worth less than this USD value (live RPC balance × live pool price)
x >= 0Response
Wallet perp positions response
Show child attributes
Show child attributes