@ai-billing also sends usage events to Billing Providers
Here is an infographic how:
And a codesnippet showing how to do it for:
Stripe
1 import { createOpenRouter } from '@openrouter/ai-sdk-provider' ;
4 convertToModelMessages ,
9 import { createOpenRouterV3Middleware } from '@ai-billing/openrouter' ;
10 import { consoleDestination } from '@ai-billing/core' ;
11 import { createStripeDestination } from '@ai-billing/stripe' ;
15 stripe_customer_id ? : string ;
18 const stripeDestination = createStripeDestination < BillingTags > ( {
19 apiKey : ` ${ process . env . STRIPE_SECRET_KEY } ` ,
20 meterName : 'llm_usage' ,
23 const openrouter = createOpenRouter ( {
25 apiKey : process . env . OPENROUTER_API_KEY ,
29 const billingMiddleware = createOpenRouterV3Middleware < BillingTags > ( {
30 destinations : [ consoleDestination ( ) , stripeDestination ] ,
33 export async function POST ( ) {
34 const messages : UIMessage [ ] = [
36 id : 'test-message-123' ,
41 text : 'What is the capital of Sweden?' ,
47 const model = 'google/gemini-2.0-flash-001' ;
49 const wrappedModel = wrapLanguageModel ( {
50 model : openrouter ( model ) ,
51 middleware : billingMiddleware ,
54 const result = streamText ( {
56 messages : await convertToModelMessages ( messages ) ,
59 stripe_customer_id : 'cus_UIMLD4AuBpC8Ux' ,
60 org_name : 'acme corp' ,
65 return result . toUIMessageStreamResponse ( ) ;
Polar 1 import { createOpenRouter } from '@openrouter/ai-sdk-provider' ;
4 convertToModelMessages ,
9 import { createOpenRouterV3Middleware } from '@ai-billing/openrouter' ;
10 import { consoleDestination } from '@ai-billing/core' ;
11 import { createPolarDestination } from '@ai-billing/polar' ;
18 const polarDestination = createPolarDestination < BillingTags > ( {
19 accessToken : process . env . POLAR_ACCESS_TOKEN ,
20 eventName : 'llm_usage' ,
24 const openrouter = createOpenRouter ( {
26 apiKey : process . env . OPENROUTER_API_KEY ,
30 const billingMiddleware = createOpenRouterV3Middleware < BillingTags > ( {
31 destinations : [ consoleDestination ( ) , polarDestination ] ,
34 export async function POST ( ) {
35 const messages : UIMessage [ ] = [
37 id : 'test-message-123' ,
42 text : 'What is the capital of Sweden?' ,
48 const model = 'google/gemini-2.0-flash-001' ;
50 const wrappedModel = wrapLanguageModel ( {
51 model : openrouter ( model ) ,
52 middleware : billingMiddleware ,
55 const result = streamText ( {
57 messages : await convertToModelMessages ( messages ) ,
60 customer_id : '4a874ea3-53ec-432d-9d55-c55bf957e18f' ,
61 org_name : 'Acme Corp' ,
66 return result . toUIMessageStreamResponse ( ) ;
Lago
1 import { createOpenRouter } from '@openrouter/ai-sdk-provider' ;
4 convertToModelMessages ,
8 import { createOpenRouterV3Middleware } from '@ai-billing/openrouter' ;
9 import { consoleDestination } from '@ai-billing/core' ;
10 import { createLagoDestination } from '@ai-billing/lago' ;
16 const lagoDestination = createLagoDestination < BillingTags > ( {
17 apiKey : ` ${ process . env . LAGO_API_KEY } ` ,
18 apiUrl : process . env . LAGO_API_URL ,
19 meterCode : 'llm_usage' ,
22 const openrouter = createOpenRouter ( {
24 apiKey : process . env . OPENROUTER_API_KEY ,
27 const billingMiddleware = createOpenRouterV3Middleware < BillingTags > ( {
28 destinations : [ consoleDestination ( ) , lagoDestination ] ,
31 export async function POST ( ) {
32 const messages : UIMessage [ ] = [
34 id : 'test-message-123' ,
39 text : 'What is the capital of Sweden?' ,
45 const model = 'openai/gpt-4o' ;
47 const wrappedModel = wrapLanguageModel ( {
48 model : openrouter ( model ) ,
49 middleware : billingMiddleware ,
52 const result = streamText ( {
54 messages : await convertToModelMessages ( messages ) ,
57 userId : 'user_lago_test' ,
62 return result . toUIMessageStreamResponse ( ) ;
OpenMeter
1 import { createOpenRouter } from '@openrouter/ai-sdk-provider' ;
4 convertToModelMessages ,
8 import { createOpenRouterV3Middleware } from '@ai-billing/openrouter' ;
9 import { consoleDestination } from '@ai-billing/core' ;
10 import { createOpenMeterDestination } from '@ai-billing/openmeter' ;
17 const openMeterDestination = createOpenMeterDestination < BillingTags > ( {
18 apiKey : ` ${ process . env . OPENMETER_API_KEY } ` ,
21 const openrouter = createOpenRouter ( {
23 apiKey : process . env . OPENROUTER_API_KEY ,
26 const billingMiddleware = createOpenRouterV3Middleware < BillingTags > ( {
27 destinations : [ consoleDestination ( ) , openMeterDestination ] ,
30 export async function POST ( ) {
31 const messages : UIMessage [ ] = [
33 id : 'test-message-123' ,
35 parts : [ { type : 'text' , text : 'What is the capital of Sweden?' } ] ,
39 const model = 'openai/gpt-4o' ;
41 const wrappedModel = wrapLanguageModel ( {
42 model : openrouter ( model ) ,
43 middleware : billingMiddleware ,
46 const result = streamText ( {
48 messages : await convertToModelMessages ( messages ) ,
51 userId : 'user_openmeter_test' ,
52 org_name : 'Acme Corp' ,
57 return result . toUIMessageStreamResponse ( ) ;