> ## Documentation Index
> Fetch the complete documentation index at: https://www.narev.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Polar

> Send AI-billing LLM usage events to Polar and sync customers so you can bill end users for AI consumption with subscriptions and metered pricing.

# Polar billing platform integration

Use this guide after your framework-level integration is complete.

This page covers Polar-specific setup:

* Configure a cost-based meter in base currency units.
* Create the `@ai-billing/polar` destination.
* Map usage events to Polar customers.
* Sync user identity with `externalId`.

For the server middleware setup, use [Node.js billing integration](https://www.narev.ai/docs/ai-billing/integrations/frameworks/nodejs.md).

## Meter units

The default `@ai-billing/polar` destination sends `credits_consumed` in base currency units and `cost_currency` alongside it. For USD, a \$0.002 cost produces `credits_consumed: 0.002`. It does not produce 2,000,000 nanos.

Create a Polar meter that filters events named `llm_usage` and sums `credits_consumed`. Match your product's unit pricing to that currency amount. Verify an actual sandbox event against your installed package version before enabling charges.

The destination maps your `userId` tag to the customer's `externalId`. Credentials and meter configuration live in your app and Polar workspace. Document your custom numeric units when you override `mapMetadata`. Verify those units against a sandbox event.

## Install dependencies

```bash theme={null}
pnpm add @ai-billing/polar @polar-sh/sdk
```

## Configure environment variables

Set these on your server:

```bash theme={null}
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`:

```ts lib/ai/destinations.ts theme={null}
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`:

```ts lib/polar-client.ts theme={null}
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:

```ts theme={null}
if (newUser) {
  await createPolarCustomer(validatedData.email, newUser.id);
}
```

## Required tag contract

In your generation routes, include:

```ts theme={null}
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 `credits_consumed` and `cost_currency`, plus the expected `tag_*` metadata and customer identity.
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.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.