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:
- Report — your server sends usage events to AuthGate as they happen
- Aggregate — AuthGate accumulates usage per user, per metric, per billing period
- 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) andquantity(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.