curl --request GET \
--url https://data.gravia.trade/api/v1/users/trades/markouts \
--header 'Authorization: <api-key>'import requests
url = "https://data.gravia.trade/api/v1/users/trades/markouts"
headers = {"Authorization": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: '<api-key>'}};
fetch('https://data.gravia.trade/api/v1/users/trades/markouts', 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://data.gravia.trade/api/v1/users/trades/markouts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: <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://data.gravia.trade/api/v1/users/trades/markouts"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "<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://data.gravia.trade/api/v1/users/trades/markouts")
.header("Authorization", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://data.gravia.trade/api/v1/users/trades/markouts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"user_address": "0x00000000000000000000000000000000000000ab",
"trades": [
{
"id": "trd_wvYmqmI0t7nA1xK9z4zQGkQe",
"timestamp": "2026-07-15T06:12:34.123Z",
"transaction_hash": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"market": {
"id": "42",
"condition_id": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"slug": "sample-market",
"question": "Will the sample event happen?"
},
"outcome": {
"token_id": "123456789",
"name": "Yes"
},
"side": "buy",
"role": "taker",
"quantity": 25,
"price": 0.4,
"value_usdc": 10,
"fee_usdc": 0.02,
"markouts": [
{
"horizon": "5s",
"status": "available",
"evaluated_at": "2026-07-15T06:12:39.123Z",
"mark_price": 0.406,
"pnl_usdc": 0.15,
"excursion": {
"best_price": 0.41,
"best_pnl_usdc": 0.25,
"worst_price": 0.396,
"worst_pnl_usdc": -0.1
}
},
{
"horizon": "15s",
"status": "available",
"evaluated_at": "2026-07-15T06:12:49.123Z",
"mark_price": 0.408,
"pnl_usdc": 0.2,
"excursion": {
"best_price": 0.416,
"best_pnl_usdc": 0.4,
"worst_price": 0.396,
"worst_pnl_usdc": -0.1
}
},
{
"horizon": "30s",
"status": "available",
"evaluated_at": "2026-07-15T06:13:04.123Z",
"mark_price": 0.412,
"pnl_usdc": 0.3,
"excursion": {
"best_price": 0.42,
"best_pnl_usdc": 0.5,
"worst_price": 0.396,
"worst_pnl_usdc": -0.1
}
},
{
"horizon": "60s",
"status": "available",
"evaluated_at": "2026-07-15T06:13:34.123Z",
"mark_price": 0.416,
"pnl_usdc": 0.4,
"excursion": {
"best_price": 0.424,
"best_pnl_usdc": 0.6,
"worst_price": 0.396,
"worst_pnl_usdc": -0.1
}
},
{
"horizon": "180s",
"status": "available",
"evaluated_at": "2026-07-15T06:15:34.123Z",
"mark_price": 0.42,
"pnl_usdc": 0.5,
"excursion": {
"best_price": 0.432,
"best_pnl_usdc": 0.8,
"worst_price": 0.392,
"worst_pnl_usdc": -0.2
}
},
{
"horizon": "5m",
"status": "available",
"evaluated_at": "2026-07-15T06:17:34.123Z",
"mark_price": 0.43,
"pnl_usdc": 0.75,
"excursion": {
"best_price": 0.44,
"best_pnl_usdc": 1,
"worst_price": 0.39,
"worst_pnl_usdc": -0.25
}
}
],
"terminal_markout": {
"status": "resolved",
"price": 1,
"pnl_usdc": 15
},
"counterparties": [
{
"address": "0x00000000000000000000000000000000000000cd",
"match_type": "swap",
"quantity": 25,
"value_usdc": 10
}
]
}
],
"page": {
"has_more": false
}
}{
"error": {
"code": "invalid_request",
"message": "user is required",
"request_id": "01f6c90f31d24db3a25c7dba6ca071ee"
}
}{
"error": {
"code": "invalid_request",
"message": "user is required",
"request_id": "01f6c90f31d24db3a25c7dba6ca071ee"
}
}{
"error": {
"code": "invalid_request",
"message": "user is required",
"request_id": "01f6c90f31d24db3a25c7dba6ca071ee"
}
}{
"error": {
"code": "rate_limit_exceeded",
"message": "rate limit exceeded",
"request_id": "01f6c90f31d24db3a25c7dba6ca071ee"
}
}{
"error": {
"code": "invalid_request",
"message": "user is required",
"request_id": "01f6c90f31d24db3a25c7dba6ca071ee"
}
}{
"error": {
"code": "invalid_request",
"message": "user is required",
"request_id": "01f6c90f31d24db3a25c7dba6ca071ee"
}
}Get a user's trades with markouts
Resolves a wallet address or Polymarket username and returns the user’s newest trades with trade-tape markouts.
A markout estimates the trade’s hypothetical unrealized PnL if the
position were valued at a fixed time after execution; it is not
realized PnL. At each horizon, mark_price is the latest token
trade-tape VWAP at or before timestamp + horizon. pnl_usdc is
side-adjusted from the user’s perspective: for a buy it is
quantity * (mark_price - trade price), and for a sell it is
quantity * (trade price - mark_price). Positive values therefore
mean the market moved in the user’s favor. Fees are not included.
best_pnl_usdc and worst_pnl_usdc are the most favorable and least
favorable side-adjusted PnL observed on the tape after execution and
through that horizon. They describe the trade’s intrahorizon upside
and downside excursions; they are not confidence bounds. For a buy,
the highest observed price produces best PnL and the lowest produces
worst PnL; for a sell, that relationship is reversed.
terminal_markout uses the market payout when resolved, or the latest
available tape mark when still open. Structural economic
counterparties are included only when explicitly requested.
curl --request GET \
--url https://data.gravia.trade/api/v1/users/trades/markouts \
--header 'Authorization: <api-key>'import requests
url = "https://data.gravia.trade/api/v1/users/trades/markouts"
headers = {"Authorization": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: '<api-key>'}};
fetch('https://data.gravia.trade/api/v1/users/trades/markouts', 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://data.gravia.trade/api/v1/users/trades/markouts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: <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://data.gravia.trade/api/v1/users/trades/markouts"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "<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://data.gravia.trade/api/v1/users/trades/markouts")
.header("Authorization", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://data.gravia.trade/api/v1/users/trades/markouts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"user_address": "0x00000000000000000000000000000000000000ab",
"trades": [
{
"id": "trd_wvYmqmI0t7nA1xK9z4zQGkQe",
"timestamp": "2026-07-15T06:12:34.123Z",
"transaction_hash": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"market": {
"id": "42",
"condition_id": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"slug": "sample-market",
"question": "Will the sample event happen?"
},
"outcome": {
"token_id": "123456789",
"name": "Yes"
},
"side": "buy",
"role": "taker",
"quantity": 25,
"price": 0.4,
"value_usdc": 10,
"fee_usdc": 0.02,
"markouts": [
{
"horizon": "5s",
"status": "available",
"evaluated_at": "2026-07-15T06:12:39.123Z",
"mark_price": 0.406,
"pnl_usdc": 0.15,
"excursion": {
"best_price": 0.41,
"best_pnl_usdc": 0.25,
"worst_price": 0.396,
"worst_pnl_usdc": -0.1
}
},
{
"horizon": "15s",
"status": "available",
"evaluated_at": "2026-07-15T06:12:49.123Z",
"mark_price": 0.408,
"pnl_usdc": 0.2,
"excursion": {
"best_price": 0.416,
"best_pnl_usdc": 0.4,
"worst_price": 0.396,
"worst_pnl_usdc": -0.1
}
},
{
"horizon": "30s",
"status": "available",
"evaluated_at": "2026-07-15T06:13:04.123Z",
"mark_price": 0.412,
"pnl_usdc": 0.3,
"excursion": {
"best_price": 0.42,
"best_pnl_usdc": 0.5,
"worst_price": 0.396,
"worst_pnl_usdc": -0.1
}
},
{
"horizon": "60s",
"status": "available",
"evaluated_at": "2026-07-15T06:13:34.123Z",
"mark_price": 0.416,
"pnl_usdc": 0.4,
"excursion": {
"best_price": 0.424,
"best_pnl_usdc": 0.6,
"worst_price": 0.396,
"worst_pnl_usdc": -0.1
}
},
{
"horizon": "180s",
"status": "available",
"evaluated_at": "2026-07-15T06:15:34.123Z",
"mark_price": 0.42,
"pnl_usdc": 0.5,
"excursion": {
"best_price": 0.432,
"best_pnl_usdc": 0.8,
"worst_price": 0.392,
"worst_pnl_usdc": -0.2
}
},
{
"horizon": "5m",
"status": "available",
"evaluated_at": "2026-07-15T06:17:34.123Z",
"mark_price": 0.43,
"pnl_usdc": 0.75,
"excursion": {
"best_price": 0.44,
"best_pnl_usdc": 1,
"worst_price": 0.39,
"worst_pnl_usdc": -0.25
}
}
],
"terminal_markout": {
"status": "resolved",
"price": 1,
"pnl_usdc": 15
},
"counterparties": [
{
"address": "0x00000000000000000000000000000000000000cd",
"match_type": "swap",
"quantity": 25,
"value_usdc": 10
}
]
}
],
"page": {
"has_more": false
}
}{
"error": {
"code": "invalid_request",
"message": "user is required",
"request_id": "01f6c90f31d24db3a25c7dba6ca071ee"
}
}{
"error": {
"code": "invalid_request",
"message": "user is required",
"request_id": "01f6c90f31d24db3a25c7dba6ca071ee"
}
}{
"error": {
"code": "invalid_request",
"message": "user is required",
"request_id": "01f6c90f31d24db3a25c7dba6ca071ee"
}
}{
"error": {
"code": "rate_limit_exceeded",
"message": "rate limit exceeded",
"request_id": "01f6c90f31d24db3a25c7dba6ca071ee"
}
}{
"error": {
"code": "invalid_request",
"message": "user is required",
"request_id": "01f6c90f31d24db3a25c7dba6ca071ee"
}
}{
"error": {
"code": "invalid_request",
"message": "user is required",
"request_id": "01f6c90f31d24db3a25c7dba6ca071ee"
}
}Authorizations
Raw database-backed API key.
Query Parameters
A 20-byte 0x wallet address, @username, or bare Polymarket username.
1 - 255Restrict results by up to 20 comma-separated selectors: market
slugs, 0x-prefixed condition IDs, decimal outcome token IDs, or
category:<dotted-slug>. Mixed selectors are ORed. Exact market
identifiers do not expand to grouped markets; category parents
include descendants through inherited category membership.
5299Restrict results to one decimal outcome token ID.
^[0-9]+$1 <= x <= 100Opaque cursor returned by the previous page.
Include structurally identified economic counterparties on each trade.