curl --request POST \
--url https://api.portalhq.io/api/v3/clients/me/integrations/yield-xyz-perps/positions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"address": "0x1234567890abcdef1234567890abcdef12345678",
"providerId": "hyperliquid",
"providerIds": [
"<string>"
]
}
'import requests
url = "https://api.portalhq.io/api/v3/clients/me/integrations/yield-xyz-perps/positions"
payload = {
"address": "0x1234567890abcdef1234567890abcdef12345678",
"providerId": "hyperliquid",
"providerIds": ["<string>"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
address: '0x1234567890abcdef1234567890abcdef12345678',
providerId: 'hyperliquid',
providerIds: ['<string>']
})
};
fetch('https://api.portalhq.io/api/v3/clients/me/integrations/yield-xyz-perps/positions', 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://api.portalhq.io/api/v3/clients/me/integrations/yield-xyz-perps/positions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'address' => '0x1234567890abcdef1234567890abcdef12345678',
'providerId' => 'hyperliquid',
'providerIds' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.portalhq.io/api/v3/clients/me/integrations/yield-xyz-perps/positions"
payload := strings.NewReader("{\n \"address\": \"0x1234567890abcdef1234567890abcdef12345678\",\n \"providerId\": \"hyperliquid\",\n \"providerIds\": [\n \"<string>\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.portalhq.io/api/v3/clients/me/integrations/yield-xyz-perps/positions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"address\": \"0x1234567890abcdef1234567890abcdef12345678\",\n \"providerId\": \"hyperliquid\",\n \"providerIds\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.portalhq.io/api/v3/clients/me/integrations/yield-xyz-perps/positions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"address\": \"0x1234567890abcdef1234567890abcdef12345678\",\n \"providerId\": \"hyperliquid\",\n \"providerIds\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"data": [
{
"marketId": "hyperliquid-eth-usdc",
"side": "long",
"size": "0.215",
"entryPrice": 4000,
"markPrice": 3975,
"leverage": 20,
"marginMode": "isolated",
"margin": 43,
"unrealizedPnl": 5.38,
"funding": -1.24,
"liquidationPrice": 4200,
"pendingActions": [
{
"type": "close",
"label": "Close Position",
"args": {
"marketId": "hyperliquid-eth-usdc",
"side": "long",
"amount": "100",
"size": "1000",
"leverage": 10,
"marginMode": "isolated",
"limitPrice": 3900,
"stopLossPrice": 3600,
"takeProfitPrice": 4400,
"orderId": "12345",
"orderIds": [
"<string>"
],
"assetIndex": 1,
"fromToken": {
"network": "eip155:42161",
"address": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831"
},
"agentAddress": "0x1234567890abcdef1234567890abcdef12345678",
"agentName": "my-app",
"validUntil": 1767225600,
"stopLossOrderId": "12346",
"takeProfitOrderId": "12347",
"skipApproval": false,
"fundingMethod": "bridge2",
"enabled": true
}
}
]
}
]
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "yield-xyz-borrow returned a response for GET /v1/positions that does not match the expected schema",
"id": "INTEGRATION_RESPONSE_SCHEMA_DRIFT",
"details": {
"integration": "yield-xyz-borrow",
"endpoint": "GET /v1/positions",
"issues": [
{
"path": "supplyBalances.0.balanceUsd",
"message": "Expected string, received number",
"code": "invalid_type"
}
]
}
}{
"error": "<string>"
}Get positions
Get a wallet’s open positions on one or more venues (size, entry/mark price, leverage, margin, unrealised PnL, funding and liquidation price), each with its available pending actions.
This is a proxy to the Yield.xyz Perps POST /v1/positions endpoint. Portal validates the upstream response against the schema documented here before returning it under data. If Yield.xyz changes the response shape, Portal returns a 500 with id: INTEGRATION_RESPONSE_SCHEMA_DRIFT instead of a partial response. Upstream reference: Yield.xyz Perps API.
curl --request POST \
--url https://api.portalhq.io/api/v3/clients/me/integrations/yield-xyz-perps/positions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"address": "0x1234567890abcdef1234567890abcdef12345678",
"providerId": "hyperliquid",
"providerIds": [
"<string>"
]
}
'import requests
url = "https://api.portalhq.io/api/v3/clients/me/integrations/yield-xyz-perps/positions"
payload = {
"address": "0x1234567890abcdef1234567890abcdef12345678",
"providerId": "hyperliquid",
"providerIds": ["<string>"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
address: '0x1234567890abcdef1234567890abcdef12345678',
providerId: 'hyperliquid',
providerIds: ['<string>']
})
};
fetch('https://api.portalhq.io/api/v3/clients/me/integrations/yield-xyz-perps/positions', 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://api.portalhq.io/api/v3/clients/me/integrations/yield-xyz-perps/positions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'address' => '0x1234567890abcdef1234567890abcdef12345678',
'providerId' => 'hyperliquid',
'providerIds' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.portalhq.io/api/v3/clients/me/integrations/yield-xyz-perps/positions"
payload := strings.NewReader("{\n \"address\": \"0x1234567890abcdef1234567890abcdef12345678\",\n \"providerId\": \"hyperliquid\",\n \"providerIds\": [\n \"<string>\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.portalhq.io/api/v3/clients/me/integrations/yield-xyz-perps/positions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"address\": \"0x1234567890abcdef1234567890abcdef12345678\",\n \"providerId\": \"hyperliquid\",\n \"providerIds\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.portalhq.io/api/v3/clients/me/integrations/yield-xyz-perps/positions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"address\": \"0x1234567890abcdef1234567890abcdef12345678\",\n \"providerId\": \"hyperliquid\",\n \"providerIds\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"data": [
{
"marketId": "hyperliquid-eth-usdc",
"side": "long",
"size": "0.215",
"entryPrice": 4000,
"markPrice": 3975,
"leverage": 20,
"marginMode": "isolated",
"margin": 43,
"unrealizedPnl": 5.38,
"funding": -1.24,
"liquidationPrice": 4200,
"pendingActions": [
{
"type": "close",
"label": "Close Position",
"args": {
"marketId": "hyperliquid-eth-usdc",
"side": "long",
"amount": "100",
"size": "1000",
"leverage": 10,
"marginMode": "isolated",
"limitPrice": 3900,
"stopLossPrice": 3600,
"takeProfitPrice": 4400,
"orderId": "12345",
"orderIds": [
"<string>"
],
"assetIndex": 1,
"fromToken": {
"network": "eip155:42161",
"address": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831"
},
"agentAddress": "0x1234567890abcdef1234567890abcdef12345678",
"agentName": "my-app",
"validUntil": 1767225600,
"stopLossOrderId": "12346",
"takeProfitOrderId": "12347",
"skipApproval": false,
"fundingMethod": "bridge2",
"enabled": true
}
}
]
}
]
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "yield-xyz-borrow returned a response for GET /v1/positions that does not match the expected schema",
"id": "INTEGRATION_RESPONSE_SCHEMA_DRIFT",
"details": {
"integration": "yield-xyz-borrow",
"endpoint": "GET /v1/positions",
"issues": [
{
"path": "supplyBalances.0.balanceUsd",
"message": "Expected string, received number",
"code": "invalid_type"
}
]
}
}{
"error": "<string>"
}Authorizations
Client API Key or Client Session Token (CST). Pass as a Bearer token in the Authorization header.
Body
- Option 1
- Option 2
Portfolio request body for positions and orders. address is required and at least one of providerId or providerIds must be present.
Response
Open positions
Show child attributes
Show child attributes
Was this page helpful?