Skip to main content
GET
https://api-mainnet.onzks.com
/
v1
/
trading
/
history
/
:identity
Get Trading History
curl --request GET \
  --url https://api-mainnet.onzks.com/v1/trading/history/:identity \
  --header 'Authorization: Bearer <token>'
{
  "success": true,
  "address": "<string>",
  "zksId": "<string>",
  "trades": [
    {
      "id": "<string>",
      "timestamp": "<string>",
      "type": "<string>",
      "protocol": "<string>",
      "chainId": 123,
      "transactionHash": "<string>",
      "blockNumber": 123,
      "value": "<string>",
      "volume": "<string>",
      "fees": "<string>",
      "pnl": "<string>",
      "assets": [
        {
          "symbol": "<string>",
          "name": "<string>",
          "amount": "<string>",
          "value": "<string>",
          "action": "<string>"
        }
      ],
      "metadata": {
        "gasUsed": "<string>",
        "gasPrice": "<string>",
        "slippage": 123,
        "priceImpact": 123,
        "route": [
          {}
        ]
      }
    }
  ],
  "pagination": {
    "total": 123,
    "limit": 123,
    "offset": 123,
    "hasMore": true
  },
  "summary": {
    "totalTrades": 123,
    "totalVolume": "<string>",
    "totalFees": "<string>",
    "totalPnL": "<string>",
    "winRate": 123,
    "averageTrade": "<string>"
  },
  "timestamp": "<string>"
}

Overview

Retrieve comprehensive trading history including individual trades, transactions, and performance metrics. This endpoint provides detailed transaction data perfect for building trading analytics, tax reporting, and performance tracking.
Use this endpoint to display individual trades, analyze trading patterns, generate reports, and provide detailed transaction history to users.

Parameters

identity
string
required
User identity (ZKS ID or wallet address)
ZKS ID is recommended for better performance and user experience
limit
number
Number of trades to return (default: 50, max: 1000)
offset
number
Number of trades to skip for pagination (default: 0)
timeframe
string
Time period for trades
  • 7d - Last 7 days
  • 30d - Last 30 days
  • 90d - Last 90 days
  • 1y - Last year
  • all - All time (default)
protocol
string
Filter by specific protocol
  • uniswap - Uniswap
  • sushiswap - SushiSwap
  • 1inch - 1inch
  • curve - Curve
  • balancer - Balancer
  • pancakeswap - PancakeSwap
asset
string
Filter by asset symbol (e.g., ETH, USDC, WBTC)
chainId
number
Filter by specific blockchain
  • 1 - Ethereum mainnet
  • 137 - Polygon
  • 56 - BSC
  • 42161 - Arbitrum
  • 10 - Optimism
  • 250 - Fantom
  • 43114 - Avalanche
type
string
Filter by trade type
  • swap - Token swaps
  • liquidity - Liquidity provision/removal
  • lending - Lending/borrowing
  • staking - Staking operations
  • yield - Yield farming
sortBy
string
Sort trades by field
  • timestamp - By timestamp (default)
  • value - By trade value
  • pnl - By profit/loss
  • volume - By volume
sortOrder
string
Sort order
  • desc - Descending (default)
  • asc - Ascending

Response

success
boolean
Indicates if the request was successful
address
string
Resolved wallet address
zksId
string
ZKS ID if available, null otherwise
trades
array
Array of trade objects
pagination
object
Pagination information
summary
object
Trading summary for the period
timestamp
string
ISO 8601 timestamp of the response

Examples

curl "https://api.onzks.com/v1/trading/history/alice.zks" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response Example

{
  "success": true,
  "address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
  "zksId": "alice.zks",
  "trades": [
    {
      "id": "trade_12345",
      "timestamp": "2024-01-20T15:45:00Z",
      "type": "swap",
      "protocol": "Uniswap V3",
      "chainId": 1,
      "transactionHash": "0xabcdef1234567890...",
      "blockNumber": 19000000,
      "value": "5000.00",
      "volume": "5000.00",
      "fees": "15.00",
      "pnl": "250.00",
      "assets": [
        {
          "symbol": "ETH",
          "name": "Ethereum",
          "amount": "2.0",
          "value": "5000.00",
          "action": "sell"
        },
        {
          "symbol": "USDC",
          "name": "USD Coin",
          "amount": "5000.00",
          "value": "5000.00",
          "action": "buy"
        }
      ],
      "metadata": {
        "gasUsed": "150000",
        "gasPrice": "20",
        "slippage": 0.5,
        "priceImpact": 0.1,
        "route": ["ETH", "USDC"]
      }
    },
    {
      "id": "trade_12346",
      "timestamp": "2024-01-20T14:30:00Z",
      "type": "liquidity",
      "protocol": "Uniswap V3",
      "chainId": 1,
      "transactionHash": "0x1234567890abcdef...",
      "blockNumber": 18999950,
      "value": "10000.00",
      "volume": "0.00",
      "fees": "30.00",
      "pnl": "0.00",
      "assets": [
        {
          "symbol": "ETH",
          "name": "Ethereum",
          "amount": "4.0",
          "value": "10000.00",
          "action": "add"
        },
        {
          "symbol": "USDC",
          "name": "USD Coin",
          "amount": "10000.00",
          "value": "10000.00",
          "action": "add"
        }
      ],
      "metadata": {
        "gasUsed": "200000",
        "gasPrice": "20",
        "slippage": 0.0,
        "priceImpact": 0.0,
        "route": []
      }
    },
    {
      "id": "trade_12347",
      "timestamp": "2024-01-20T13:15:00Z",
      "type": "swap",
      "protocol": "1inch",
      "chainId": 1,
      "transactionHash": "0x9876543210fedcba...",
      "blockNumber": 18999900,
      "value": "2500.00",
      "volume": "2500.00",
      "fees": "7.50",
      "pnl": "-50.00",
      "assets": [
        {
          "symbol": "USDC",
          "name": "USD Coin",
          "amount": "2500.00",
          "value": "2500.00",
          "action": "sell"
        },
        {
          "symbol": "WBTC",
          "name": "Wrapped Bitcoin",
          "amount": "0.1",
          "value": "2450.00",
          "action": "buy"
        }
      ],
      "metadata": {
        "gasUsed": "120000",
        "gasPrice": "18",
        "slippage": 1.2,
        "priceImpact": 0.3,
        "route": ["USDC", "ETH", "WBTC"]
      }
    }
  ],
  "pagination": {
    "total": 342,
    "limit": 50,
    "offset": 0,
    "hasMore": true
  },
  "summary": {
    "totalTrades": 342,
    "totalVolume": "1250000.50",
    "totalFees": "3750.00",
    "totalPnL": "125000.75",
    "winRate": 68.5,
    "averageTrade": "3654.97"
  },
  "timestamp": "2024-01-20T15:45:00Z"
}

Use Cases

1. Trading Analytics Dashboard

Create a comprehensive trading analytics dashboard:
function createTradingAnalytics(trades) {
  const analytics = {
    performance: calculatePerformance(trades),
    patterns: analyzeTradingPatterns(trades),
    assets: analyzeAssetDistribution(trades),
    protocols: analyzeProtocolUsage(trades),
    timing: analyzeTradingTiming(trades)
  };
  
  return analytics;
}

function calculatePerformance(trades) {
  const totalPnL = trades.reduce((sum, trade) => sum + parseFloat(trade.pnl), 0);
  const totalVolume = trades.reduce((sum, trade) => sum + parseFloat(trade.volume), 0);
  const totalFees = trades.reduce((sum, trade) => sum + parseFloat(trade.fees), 0);
  
  const profitableTrades = trades.filter(trade => parseFloat(trade.pnl) > 0);
  const winRate = (profitableTrades.length / trades.length) * 100;
  
  return {
    totalPnL,
    totalVolume,
    totalFees,
    winRate,
    averageTrade: totalVolume / trades.length,
    roi: (totalPnL / totalVolume) * 100
  };
}

2. Trade Analysis

Analyze individual trades:
function analyzeTrade(trade) {
  const analysis = {
    profitability: parseFloat(trade.pnl) > 0 ? 'Profitable' : 'Loss',
    efficiency: parseFloat(trade.pnl) / parseFloat(trade.value) * 100,
    gasEfficiency: parseFloat(trade.value) / parseFloat(trade.metadata.gasUsed),
    slippage: trade.metadata.slippage,
    priceImpact: trade.metadata.priceImpact
  };
  
  return analysis;
}

function findBestTrades(trades, limit = 10) {
  return trades
    .sort((a, b) => parseFloat(b.pnl) - parseFloat(a.pnl))
    .slice(0, limit);
}

function findWorstTrades(trades, limit = 10) {
  return trades
    .sort((a, b) => parseFloat(a.pnl) - parseFloat(b.pnl))
    .slice(0, limit);
}

3. Protocol Analysis

Analyze trading by protocol:
function analyzeProtocols(trades) {
  const protocolStats = {};
  
  trades.forEach(trade => {
    if (!protocolStats[trade.protocol]) {
      protocolStats[trade.protocol] = {
        trades: 0,
        volume: 0,
        pnl: 0,
        fees: 0
      };
    }
    
    protocolStats[trade.protocol].trades++;
    protocolStats[trade.protocol].volume += parseFloat(trade.volume);
    protocolStats[trade.protocol].pnl += parseFloat(trade.pnl);
    protocolStats[trade.protocol].fees += parseFloat(trade.fees);
  });
  
  return Object.entries(protocolStats).map(([protocol, stats]) => ({
    protocol,
    ...stats,
    efficiency: stats.pnl / stats.volume * 100,
    averageTrade: stats.volume / stats.trades
  }));
}

4. Asset Analysis

Analyze trading by asset:
function analyzeAssets(trades) {
  const assetStats = {};
  
  trades.forEach(trade => {
    trade.assets.forEach(asset => {
      if (!assetStats[asset.symbol]) {
        assetStats[asset.symbol] = {
          name: asset.name,
          trades: 0,
          volume: 0,
          pnl: 0,
          actions: { buy: 0, sell: 0, add: 0, remove: 0 }
        };
      }
      
      assetStats[asset.symbol].trades++;
      assetStats[asset.symbol].volume += parseFloat(asset.value);
      assetStats[asset.symbol].actions[asset.action]++;
    });
  });
  
  return Object.entries(assetStats).map(([symbol, stats]) => ({
    symbol,
    ...stats,
    averageTrade: stats.volume / stats.trades
  }));
}

5. Time-based Analysis

Analyze trading patterns over time:
function analyzeTradingTiming(trades) {
  const hourlyStats = {};
  const dailyStats = {};
  const monthlyStats = {};
  
  trades.forEach(trade => {
    const date = new Date(trade.timestamp);
    const hour = date.getHours();
    const day = date.getDay();
    const month = date.getMonth();
    
    // Hourly analysis
    if (!hourlyStats[hour]) {
      hourlyStats[hour] = { trades: 0, volume: 0, pnl: 0 };
    }
    hourlyStats[hour].trades++;
    hourlyStats[hour].volume += parseFloat(trade.volume);
    hourlyStats[hour].pnl += parseFloat(trade.pnl);
    
    // Daily analysis
    if (!dailyStats[day]) {
      dailyStats[day] = { trades: 0, volume: 0, pnl: 0 };
    }
    dailyStats[day].trades++;
    dailyStats[day].volume += parseFloat(trade.volume);
    dailyStats[day].pnl += parseFloat(trade.pnl);
    
    // Monthly analysis
    if (!monthlyStats[month]) {
      monthlyStats[month] = { trades: 0, volume: 0, pnl: 0 };
    }
    monthlyStats[month].trades++;
    monthlyStats[month].volume += parseFloat(trade.volume);
    monthlyStats[month].pnl += parseFloat(trade.pnl);
  });
  
  return {
    hourly: hourlyStats,
    daily: dailyStats,
    monthly: monthlyStats
  };
}

Best Practices

1. Pagination

Handle large trading histories with pagination:
async function getAllTradingHistory(identity, options = {}) {
  const allTrades = [];
  let offset = 0;
  const limit = 100;
  
  while (true) {
    const data = await getTradingHistory(identity, {
      ...options,
      limit,
      offset
    });
    
    allTrades.push(...data.trades);
    
    if (!data.pagination.hasMore) {
      break;
    }
    
    offset += limit;
  }
  
  return allTrades;
}

2. Filtering

Implement efficient filtering:
function filterTrades(trades, filters) {
  return trades.filter(trade => {
    if (filters.protocol && trade.protocol !== filters.protocol) return false;
    if (filters.type && trade.type !== filters.type) return false;
    if (filters.asset && !trade.assets.some(a => a.symbol === filters.asset)) return false;
    if (filters.chainId && trade.chainId !== filters.chainId) return false;
    if (filters.minValue && parseFloat(trade.value) < filters.minValue) return false;
    if (filters.maxValue && parseFloat(trade.value) > filters.maxValue) return false;
    if (filters.profitable && parseFloat(trade.pnl) <= 0) return false;
    
    return true;
  });
}

3. Caching

Cache trading history for performance:
let tradingHistoryCache = new Map();
const CACHE_TTL = 2 * 60 * 1000; // 2 minutes

async function getCachedTradingHistory(identity, options = {}) {
  const cacheKey = `${identity}-${JSON.stringify(options)}`;
  const cached = tradingHistoryCache.get(cacheKey);
  
  if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
    return cached.data;
  }
  
  const data = await getTradingHistory(identity, options);
  tradingHistoryCache.set(cacheKey, {
    data,
    timestamp: Date.now()
  });
  
  return data;
}

4. Real-time Updates

Subscribe to new trades:
function subscribeToNewTrades(identity, callback) {
  const ws = new WebSocket(`wss://api.onzks.com/v1/trading/history/${identity}/subscribe`);
  
  ws.onmessage = (event) => {
    const newTrade = JSON.parse(event.data);
    callback(newTrade);
  };
  
  return () => ws.close();
}

Troubleshooting

”No trading history found”

Cause: User has no trading activity or filters are too restrictive. Solution:
  • Remove filters to see all trades
  • Check if the user has any trading activity
  • Try a longer timeframe

”Invalid protocol”

Cause: Unsupported protocol value. Solution:
  • Use supported protocols: uniswap, sushiswap, 1inch, curve, balancer, pancakeswap
  • Check for typos

”Invalid asset”

Cause: Unsupported asset symbol. Solution:
  • Use standard asset symbols (ETH, USDC, WBTC, etc.)
  • Check for typos

Rate Limits

Trading history requests are subject to rate limits:
  • Free tier: 60 requests per minute
  • Starter tier: 300 requests per minute
  • Professional tier: 1,000 requests per minute
  • Enterprise tier: Custom limits
Implement caching to reduce API calls.