curl --request GET \
--url https://api.polynode.dev/v3/wallets/{address}/combos/summary \
--header 'x-api-key: <api-key>'import requests
url = "https://api.polynode.dev/v3/wallets/{address}/combos/summary"
headers = {"x-api-key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'x-api-key': '<api-key>'}};
fetch('https://api.polynode.dev/v3/wallets/{address}/combos/summary', 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.polynode.dev/v3/wallets/{address}/combos/summary",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: <api-key>"
],
]);
$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://api.polynode.dev/v3/wallets/{address}/combos/summary"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.polynode.dev/v3/wallets/{address}/combos/summary")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.polynode.dev/v3/wallets/{address}/combos/summary")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"address": "<string>",
"summary": {
"position_type": "<string>",
"wallet_address": "<string>",
"open_combo_count": 123,
"closed_combo_count": 123,
"balance_count": 123,
"realized_pnl_usdc": "<string>",
"unrealized_pnl_usdc": "<string>",
"total_pnl_usdc": "<string>",
"last_activity_at": "<string>",
"win_count": 123,
"loss_count": 123,
"resolved_count": 123,
"win_rate": "<string>"
},
"rows_returned": 123,
"position_type": "<string>",
"source": "<string>",
"elapsed_ms": 123,
"period": "<string>",
"window": {
"after": 123,
"before": 123
},
"wallets": [
{
"wallet": "<string>",
"type": "<string>"
}
]
}{
"error": "invalid_request",
"message": "period must be all, 1d, 7d, 30d, or custom."
}{
"error": "combo_window_unavailable",
"message": "Windowed combo win/loss counts are temporarily unavailable."
}Wallet Combo Summary
Get combo-only P&L, position counts, and win/loss counts for one wallet, all time or inside a time window.
curl --request GET \
--url https://api.polynode.dev/v3/wallets/{address}/combos/summary \
--header 'x-api-key: <api-key>'import requests
url = "https://api.polynode.dev/v3/wallets/{address}/combos/summary"
headers = {"x-api-key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'x-api-key': '<api-key>'}};
fetch('https://api.polynode.dev/v3/wallets/{address}/combos/summary', 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.polynode.dev/v3/wallets/{address}/combos/summary",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: <api-key>"
],
]);
$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://api.polynode.dev/v3/wallets/{address}/combos/summary"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.polynode.dev/v3/wallets/{address}/combos/summary")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.polynode.dev/v3/wallets/{address}/combos/summary")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"address": "<string>",
"summary": {
"position_type": "<string>",
"wallet_address": "<string>",
"open_combo_count": 123,
"closed_combo_count": 123,
"balance_count": 123,
"realized_pnl_usdc": "<string>",
"unrealized_pnl_usdc": "<string>",
"total_pnl_usdc": "<string>",
"last_activity_at": "<string>",
"win_count": 123,
"loss_count": 123,
"resolved_count": 123,
"win_rate": "<string>"
},
"rows_returned": 123,
"position_type": "<string>",
"source": "<string>",
"elapsed_ms": 123,
"period": "<string>",
"window": {
"after": 123,
"before": 123
},
"wallets": [
{
"wallet": "<string>",
"type": "<string>"
}
]
}{
"error": "invalid_request",
"message": "period must be all, 1d, 7d, 30d, or custom."
}{
"error": "combo_window_unavailable",
"message": "Windowed combo win/loss counts are temporarily unavailable."
}GET /v3/wallets/{address}?include_combos=true.
wallets. See Owner addresses.Request
GET /v3/wallets/{address}/combos/summary
Path parameters
| Parameter | Type | Description |
|---|---|---|
address | string | Wallet address or owner EOA |
Query parameters
All optional. They scope only the win and loss counts; see Time windows.| Parameter | Type | Default | Description |
|---|---|---|---|
period | string | all | all, 1d, 7d, 30d, or custom. 1d / 7d / 30d end now. |
after | integer | none | Window start, Unix seconds, inclusive. Requires period=custom (or no period) |
before | integer | none | Window end, Unix seconds, exclusive. Requires period=custom (or no period) |
Example
curl "https://api.polynode.dev/v3/wallets/0x8f73711ac46f9e9c7d97196889603a52bc42bb9e/combos/summary" \
-H "x-api-key: $POLYNODE_API_KEY"
{
"address": "0x8f73711ac46f9e9c7d97196889603a52bc42bb9e",
"summary": {
"position_type": "combo",
"wallet_address": "0x8f73711ac46f9e9c7d97196889603a52bc42bb9e",
"open_combo_count": 17,
"closed_combo_count": 39,
"balance_count": 56,
"realized_pnl_usdc": "1849.109086",
"unrealized_pnl_usdc": "-1046.697946",
"total_pnl_usdc": "802.411140",
"last_activity_at": "2026-10-06T22:41:31.671553+00:00",
"win_count": 39,
"loss_count": 17,
"resolved_count": 56,
"win_rate": "0.6964"
},
"rows_returned": 1,
"position_type": "combo",
"source": "v3.wallet_combos.summary"
}
Past 7 days
curl "https://api.polynode.dev/v3/wallets/0x1109da04152c38666464f5adb5d7c55618810b2c/combos/summary?period=7d" \
-H "x-api-key: $POLYNODE_API_KEY"
{
"address": "0x1109da04152c38666464f5adb5d7c55618810b2c",
"summary": {
"position_type": "combo",
"wallet_address": "0x1109da04152c38666464f5adb5d7c55618810b2c",
"open_combo_count": 10307,
"closed_combo_count": 44089,
"balance_count": 54396,
"realized_pnl_usdc": "7725995.313053",
"unrealized_pnl_usdc": "-4222707.461465",
"total_pnl_usdc": "3503287.851588",
"last_activity_at": "2026-10-27T07:39:59.108677+00:00",
"win_count": 483,
"loss_count": 0,
"resolved_count": 483,
"win_rate": "1.0000"
},
"rows_returned": 1,
"position_type": "combo",
"source": "v3.wallet_combos.summary",
"period": "7d",
"window": {
"after": 1792484127,
"before": 1793088927
}
}
Response fields
| Field | Type | Description |
|---|---|---|
open_combo_count | integer | Open combo positions |
closed_combo_count | integer | Closed combo positions |
balance_count | integer | Total combo balance rows tracked for the wallet |
realized_pnl_usdc | string | Realized combo P&L in USD |
unrealized_pnl_usdc | string or null | Current unrealized combo P&L when available |
total_pnl_usdc | string | Realized + unrealized combo P&L |
last_activity_at | string | Last observed combo activity for this wallet |
win_count | integer | Resolved combo positions the wallet won |
loss_count | integer | Resolved combo positions the wallet lost |
resolved_count | integer | win_count + loss_count |
win_rate | string or null | win_count / resolved_count as a 4-decimal fraction ("0.6964" = 69.64%); null when the wallet has no resolved combo |
| Field | Type | Description |
|---|---|---|
period | string | The requested period: 1d, 7d, 30d, or custom |
window | object | {after, before} in Unix seconds that the counts used; after inclusive, before exclusive, null when open |
Win and loss counts
A combo position is won or lost once its legs resolve: a YES position wins when every leg wins and loses as soon as any leg loses; a NO position is the reverse. The counts cover every combo position the wallet has held, all time, whether or not it was redeemed, including positions it sold or transferred before the combo resolved. Open positions are not counted. To list the positions behind the all-time counts, call Wallet Combo Positions withstatus=resolved_win, status=resolved_loss, or status=resolved (both).
That listing is not window-scoped.
Time windows
Withperiod=1d, 7d, 30d, or custom, win_count, loss_count,
resolved_count and win_rate count only the combo positions that settled
inside the window. P&L, open_combo_count, closed_combo_count,
balance_count and last_activity_at are always all time.
- A combo settles at its first payout to any holder. Both sides of a combo share that time, so a lost position is placed when the winning side was paid.
- A small share of resolved combos has no recorded payout. Their positions
count in the all-time totals but in no window, until a payout is recorded.
Most of them are losses, so a windowed
win_ratecan read slightly high. - The window is half-open:
afteris inclusive andbeforeis exclusive, like the Combo P&L Leaderboard. Wallet Combo Redemptions treatsbeforeas inclusive. - An invalid window returns 400
invalid_request, for exampleperiod=1y,period=customwith no bound,afternot less thanbefore, orwindow=7d(useperiod). Windowed counts can briefly return 503combo_window_unavailablewhen the payout data is catching up; retry, or call without a window for the all-time counts.
Owner address fields
Present only when you pass an owner EOA. See Owner addresses.| Field | Type | Description |
|---|---|---|
wallets | array | The combined wallets, in a fixed order, each {wallet, type} with type one of eoa, safe, proxy, or deposit_wallet |
win_rate is recomputed from the summed counts, and last_activity_at is the latest of them. With a window, every combined wallet uses the same window.Authorizations
Path Parameters
Wallet address, or an owner EOA to combine every Polymarket wallet it owns
^0x[a-fA-F0-9]{40}$Query Parameters
Window for the win/loss counts. All Time is the default. Custom requires after or before. Fixed periods and All Time forbid explicit bounds.
all, 1d, 7d, 30d, custom Inclusive custom lower bound in Unix seconds. Accepted only with period=custom (or no period).
0 <= x <= 9999999999Exclusive custom upper bound in Unix seconds. Accepted only with period=custom (or no period).
0 <= x <= 9999999999Response
Wallet combo summary
Show child attributes
Show child attributes
Present only with a window: 1d, 7d, 30d, or custom
Present only with a window: the bounds the counts used, after inclusive and before exclusive
Show child attributes
Show child attributes
Present only for an owner EOA: the combined wallets
Show child attributes
Show child attributes

