Documentation Index
Fetch the complete documentation index at: https://docs.bouncy.ai/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The Bouncy.ai API provides detailed analytics for individual links, bio websites, and aggregate data across your entire account. Track:
- Views and clicks - Total views, tracked clicks, and time-series trends
- Website button clicks - Per-button click totals and daily click counts for bio pages
- Geographic data - Country-level location
- Device information - Mobile vs desktop and platform breakdowns
- Referrer sources - Where your traffic comes from
- Time series data - Clicks over time with hourly/daily granularity
- Adult confirmations - Confirmation count and rate for adult-gated links
Get Link or Website Analytics
Retrieve detailed analytics for a specific link or bio website. For websites, use the website document ID, custom slug, or custom domain:
curl https://api.bouncy.ai/v1/analytics/links/link_abc123 \
-H "Authorization: Bearer bcy_live_pk_YOUR_API_KEY"
Response
{
"id": "my-bio-page",
"identifier": "my-bio-page",
"type": "Website",
"resolvedBy": "customSlug",
"totalViews": 190,
"dailyViews": [
{
"date": "2026-01-15",
"views": 74,
"clicks": 32,
"adultClicks": 0
}
],
"deviceStats": {
"mobile": 176,
"desktop": 14
},
"countryStats": [
{ "name": "United States", "views": 112 },
{ "name": "United Kingdom", "views": 49 }
],
"topCountry": "United States",
"topCountryViews": 112,
"lastViewed": "2026-01-31T19:22:10.000Z",
"platformStats": {
"ios": 104,
"android": 72,
"windows": 14
},
"referrerStats": [
{ "domain": "instagram.com", "views": 89 },
{ "domain": "direct", "views": 54 }
],
"totalClicks": 88,
"clicksByLink": [
{
"id": "shop_0_lx8abc",
"count": 88,
"totalClicks": 88,
"title": "Shop Now",
"url": "https://example.com/shop",
"type": "standard",
"dailyClicks": [
{ "date": "2026-01-15", "clicks": 32 },
{ "date": "2026-01-16", "clicks": 56 }
]
}
],
"adultConfirmation": null
}
Bio website button clicks are included in the same endpoint under clicksByLink. Each item represents one tracked button or social link and includes:
id - Stable button/link ID
title - Button title shown on the page
url - Destination URL
count and totalClicks - Total clicks in the selected range
dailyClicks - Per-day click counts for that button
GET /v1/analytics/links/my-bio-page?timeframe=last_30_days
const response = await fetch(
'https://api.bouncy.ai/v1/analytics/links/my-bio-page?timeframe=last_30_days',
{
headers: { 'Authorization': 'Bearer bcy_live_pk_YOUR_API_KEY' }
}
);
const analytics = await response.json();
const buttons = analytics.clicksByLink.map(button => ({
id: button.id,
title: button.title,
url: button.url,
totalClicks: button.totalClicks,
dailyClicks: button.dailyClicks
}));
Filter Analytics by Date Range
Add query parameters to filter by date:
GET /v1/analytics/links/link_abc123?from=2026-01-01&to=2026-01-31
curl "https://api.bouncy.ai/v1/analytics/links/link_abc123?from=2026-01-01&to=2026-01-31" \
-H "Authorization: Bearer bcy_live_pk_YOUR_API_KEY"
Get Summary Analytics
Get aggregated analytics across all your links:
curl https://api.bouncy.ai/v1/analytics/summary \
-H "Authorization: Bearer bcy_live_pk_YOUR_API_KEY"
Response
{
"totalLinks": 245,
"totalClicks": 45678,
"uniqueVisitors": 32456,
"averageClicksPerLink": 186,
"topLinks": [
{
"linkId": "link_abc123",
"shortUrl": "https://bouncy.ai/summer",
"clicks": 2345
},
{
"linkId": "link_def456",
"shortUrl": "https://bouncy.ai/promo",
"clicks": 1987
}
],
"topCountries": [
{ "country": "US", "clicks": 15678 },
{ "country": "GB", "clicks": 8765 },
{ "country": "CA", "clicks": 5432 }
],
"clicksOverTime": [
{ "date": "2026-02-01", "clicks": 234 },
{ "date": "2026-02-02", "clicks": 345 },
{ "date": "2026-02-03", "clicks": 456 }
]
}
Get analytics for links with a specific tag:
GET /v1/analytics/summary?tag=summer2026
const response = await fetch(
'https://api.bouncy.ai/v1/analytics/summary?tag=summer2026',
{
headers: { 'Authorization': 'Bearer bcy_live_pk_YOUR_API_KEY' }
}
);
const campaignAnalytics = await response.json();
console.log(`Campaign clicks: ${campaignAnalytics.totalClicks}`);
This is perfect for tracking campaign performance!
Real-World Use Cases
Build a custom dashboard showing performance across campaigns:
async function getCampaignStats(campaignTag) {
const response = await fetch(
`https://api.bouncy.ai/v1/analytics/summary?tag=${campaignTag}`,
{
headers: { 'Authorization': 'Bearer bcy_live_pk_YOUR_API_KEY' }
}
);
const stats = await response.json();
return {
campaign: campaignTag,
totalClicks: stats.totalClicks,
uniqueVisitors: stats.uniqueVisitors,
topLink: stats.topLinks[0],
topCountry: stats.topCountries[0]
};
}
const campaigns = ['summer2026', 'winter2026', 'blackfriday'];
const results = await Promise.all(
campaigns.map(tag => getCampaignStats(tag))
);
console.table(results);
Automated Reporting
Send weekly email reports with link performance:
import nodemailer from 'nodemailer';
async function sendWeeklyReport() {
// Get last 7 days of data
const endDate = new Date().toISOString().split('T')[0];
const startDate = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000)
.toISOString()
.split('T')[0];
const response = await fetch(
`https://api.bouncy.ai/v1/analytics/summary?startDate=${startDate}&endDate=${endDate}`,
{
headers: { 'Authorization': 'Bearer bcy_live_pk_YOUR_API_KEY' }
}
);
const stats = await response.json();
const emailBody = `
Weekly Link Report (${startDate} to ${endDate})
Total Clicks: ${stats.totalClicks}
Unique Visitors: ${stats.uniqueVisitors}
Top Performing Links:
${stats.topLinks.map(link => ` - ${link.shortUrl}: ${link.clicks} clicks`).join('\n')}
Top Countries:
${stats.topCountries.map(c => ` - ${c.country}: ${c.clicks} clicks`).join('\n')}
`;
// Send email (configure your SMTP settings)
const transporter = nodemailer.createTransport({...});
await transporter.sendMail({
to: 'team@example.com',
subject: 'Weekly Bouncy.ai Link Report',
text: emailBody
});
}
// Run weekly
setInterval(sendWeeklyReport, 7 * 24 * 60 * 60 * 1000);
A/B Testing
Compare performance of different link variations:
async function compareLinks(linkIds) {
const results = await Promise.all(
linkIds.map(async (linkId) => {
const response = await fetch(
`https://api.bouncy.ai/v1/analytics/links/${linkId}`,
{
headers: { 'Authorization': 'Bearer bcy_live_pk_YOUR_API_KEY' }
}
);
return response.json();
})
);
const comparison = results.map((analytics, index) => ({
linkId: linkIds[index],
views: analytics.totalViews,
clicks: analytics.totalClicks,
clickRate: analytics.totalViews > 0
? (analytics.totalClicks / analytics.totalViews * 100).toFixed(2) + '%'
: '0.00%',
adultConfirmations: analytics.adultConfirmation?.clicks ?? 0,
adultConfirmationRate: analytics.adultConfirmation
? analytics.adultConfirmation.rate + '%'
: 'N/A'
}));
console.table(comparison);
// Determine winner
const winner = comparison.reduce((prev, current) =>
current.clicks > prev.clicks ? current : prev
);
console.log(`Winner: ${winner.linkId} with ${winner.clicks} clicks`);
return winner;
}
const testLinks = ['link_abc123', 'link_def456', 'link_ghi789'];
const winner = await compareLinks(testLinks);
Analytics Best Practices
Analytics don’t change instantly - cache results for a few minutes:const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
async function getCachedAnalytics(linkId) {
const cached = cache.get(linkId);
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
return cached.data;
}
const response = await fetch(
`https://api.bouncy.ai/v1/analytics/links/${linkId}`,
{
headers: { 'Authorization': 'Bearer bcy_live_pk_YOUR_API_KEY' }
}
);
const data = await response.json();
cache.set(linkId, { data, timestamp: Date.now() });
return data;
}
Use date filters for performance
Track by tags for campaigns
Next Steps
Create Links
Create links to start tracking analytics
Organize with Tags
Use tags to group links by campaign
API Reference
Full analytics endpoint documentation
Webhooks
Get notified when links reach milestones (coming soon)