← All IntegrationsIntegration

Analytics for Sentry

Sentry tells you what broke. BetterMeter tells you who was affected. Together, they answer the full question: did that error spike happen because traffic surged, because an AI crawler hammered a fragile endpoint, or because a deploy went wrong?

The error-traffic correlation workflow

When Sentry fires an alert, query BetterMeter for the day the alert landed on. BetterMeter reports traffic by calendar day — one point per day, not per hour — so the comparison is that day against the days before it. If the alert's day is well above the recent baseline, the errors are likely load-related. If traffic is in line with the baseline but errors are up, the root cause is a code or infrastructure change.

sentry-webhook-handler.ts
// Sentry webhook → correlate with BetterMeter traffic
// siteId is the Site id from your BetterMeter dashboard, not the domain.
const SITE_ID = "clx8k2p0a0001qw3f7h2n9d4e";
const day = (d: Date) => d.toISOString().slice(0, 10); // YYYY-MM-DD

export async function handleSentryAlert(alert: SentryAlert) {
  // Traffic is reported per calendar day, so compare the alert's day
  // against the week before it rather than the hour before it.
  const alertDay = new Date(alert.triggeredAt);
  const weekBefore = new Date(alertDay.getTime() - 7 * 24 * 60 * 60 * 1000);
  const query = `siteId=${SITE_ID}&from=${day(weekBefore)}&to=${day(alertDay)}`;
  const headers = { Authorization: `Bearer ${process.env.BETTERMETER_API_KEY}` };

  const [seriesRes, aiRes] = await Promise.all([
    fetch(`https://bettermeter.com/api/analytics/timeseries?${query}`, { headers }),
    fetch(`https://bettermeter.com/api/analytics/ai-traffic?${query}`, { headers }),
  ]);

  // [{ date: "2026-01-05", visitors, pageviews }] — one point per day, gaps filled with zeroes
  const series = await seriesRes.json();
  // { totalAiVisitors, totalVisitors, aiPercentage, byPlatform: [{ platform, visitors, pageviews }] }
  const ai = await aiRes.json();

  const alertDayVisitors = series.at(-1)?.visitors ?? 0;
  const baseline = series.slice(0, -1);
  const avgVisitors = baseline.reduce((s, d) => s + d.visitors, 0) / (baseline.length || 1);

  return {
    errorCount: alert.count,
    trafficCorrelation: alertDayVisitors > avgVisitors * 1.5
      ? "Traffic spike that day — errors likely load-related"
      : "Traffic in line with the baseline — errors likely code-related",
    aiVisitorPercent: ai.aiPercentage,
    topAiPlatforms: ai.byPlatform.slice(0, 3),
  };
}

Why Sentry alone isn't enough

  • 01No traffic context — Sentry shows error counts but not whether a traffic surge caused them. BetterMeter provides the traffic timeline.
  • 02Bot-induced errors — AI crawlers hitting undocumented routes can trigger 500s. BetterMeter identifies exactly which bots are responsible.
  • 03Referrer attribution — When errors spike, see which traffic sources sent the users who encountered them.
  • 04Privacy-first — Sentry captures user sessions and IPs. BetterMeter's traffic data uses no cookies and stores no PII.

Complementary, not competing

Sentry is the best error tracker. BetterMeter is the best privacy-first analytics platform. Use both: Sentry for what broke, BetterMeter for who was there and why traffic behaved the way it did. The combination gives you full incident context without sacrificing user privacy.

Error Correlation
Traffic vs errors
Bot Attribution
Which crawler caused it
Alert Enrichment
Traffic context on a Sentry webhook