Loading...
Loading...
Next.js App Router patterns for Narev usage-based AI billing with the Vercel AI SDK, @ai-billing/core, provider middleware, price resolvers, destinations, route handlers, streaming, and customer usage tags.
npx skill4agent add narevai/skills narev-nextjs-patternsgenerateTextstreamTextnarev-lookup-llm-pricingnarev-update-llm-pricing| Task | Reference |
|---|---|
| Bill a Next.js route handler | references/api-routes.md |
| Pick provider middleware | references/provider-middleware.md |
| Resolve model prices with Narev | references/price-resolvers.md |
| Send usage to destinations and tag customers | references/destinations-and-tags.md |
| Production-safe setup | references/production-setup.md |
| Full-stack Polar integration (existing chatbot) | references/polar-integration.md |
@ai-sdk/<provider>@ai-billing/<provider>createNarevPriceResolver()consoleDestination()wrapLanguageModel()generateTextstreamTextproviderOptions['ai-billing-tags']gateway.languageModel()createGatewayV3Middleware@ai-billing/gatewaypriceResolverreferences/polar-integration.mdimport { createOpenAI } from '@ai-sdk/openai';
import { createOpenAIMiddleware } from '@ai-billing/openai';
import { consoleDestination, createNarevPriceResolver } from '@ai-billing/core';
import { convertToModelMessages, generateText, wrapLanguageModel } from 'ai';
const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY });
const billingMiddleware = createOpenAIMiddleware({
destinations: [consoleDestination()],
priceResolver: createNarevPriceResolver({
apiKey: process.env.NAREV_API_KEY ?? '',
}),
});
export async function POST(request: Request) {
const { messages, userId } = await request.json();
const modelId = 'gpt-4o';
const result = await generateText({
model: wrapLanguageModel({
model: openai(modelId),
middleware: billingMiddleware,
}),
messages: await convertToModelMessages(messages),
providerOptions: {
'ai-billing-tags': {
userId,
modelId,
},
},
});
return Response.json(result);
}| Symptom | Cause | Fix |
|---|---|---|
| Usage is not recorded | Raw provider model is passed to | Pass the |
| Secret leaks into browser bundle | Billing code imported by a Client Component | Keep billing setup in route handlers or server-only modules |
| Model cost is missing or wrong | No | Use the provider-specific middleware and |
| Usage cannot be attributed | Missing tags | Set |
| Tests fail or emit billing events | Middleware initialized during tests | Return the raw model in test environments |
| Cold starts do extra work | Middleware created inside every request | Cache middleware or wrapped-model helpers at module scope |
| Provider | AI SDK package | Billing package |
|---|---|---|
| OpenAI | | |
| Groq | | |
| Anthropic | | |
| | |
| Gateway | AI Gateway provider | |
| OpenRouter | | |
@ai-billing/polar@polar-sh/sdk@ai-billing/nextjsnarevnarev-lookup-llm-pricingnarev-update-llm-pricing