
Next.js + OpenAI: OAuth Auth, Usage-Based Billing
Learn how to implement Next.js AI billing with OAuth user authentication, server-side OpenAI request proxying, per-user quotas, usage tracking, and usage-based billing patterns (including Stripe).
Building an AI feature is easy; running it sustainably is not. The moment you connect a Next.js app to the OpenAI API, you inherit real costs, abuse risk, and the need to turn usage into revenue (or at least keep it bounded). This guide shows a practical, production-minded approach to Next.js AI billing: implement OAuth user authentication, track per-user usage, enforce quotas, and add usage-based billing—without relying on guesswork or fragile client-side controls.
This article is framework-first (Next.js App Router), provider-agnostic where possible, and focused on patterns that are verifiable and commonly used in production systems.
What you’re building (architecture overview)
A robust Next.js AI billing setup usually has five moving parts:
- OAuth authentication to identify users reliably (and create accounts on first sign-in).
- A database schema that stores users, plans, subscriptions (optional), and usage events.
- A server-side AI proxy route (never call OpenAI directly from the browser) that meters usage.
- Quota enforcement (free tier limits, paid tiers, per-seat limits, etc.).
- Billing integration (typically Stripe) for subscription + metered/usage-based charges or prepaid credits.
Key principle: treat OpenAI calls like any paid backend resource. Centralize them behind authenticated server routes, record usage, and enforce limits before you spend money.
1) OAuth user authentication in Next.js (App Router)
For OAuth in Next.js, a common approach is to use an authentication library that supports OAuth providers (Google, GitHub, etc.) and server-side session retrieval. The exact library choice is up to you, but the requirements are consistent:
- OAuth provider configuration (client ID/secret).
- A session mechanism that works in server components and route handlers.
- A callback that creates or updates your user record in the database.
- A stable internal user ID you can attach usage and billing data to.
Implementation checklist:
- Add OAuth provider credentials to environment variables.
- Configure auth routes (sign-in, callback).
- On successful sign-in, upsert a user record (by provider account ID/email).
- Store a user ID in the session so your API routes can enforce quotas and billing rules.
Important: enforce authentication on the server for AI routes. Even if your UI hides the button for anonymous users, the backend must reject unauthenticated requests.
2) Data model for Next.js AI billing (users, plans, usage)
You need a schema that can answer these questions quickly and safely:
- Who is the user making this request?
- What plan are they on (free, pro, team)?
- How much have they used in the current billing period?
- Are they allowed to make this request right now?
- If billed, how do we map usage to an invoice or balance?
A minimal, practical schema (relational) looks like this:
- users: id, email, name, createdAt
- accounts (optional): oauth provider linkage (provider, providerAccountId, userId)
- plans: id, name, monthlyQuotaTokens (or credits), features
- subscriptions (if using recurring billing): id, userId, providerCustomerId, providerSubscriptionId, status, currentPeriodStart, currentPeriodEnd, planId
- usage_events: id, userId, timestamp, model, inputTokens, outputTokens, totalTokens, requestId, costCents (optional), metadata JSON
Notes:
- Track usage in a dedicated table (append-only). It’s audit-friendly and makes disputes easier to resolve.
- Store token counts returned by the OpenAI API response (where available) rather than estimating.
- If you do cost calculations, keep them versioned or store enough metadata to recompute later. Pricing can change over time; don’t hardcode assumptions into historical records.
3) Proxy OpenAI requests through a server route (never from the client)
For security and billing control, the browser should never hold your OpenAI API key. Instead, create a Next.js Route Handler (e.g., /api/ai/chat) that:
- Authenticates the user via server-side session.
- Checks quota/entitlements.
- Calls OpenAI using your server-side key.
- Records usage (tokens) in the database.
- Returns the model output to the client.
// app/api/ai/chat/route.ts
import { NextResponse } from "next/server";
export async function POST(req: Request) {
// 1) Authenticate user (pseudo-code)
// const session = await auth();
// if (!session?.user?.id) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
// 2) Read request
const body = await req.json();
const { messages } = body;
// 3) Enforce quota (pseudo-code)
// const allowed = await checkQuota(session.user.id);
// if (!allowed) return NextResponse.json({ error: "Quota exceeded" }, { status: 402 });
// 4) Call OpenAI (pseudo-code)
// const response = await openai.responses.create({ model: "...", input: messages });
// 5) Record usage (pseudo-code)
// await recordUsage({ userId: session.user.id, usage: response.usage, model: response.model });
// 6) Return
return NextResponse.json({ ok: true });
}Keep the code provider-agnostic in your app structure: a single “AI gateway” module is ideal. That’s where you normalize usage fields, handle retries, and attach request IDs for tracing.
4) Measuring usage: tokens, requests, or credits? (choose one primary meter)
To implement Next.js AI billing, you need a unit of account. Common options:
- Tokens (input + output): best when your costs scale with tokens and you want fairness across short/long prompts.
- Requests: simplest, but can be unfair (a 20-token request costs less than a 2,000-token request).
- Credits: a product abstraction (e.g., 1 credit = N tokens). Good for UX and plan design, but you still need a mapping to real usage.
If you’re early-stage, start by storing raw token usage per request and optionally expose “credits” in the UI. Raw usage is the source of truth; credits are a presentation layer.
5) Enforcing per-user quotas (hard limits that actually work)
Quota enforcement must be server-side and race-condition aware. The two most common strategies are:
- Rolling aggregation: sum usage_events for the current period and compare to quota. Easy to implement but can be slow at scale without careful indexing/caching.
- Ledger + counters: write usage_events and maintain a per-user counter (e.g., usage_totals table) updated transactionally. Faster reads and simpler checks under load.
Practical enforcement flow:
- Determine the user’s active plan and current billing period window.
- Compute current usage (tokens/credits) for that window.
- If the next request would exceed the quota, reject before calling OpenAI.
- If allowed, call OpenAI, then persist the actual usage from the response.
- Optionally: if the response usage is higher than expected, you can allow small overages or clamp output via max tokens to reduce risk.
To reduce surprises, set explicit model limits (like maximum output tokens) and validate user inputs (prompt size, file size) before sending to the model.
6) Usage-based billing with Stripe (patterns that map well to AI)
Stripe is a common choice for SaaS billing, including usage-based billing. There are two widely used product models for AI features:
Model A: Subscription with included quota + overage
Users pay a monthly fee that includes a token/credit allowance. If they exceed it, you either:
- Block usage (hard cap), or
- Charge overage (metered billing)
This model is easy to explain and works well when you want predictable revenue and predictable usage boundaries.
Model B: Prepaid credits (top-ups)
Users buy credits in advance, you decrement their balance as they use the AI, and you block when the balance is zero. This can be simpler than metered invoices for some products and reduces payment disputes, but requires a good credit UX.
Whichever you choose, the integration principles are the same:
- Use Stripe webhooks as the source of truth for subscription status and payment events.
- Store Stripe customer/subscription IDs in your database.
- Gate AI routes based on subscription status and quota/balance.
- Record usage internally even if Stripe is metering it—your app needs real-time enforcement.
If you implement metered billing, you typically report usage to Stripe periodically (or near real-time) and Stripe invoices at period end. Your app should still enforce a safety ceiling to prevent runaway costs if a webhook is delayed or a customer’s payment fails.
7) Preventing abuse and runaway spend (must-have safeguards)
AI endpoints are attractive targets for abuse. Add layered controls:
- Authentication required for all AI routes.
- Rate limiting per user and per IP (especially for sign-up and free tier).
- Request validation: max prompt size, max attachments, allowed tools/models.
- Strict server-side quotas with clear error responses.
- Idempotency keys or request IDs to avoid double-charging on retries.
- Logging + alerting for spikes in usage (by user, by route, by model).
Also consider separating “free trial” from “free forever.” A free trial with a small, time-boxed quota reduces long-term abuse pressure.
8) UX: show usage transparently (and reduce support tickets)
Your billing system is only as good as its user experience. Include:
- A usage dashboard: used vs remaining for the current period.
- A clear upgrade path when quota is exceeded.
- Email or in-app warnings at thresholds (e.g., 50%, 80%, 100%).
- Receipts/invoices and a simple billing portal link (if using Stripe).
When returning quota errors from your AI route, use a dedicated status and message that the frontend can interpret (e.g., “quota_exceeded” with next reset date).
9) SEO-friendly implementation notes (for your docs and marketing pages)
If you’re targeting “Next.js AI billing,” create supporting pages that answer adjacent intent:
- “How to track OpenAI token usage in Next.js”
- “Implement per-user quotas in Next.js App Router”
- “Stripe usage-based billing for AI SaaS”
- “OAuth login in Next.js for SaaS apps”
Interlink these pages and include a simple diagram of your flow (OAuth → AI proxy → usage ledger → quota check → billing). That improves comprehension and helps search engines understand topical authority.
10) Putting it together: a reference request flow
- User signs in via OAuth.
- Your auth callback upserts a user record and establishes a session.
- User hits your AI endpoint (/api/ai/*).
- Server loads session → userId.
- Server loads plan/subscription status and current period.
- Server checks rate limits and quota/balance.
- Server calls OpenAI with server key and safe limits.
- Server records usage from the response (tokens, model, requestId).
- Server returns AI output.
- A background job/webhook sync optionally reports usage to Stripe (if metered) and keeps subscription state current.
Conclusion
Next.js AI billing is less about “adding payments” and more about building a trustworthy control system around expensive API calls. With OAuth-based identity, a server-side AI proxy, an append-only usage ledger, and strict quota enforcement, you can ship AI features that scale financially. Add Stripe (subscription, metered overage, or prepaid credits) and you have a complete path from authenticated user → measured usage → enforceable limits → revenue.
If you want, share your intended pricing model (free tier + monthly plans vs prepaid credits) and which OAuth/billing providers you prefer, and I can outline a concrete schema and route structure tailored to your app.