Skip to main content

Overview

The Bouncy.ai API provides detailed analytics for individual links and aggregate data across your entire account. Track:
  • Click counts - Total clicks and unique visitors
  • Geographic data - Country and city-level location
  • Device information - Mobile vs desktop, OS, browser
  • Referrer sources - Where your traffic comes from
  • Time series data - Clicks over time with hourly/daily granularity
Retrieve detailed analytics for a specific link:
curl https://api.bouncy.ai/v1/analytics/links/link_abc123 \
  -H "Authorization: Bearer bcy_live_pk_YOUR_API_KEY"

Response

{
  "linkId": "link_abc123",
  "shortUrl": "https://bouncy.ai/summer",
  "totalClicks": 1234,
  "uniqueVisitors": 892,
  "lastClickAt": "2026-02-06T11:30:00Z",
  "topCountries": [
    { "country": "US", "clicks": 456 },
    { "country": "GB", "clicks": 234 },
    { "country": "CA", "clicks": 123 }
  ],
  "topCities": [
    { "city": "London", "country": "GB", "clicks": 89 },
    { "city": "New York", "country": "US", "clicks": 67 }
  ],
  "topReferrers": [
    { "referrer": "twitter.com", "clicks": 345 },
    { "referrer": "facebook.com", "clicks": 234 },
    { "referrer": "direct", "clicks": 189 }
  ],
  "devices": {
    "mobile": 678,
    "desktop": 456,
    "tablet": 100
  },
  "browsers": {
    "Chrome": 567,
    "Safari": 345,
    "Firefox": 234,
    "Edge": 88
  },
  "operatingSystems": {
    "iOS": 456,
    "Android": 345,
    "Windows": 234,
    "macOS": 199
  }
}

Filter Analytics by Date Range

Add query parameters to filter by date:
GET /v1/analytics/links/link_abc123?startDate=2026-01-01&endDate=2026-01-31
curl "https://api.bouncy.ai/v1/analytics/links/link_abc123?startDate=2026-01-01&endDate=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 }
  ]
}

Filter Summary by Tags

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

Campaign Performance Dashboard

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();
    })
  );

  // Calculate conversion rates (assuming you track conversions)
  const comparison = results.map(analytics => ({
    url: analytics.shortUrl,
    clicks: analytics.totalClicks,
    uniqueVisitors: analytics.uniqueVisitors,
    clickThroughRate: (analytics.uniqueVisitors / analytics.totalClicks * 100).toFixed(2) + '%'
  }));

  console.table(comparison);

  // Determine winner
  const winner = comparison.reduce((prev, current) =>
    current.clicks > prev.clicks ? current : prev
  );

  console.log(`Winner: ${winner.url} 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;
}
When querying large date ranges, the API processes more data. For better performance, query smaller date ranges:
// ❌ Slow: Query entire year
const yearAnalytics = await fetch(
  'https://api.bouncy.ai/v1/analytics/summary?startDate=2026-01-01&endDate=2026-12-31'
);

// ✅ Fast: Query last 30 days
const monthAnalytics = await fetch(
  'https://api.bouncy.ai/v1/analytics/summary?startDate=2026-01-07&endDate=2026-02-06'
);
Always tag your links by campaign so you can filter analytics later:
// Create link with campaign tags
await fetch('https://api.bouncy.ai/v1/links', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer bcy_live_pk_YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    url: 'https://example.com/sale',
    tags: ['summer2026', 'instagram', 'story']
  })
});

// Later: Get campaign analytics
const analytics = await fetch(
  'https://api.bouncy.ai/v1/analytics/summary?tag=summer2026'
);

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)