Skip to main content

Overview

The quota endpoint allows you to check your current API usage against your plan’s monthly limits.
This endpoint uses Hono.js server procedures and requires authentication via session cookies (not Bearer tokens). It is primarily used by the PingPilot web dashboard.

Get Usage Statistics

Retrieve current usage statistics for categories and events.
GET /api/project/getUsage

Response

categoriesUsed
number
Number of event categories you’ve created.
categoriesLimit
number
Maximum number of categories allowed by your plan.
eventsUsed
number
Number of events sent this month.
eventsLimit
number
Maximum number of events allowed per month by your plan.
resetDate
string
ISO timestamp when quota resets (first day of next month).

Success Response

{
  "categoriesUsed": 5,
  "categoriesLimit": 10,
  "eventsUsed": 247,
  "eventsLimit": 1000,
  "resetDate": "2026-04-01T00:00:00.000Z"
}

Quota Limits by Plan

Free Plan

{
  "categoriesLimit": 3,
  "eventsLimit": 100
}

Pro Plan

{
  "categoriesLimit": 10,
  "eventsLimit": 1000
}

Enterprise Plan

{
  "categoriesLimit": 100,
  "eventsLimit": 10000
}

Usage Calculation

Categories

Counts all event categories created in your account, regardless of when they were created.
SELECT COUNT(*) FROM event_categories WHERE user_id = ?

Events

Counts only events sent in the current calendar month:
SELECT count FROM quota 
WHERE user_id = ? 
  AND month = CURRENT_MONTH 
  AND year = CURRENT_YEAR
The quota counter increments after successful event creation, even if delivery fails.

Reset Date

Quota resets on the 1st day of each month at 00:00:00 UTC. The resetDate field shows when your next reset occurs:
const currentDate = startOfMonth(new Date());
const resetDate = addMonths(currentDate, 1);
// Example: 2026-04-01T00:00:00.000Z

Monitoring Usage

Calculate Remaining Quota

const getRemainingQuota = (usage) => {
  const eventsRemaining = usage.eventsLimit - usage.eventsUsed;
  const categoriesRemaining = usage.categoriesLimit - usage.categoriesUsed;
  
  return {
    events: eventsRemaining,
    categories: categoriesRemaining,
    eventsPercent: (usage.eventsUsed / usage.eventsLimit) * 100,
    categoriesPercent: (usage.categoriesUsed / usage.categoriesLimit) * 100
  };
};

Usage Alerts

const checkUsageAlerts = (usage) => {
  const eventsPercent = (usage.eventsUsed / usage.eventsLimit) * 100;
  const categoriesPercent = (usage.categoriesUsed / usage.categoriesLimit) * 100;
  
  const alerts = [];
  
  if (eventsPercent >= 90) {
    alerts.push({
      type: 'critical',
      message: `⚠️ 90% of monthly events used (${usage.eventsUsed}/${usage.eventsLimit})`
    });
  } else if (eventsPercent >= 75) {
    alerts.push({
      type: 'warning',
      message: `⚑ 75% of monthly events used (${usage.eventsUsed}/${usage.eventsLimit})`
    });
  }
  
  if (categoriesPercent >= 100) {
    alerts.push({
      type: 'critical',
      message: `🚫 Category limit reached (${usage.categoriesUsed}/${usage.categoriesLimit})`
    });
  }
  
  return alerts;
};

Days Until Reset

const getDaysUntilReset = (resetDate) => {
  const now = new Date();
  const reset = new Date(resetDate);
  const diffMs = reset - now;
  const diffDays = Math.ceil(diffMs / (1000 * 60 * 60 * 24));
  return diffDays;
};

// Usage
const daysLeft = getDaysUntilReset(usage.resetDate);
console.log(`Quota resets in ${daysLeft} days`);

Quota Enforcement

Events

When you reach your monthly event limit:
  1. New event requests return 429 Too Many Requests
  2. Error message: "Monthly quota reached. Please upgrade your plan for more events"
  3. Events are not created and not delivered
  4. Quota counter is not incremented
See Rate Limits for details.

Categories

When you reach your category limit:
  1. Category creation requests fail
  2. You must delete existing categories or upgrade your plan
  3. Existing categories continue to work normally

Example: Usage Dashboard

const fetchUsageDashboard = async () => {
  const response = await fetch('/api/project/getUsage', {
    credentials: 'include'
  });
  
  const usage = await response.json();
  
  // Calculate metrics
  const eventsPercent = (usage.eventsUsed / usage.eventsLimit) * 100;
  const categoriesPercent = (usage.categoriesUsed / usage.categoriesLimit) * 100;
  const daysLeft = getDaysUntilReset(usage.resetDate);
  
  return {
    ...usage,
    metrics: {
      eventsPercent: eventsPercent.toFixed(1),
      categoriesPercent: categoriesPercent.toFixed(1),
      daysUntilReset: daysLeft,
      eventsRemaining: usage.eventsLimit - usage.eventsUsed,
      categoriesRemaining: usage.categoriesLimit - usage.categoriesUsed
    },
    alerts: checkUsageAlerts(usage)
  };
};

// Display usage
const dashboard = await fetchUsageDashboard();

console.log(`πŸ“Š Usage Dashboard`);
console.log(`\nEvents: ${dashboard.eventsUsed}/${dashboard.eventsLimit} (${dashboard.metrics.eventsPercent}%)`);
console.log(`Categories: ${dashboard.categoriesUsed}/${dashboard.categoriesLimit} (${dashboard.metrics.categoriesPercent}%)`);
console.log(`\nπŸ“… Resets in ${dashboard.metrics.daysUntilReset} days`);

if (dashboard.alerts.length > 0) {
  console.log(`\n⚠️ Alerts:`);
  dashboard.alerts.forEach(alert => console.log(`  ${alert.message}`));
}

Best Practices

  • Monitor regularly: Check usage weekly or after bulk operations
  • Set up alerts: Notify yourself at 75% and 90% usage
  • Plan ahead: Upgrade before hitting limits if usage is consistent
  • Track trends: Compare month-over-month usage patterns
  • Clean up: Delete unused categories to free up slots
  • Optimize: Batch similar events or reduce non-critical notifications

Build docs developers (and LLMs) love