Historical Token Trades API
What you'll learn
- How to fetch historical trading data for specific tokens
- Query trade history with pagination
- Analyze trading patterns and metrics
- Track liquidity changes over time
Introduction
The Historical Token Trades API enables you to retrieve and analyze past trading activity for any token. This API is specifically designed for historical analysis of trading patterns, price movements, and liquidity changes.
Access Requirements
- Valid API key (visit https://app.callstatic.com for tier information)
- Rate limits and data access vary by subscription tier
Authentication
All requests require a Bearer token in UUID format:
Authorization: Bearer your-api-key-here
Base URL
https://api.callstaticrpc.com/pumpfun/v1
Data Structure
The API returns detailed information about token trades:
- Response Structure
{
"success": true,
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"hash": "CcC5cC2cC8cC1cC7cC3cC9cC4cC6cC2cC8cC5cC1cC7cC4c",
"timestamp": 1679616000000,
"sol_amount": 1000000000,
"token_amount": 50000000000,
"token": "BbB3bB7bB2bB9bB4bB8bB1bBb5bB2bB6bB3bB9bB4bB",
"price": 0.02,
"dex": 1,
"buyer": "AaA2aA5aA8aA4aA7aA1aA9aAa3aA6aA2aA8aA5aA1a",
"virtual_sol_reserves": 100000000000,
"virtual_token_reserves": 5000000000000,
"real_sol_reserves": 98000000000,
"real_token_reserves": 5100000000000,
"is_buy": true
}
],
"has_more": false,
"total": 1
}
- TypeScript
- Python
import axios from 'axios';
interface Trade {
id: string;
hash: string;
timestamp: number;
sol_amount: number;
token_amount: number;
token: string;
price: number;
dex: 1 | 2; // 1 for PumpFun, 2 for Raydium
buyer: string;
virtual_sol_reserves: number;
virtual_token_reserves: number;
real_sol_reserves: number;
real_token_reserves: number;
is_buy: boolean;
}
interface PaginatedResponse {
success: boolean;
data: Trade[];
has_more: boolean;
total: number;
}
class TokenTradesClient {
private readonly baseUrl = 'https://api.callstaticrpc.com/pumpfun/v1';
constructor(private readonly apiKey: string) {}
async getTokenTrades(params: {
token: string;
limit?: number;
offset?: number;
}): Promise<PaginatedResponse> {
const response = await axios.get(`${this.baseUrl}/historical/trades/byToken`, {
headers: {
Authorization: `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
},
params
});
return response.data;
}
async getAllTokenTrades(token: string): Promise<Trade[]> {
let allTrades: Trade[] = [];
let offset = 0;
const limit = 100;
while (true) {
const response = await this.getTokenTrades({
token,
limit,
offset
});
allTrades = [...allTrades, ...response.data];
if (!response.has_more) break;
offset += limit;
}
return allTrades;
}
}
from typing import List, Dict, Any
import requests
class TokenTradesClient:
def __init__(self, api_key: str):
self.base_url = "https://api.callstaticrpc.com/pumpfun/v1"
self.api_key = api_key
def get_token_trades(
self,
token: str,
limit: int = None,
offset: int = None
) -> Dict[str, Any]:
response = requests.get(
f"{self.base_url}/historical/trades/byToken",
headers={
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
},
params={
"token": token,
"limit": limit,
"offset": offset
}
)
response.raise_for_status()
return response.json()
def get_all_token_trades(self, token: str) -> List[Dict[str, Any]]:
all_trades = []
offset = 0
limit = 100
while True:
response = self.get_token_trades(
token=token,
limit=limit,
offset=offset
)
all_trades.extend(response["data"])
if not response["has_more"]:
break
offset += limit
return all_trades
Analysis Examples
Here are some common analysis scenarios using the historical trades data:
- TypeScript
async function analyzePriceMovement(token: string) {
const client = new TokenTradesClient('your-api-key');
const trades = await client.getAllTokenTrades(token);
return {
totalTrades: trades.length,
volumeInSol: trades.reduce((sum, trade) => sum + trade.sol_amount, 0),
averagePrice: trades.reduce((sum, trade) => sum + trade.price, 0) / trades.length,
priceRange: {
min: Math.min(...trades.map(t => t.price)),
max: Math.max(...trades.map(t => t.price))
},
buyCount: trades.filter(t => t.is_buy).length,
sellCount: trades.filter(t => !t.is_buy).length
};
}
async function analyzeLiquidityChanges(token: string) {
const client = new TokenTradesClient('your-api-key');
const trades = await client.getAllTokenTrades(token);
return trades.map(trade => ({
timestamp: new Date(trade.timestamp),
virtualLiquidity: {
sol: trade.virtual_sol_reserves,
token: trade.virtual_token_reserves
},
realLiquidity: {
sol: trade.real_sol_reserves,
token: trade.real_token_reserves
},
divergence: {
sol: trade.virtual_sol_reserves - trade.real_sol_reserves,
token: trade.virtual_token_reserves - trade.real_token_reserves
}
}));
}
Error Handling
The API returns standard HTTP status codes:
Status Code | Description |
---|---|
200 | Successful response |
400 | Bad request |
401 | Unauthorized - Invalid or missing bearer token |
500 | Internal server error |
Best Practices
-
Implement Pagination
- Use the
limit
andoffset
parameters for large datasets - Default to reasonable page sizes (e.g., 100 records)
- Handle the
has_more
flag to determine if more data is available
- Use the
-
Error Handling
try {
const trades = await client.getTokenTrades({
token: "BbB3...",
});
} catch (error) {
if (error.response?.status === 401) {
console.error("Invalid API key");
} else if (error.response?.status === 400) {
console.error("Invalid parameters");
}
}
- Rate Limiting
- Implement exponential backoff for retry logic
- Monitor your API usage through the dashboard
- Consider caching frequently accessed data
Next Steps
Now that you understand how to analyze historical token trading data, you can:
- 📊 Build trading analytics dashboards
- 🔍 Track price movements and volatility
- 📈 Monitor liquidity changes
- 🏷️ Analyze trading patterns
Real-time Data
For real-time trade notifications, check out our WebSocket Streams API documentation.
Need Help?
For additional support:
- Email us at [email protected]
- Visit our Support Portal