Historical Holders & Transfers
Track token holder count and transfer volume trends over time. This data is essential for growth analysis, adoption metrics, and detecting accumulation or distribution phases before they're reflected in price.
Why Historical Holder Data Matters
Holder count is one of the most important leading indicators for token health:
- Growing holders often precede price appreciation as adoption increases
- Declining holders can signal distribution or loss of interest
- Volume spikes may indicate whale activity or upcoming volatility
- Holder velocity (rate of change) reveals momentum
Unlike price data which reacts instantly to trades, holder metrics move more slowly and can provide early signals of fundamental shifts in a token's community.
Endpoints
| Endpoint | Description |
|---|---|
GET /tokens/{mint}/holders-ts | Holder count over time |
GET /tokens/{mint}/volume-ts | Transfer volume over time |
Holder Count History
Track how many unique addresses hold a token over time.
Parameters
| Parameter | Type | Description |
|---|---|---|
mintAddress | string | Token mint public key (required) |
interval | string | Time granularity: day or hour |
startTime | number | Start of range (Unix timestamp) |
endTime | number | End of range (Unix timestamp) |
limit | number | Results per page |
page | number | Page number (0-indexed) |
Example Request
curl "https://api.vybenetwork.com/tokens/DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263/holders-ts?interval=day&limit=30" \
-H "X-API-Key: YOUR_API_KEY"Example Response
{
"mintAddress": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
"symbol": "BONK",
"data": [
{
"timestamp": "2024-01-15T00:00:00Z",
"holderCount": 892345,
"change": 1234
},
{
"timestamp": "2024-01-14T00:00:00Z",
"holderCount": 891111,
"change": 2345
}
]
}Response Fields
| Field | Description |
|---|---|
timestamp | Date/time of the snapshot |
holderCount | Total unique holders at this time |
change | Net change from previous period |
Volume History
Track transfer volume in USD over time—useful for identifying periods of high activity.
Parameters
| Parameter | Type | Description |
|---|---|---|
mintAddress | string | Token mint public key (required) |
interval | string | Time granularity: day or hour |
startTime | number | Start of range (Unix timestamp) |
endTime | number | End of range (Unix timestamp) |
limit | number | Results per page |
page | number | Page number (0-indexed) |
Example Request
curl "https://api.vybenetwork.com/tokens/DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263/volume-ts?interval=day&limit=30" \
-H "X-API-Key: YOUR_API_KEY"Example Response
{
"mintAddress": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
"symbol": "BONK",
"data": [
{
"timestamp": "2024-01-15T00:00:00Z",
"volumeUsd": "12345678.90",
"transactionCount": 45678
},
{
"timestamp": "2024-01-14T00:00:00Z",
"volumeUsd": "10234567.89",
"transactionCount": 42345
}
]
}Common Use Cases
| Use Case | Implementation |
|---|---|
| Growth Charts | Plot holder count for token dashboards |
| Adoption Metrics | Track daily new holders for reports |
| Volume Analysis | Identify unusual activity periods |
| Research Reports | Historical data for due diligence |
| Alert Systems | Trigger on growth rate changes |
| Trend Detection | Find tokens with accelerating adoption |
Growth Analysis Example
Calculate comprehensive growth metrics:
async function analyzeTokenGrowth(mintAddress, days = 30) {
const response = await fetch(
`https://api.vybenetwork.com/tokens/${mintAddress}/holders-ts?interval=day&limit=${days}`,
{ headers: { "X-API-Key": API_KEY } }
);
const { data, symbol } = await response.json();
// Sort chronologically (oldest first)
const sorted = [...data].reverse();
// Basic metrics
const startHolders = sorted[0].holderCount;
const endHolders = sorted[sorted.length - 1].holderCount;
const totalGrowth = endHolders - startHolders;
const percentGrowth = ((totalGrowth / startHolders) * 100);
const avgDaily = totalGrowth / days;
// Best and worst days
const bestDay = sorted.reduce((max, d) => d.change > max.change ? d : max);
const worstDay = sorted.reduce((min, d) => d.change < min.change ? d : min);
// Growth velocity (is growth accelerating or slowing?)
const firstHalf = sorted.slice(0, Math.floor(days / 2));
const secondHalf = sorted.slice(Math.floor(days / 2));
const firstHalfGrowth = firstHalf.reduce((sum, d) => sum + d.change, 0);
const secondHalfGrowth = secondHalf.reduce((sum, d) => sum + d.change, 0);
const accelerating = secondHalfGrowth > firstHalfGrowth;
return {
symbol,
period: `${days} days`,
startHolders: startHolders.toLocaleString(),
endHolders: endHolders.toLocaleString(),
totalGrowth: totalGrowth.toLocaleString(),
percentGrowth: `${percentGrowth.toFixed(2)}%`,
avgDailyGrowth: Math.round(avgDaily).toLocaleString(),
bestDay: {
date: bestDay.timestamp.split('T')[0],
added: bestDay.change.toLocaleString()
},
worstDay: {
date: worstDay.timestamp.split('T')[0],
added: worstDay.change.toLocaleString()
},
momentum: accelerating ? "Accelerating 📈" : "Decelerating 📉"
};
}Volume Trend Chart
Build a volume chart for your token dashboard:
async function getVolumeChart(mintAddress, days = 30) {
const response = await fetch(
`https://api.vybenetwork.com/tokens/${mintAddress}/volume-ts?interval=day&limit=${days}`,
{ headers: { "X-API-Key": API_KEY } }
);
const { data } = await response.json();
// Format for charting library (Chart.js, Recharts, etc.)
const chartData = data.reverse().map(d => ({
date: new Date(d.timestamp),
label: d.timestamp.split('T')[0],
volume: parseFloat(d.volumeUsd),
transactions: d.transactionCount
}));
// Calculate moving average
const movingAvg = chartData.map((point, i) => {
const window = chartData.slice(Math.max(0, i - 6), i + 1);
const avg = window.reduce((sum, p) => sum + p.volume, 0) / window.length;
return { ...point, movingAvg: avg };
});
return movingAvg;
}Correlation Analysis
Compare holder growth with price action to find patterns:
async function correlateHoldersAndPrice(mintAddress) {
const [holders, candles] = await Promise.all([
fetch(`https://api.vybenetwork.com/tokens/${mintAddress}/holders-ts?interval=day&limit=30`, {
headers: { "X-API-Key": API_KEY }
}),
fetch(`https://api.vybenetwork.com/tokens/${mintAddress}/candles?resolution=1d&limit=30`, {
headers: { "X-API-Key": API_KEY }
})
].map(p => p.then(r => r.json())));
// Combine data by date
const combined = holders.data.map(h => {
const date = h.timestamp.split('T')[0];
const candle = candles.data.find(c => c.timestamp.split('T')[0] === date);
return {
date,
holderChange: h.change,
holderCount: h.holderCount,
priceChange: candle
? ((parseFloat(candle.close) - parseFloat(candle.open)) / parseFloat(candle.open) * 100).toFixed(2)
: null,
price: candle ? parseFloat(candle.close) : null
};
});
// Find days where holders grew but price didn't (potential opportunity)
const divergences = combined.filter(d =>
d.holderChange > 100 && parseFloat(d.priceChange) < 0
);
return { combined, divergences };
}Anomaly Detection
Detect unusual holder activity:
async function detectHolderAnomalies(mintAddress) {
const response = await fetch(
`https://api.vybenetwork.com/tokens/${mintAddress}/holders-ts?interval=day&limit=30`,
{ headers: { "X-API-Key": API_KEY } }
);
const { data } = await response.json();
// Calculate mean and standard deviation
const changes = data.map(d => d.change);
const mean = changes.reduce((a, b) => a + b, 0) / changes.length;
const stdDev = Math.sqrt(
changes.reduce((sq, n) => sq + Math.pow(n - mean, 2), 0) / changes.length
);
// Flag days with changes > 2 standard deviations
const anomalies = data.filter(d =>
Math.abs(d.change - mean) > 2 * stdDev
).map(d => ({
date: d.timestamp,
change: d.change,
type: d.change > mean ? 'SURGE' : 'DROP',
deviation: ((d.change - mean) / stdDev).toFixed(2)
}));
return {
avgDailyChange: Math.round(mean),
stdDeviation: Math.round(stdDev),
anomalies
};
}Related Endpoints
- Holders - Current top holders snapshot
- Token Details - Current metrics
- Token Candles - Price history for correlation
Updated 4 days ago