Skip to main content

Documentation Index

Fetch the complete documentation index at: https://narev.ai/docs/llms.txt

Use this file to discover all available pages before exploring further.

Polar billing platform integration

Use this guide after your framework-level integration is complete. This page covers Polar-specific setup:
  • Create the @ai-billing/polar destination.
  • Map usage events to Polar customers.
  • Sync user identity with externalId.
For the framework setup in Next.js, use Next.js billing integration.

Install polar dependencies

pnpm add @ai-billing/polar @polar-sh/sdk

Configure environment variables

Set these on your server:
POLAR_ACCESS_TOKEN=****
POLAR_SERVER=sandbox # or production
Use sandbox until your metering flow is verified.

Create Polar billing destinations

Create lib/ai/destinations.ts:
lib/ai/destinations.ts
import { createPolarDestination } from '@ai-billing/polar';

export function getBillingDestinations() {
  const polarAccessToken = process.env.POLAR_ACCESS_TOKEN;
  const polarServer = process.env.POLAR_SERVER as
    | 'sandbox'
    | 'production'
    | undefined;

  if (!polarAccessToken) return [];

  return [
    createPolarDestination({
      accessToken: polarAccessToken,
      server: polarServer ?? 'sandbox',
      eventName: 'llm_usage',
      externalCustomerIdKey: 'userId',
    }),
  ];
}
The key mapping is externalCustomerIdKey: 'userId'. Your billing tags must include userId.

Sync Polar customers on signup

Create lib/polar-client.ts:
lib/polar-client.ts
import { Polar } from '@polar-sh/sdk';

let _polar: Polar | null = null;

function getPolarClient(): Polar | null {
  if (_polar) return _polar;

  const accessToken = process.env.POLAR_ACCESS_TOKEN;
  if (!accessToken) return null;

  const server = (process.env.POLAR_SERVER ?? 'sandbox') as
    | 'sandbox'
    | 'production';

  _polar = new Polar({ accessToken, server });
  return _polar;
}

export async function createPolarCustomer(email: string, userId: string) {
  const polar = getPolarClient();
  if (!polar) return;

  try {
    await polar.customers.create({ email, externalId: userId });
  } catch (error) {
    console.error('[ai-billing] Failed to create Polar customer:', error);
  }
}
Call this when a user signs up:
if (newUser) {
  await createPolarCustomer(validatedData.email, newUser.id);
}

Required tag contract

In your generation routes, include:
providerOptions: {
  'ai-billing-tags': {
    userId: session.user.id,
    modelId: chatModel,
    chatId: id,
  },
}
Contract requirements:
  • userId in ai-billing-tags must match Polar externalId.
  • Each user should have one Polar customer record.

Verify polar metering

  1. Register a new user and confirm a Polar customer exists with externalId = userId.
  2. Trigger a model call and confirm an event named llm_usage appears.
  3. Validate metadata contains userId, modelId, and route context.
  4. Confirm your environment uses the expected Polar server (sandbox or production).

Common issues

Events appear but don’t map to customers

  • Confirm userId exists in ai-billing-tags.
  • Confirm destination uses externalCustomerIdKey: 'userId'.
  • Confirm customer creation uses externalId = userId.

No events arrive in Polar

  • Confirm POLAR_ACCESS_TOKEN is present at runtime.
  • Confirm POLAR_SERVER matches the Polar workspace you are checking.
  • Confirm framework routes call the billing-wrapped model helper.