Usage-Based Billing

Report usage events from your server and AuthGate aggregates them into metered charges at the end of each billing period.


How usage billing works

Usage-based billing works in three stages:

  1. Report — your server sends usage events to AuthGate as they happen
  2. Aggregate — AuthGate accumulates usage per user, per metric, per billing period
  3. Bill — at period end, AuthGate calculates the charge based on the aggregated usage and instructs Stripe to collect payment

Usage is tied to a metric name (e.g. api_calls, storage_gb, seats). Each metric maps to a metered or tiered price on a plan. Users on plans that do not include a given metric are not charged for it.


Reporting usage

Report usage server-side using createBillingHelpers from @auth-gate/nextjs. Never report usage from the client — usage events must come from trusted server code.

src/lib/billing.ts

import { createBillingHelpers } from "@auth-gate/nextjs";

export const billing = createBillingHelpers({
  baseUrl: process.env.AUTHGATE_URL!,
  apiKey: process.env.AUTHGATE_API_KEY!,
});

src/app/api/generate/route.ts

import { billing } from "@/lib/billing";
import { billing as billingConfig } from "../../authgate.billing";
import { getSession } from "@/lib/auth";

export async function POST(request: Request) {
  const user = await getSession();
  if (!user) return new Response("Unauthorized", { status: 401 });

  // ... perform the action ...

  await billing.reportUsage({
    userId: user.id,
    projectId: process.env.AUTHGATE_PROJECT_ID!,
    events: { metric: billingConfig.features.api_calls, quantity: 1 },  // type-safe — no .key needed
  });

  return Response.json({ success: true });
}

Parameters

  • Name
    userId
    Type
    string
    Description

    The ID of the user who consumed the resource. Must match the user ID in AuthGate.

  • Name
    projectId
    Type
    string
    Description

    Your AuthGate project ID.

  • Name
    events
    Type
    object
    Description

    An object with metric (the feature object or string key, e.g. billing.features.api_calls) and quantity (the amount to add). Quantity must be a positive integer.

  • Name
    idempotencyKey
    Type
    string
    Description

    Optional. A unique key to prevent duplicate reporting. See Idempotency.

  • Name
    timestamp
    Type
    string
    Description

    Optional ISO 8601 timestamp. Defaults to the current time. Use this when reporting usage retroactively.

Batch reporting

To report multiple metrics or larger quantities in a single call, pass an array to events:

await billing.reportUsage({
  userId: user.id,
  projectId: process.env.AUTHGATE_PROJECT_ID!,
  events: [
    { metric: billingConfig.features.api_calls, quantity: 5 },
    { metric: billingConfig.features.storage_gb, quantity: 2 },
  ],
});

Idempotency

If your server retries failed requests, the same usage event could be reported twice. Prevent double-billing by passing an idempotencyKey:

await billing.reportUsage({
  userId: user.id,
  projectId: process.env.AUTHGATE_PROJECT_ID!,
  events: { metric: billingConfig.features.api_calls.key, quantity: 1 },  // type-safe enum
  idempotencyKey: `req_${requestId}`,
});

AuthGate deduplicates events with the same idempotency key within a 24-hour window. Keys must be unique per user and metric.


Querying usage

Use the useUsage hook to display usage data in your application's UI:

import { useUsage } from "@auth-gate/react";
import { billing } from "../../authgate.billing";

function UsageDashboard() {
  const { usage, loading } = useUsage({ metric: billing.features.api_calls });  // type-safe — no .key needed

  if (loading) return <p>Loading usage...</p>;

  return (
    <div>
      <p>API calls this period: {usage?.quantity ?? 0}</p>
      <p>Period ends: {usage ? new Date(usage.period_end).toLocaleDateString() : "—"}</p>
    </div>
  );
}

For server-side usage queries, use the REST endpoint directly:

curl https://your-authgate-instance.com/api/proxy/billing/usage/summary?metric=api_calls \
  -H "Authorization: Bearer <session_token>"

Pricing models

Metered

A flat per-unit price applied to total usage at period end.

$0.001 per api_call → 10,000 calls → $10.00

Tiered (volume)

The per-unit price for all units is determined by the total quantity in that tier.

1–1,000 calls:    $0.002/call
1,001–10,000:     $0.001/call
10,001+:          $0.0005/call

If a user makes 5,000 calls, all 5,000 are billed at $0.001.

Tiered (graduated)

Each tier's price applies only to the units within that tier.

First 1,000 calls:    $0.002/call → $2.00
Next 9,000 calls:     $0.001/call → $9.00
Total for 10,000 calls: $11.00

Configure the pricing model when creating a price in the dashboard under Billing → Plans → [Plan] → Prices → New Price.

Was this page helpful?