BillingOS uses session tokens to securely identify your customers. You create the token on your server (so your secret key stays private), and the SDK uses it automatically for all API calls.Add your secret key to your environment:
.env.local
Copy
BILLINGOS_SECRET_KEY=sk_test_your_secret_key_here
Then create an endpoint that generates a token for the logged-in user:
Copy
import { BillingOS } from "@billingos/node";const billing = new BillingOS({ secretKey: process.env.BILLINGOS_SECRET_KEY!,});export async function GET(request: Request) { // Replace with your actual auth — NextAuth, Clerk, Supabase, etc. const userId = await getLoggedInUserId(request); const { sessionToken, expiresAt } = await billing.createSessionToken({ externalUserId: userId, // your user's ID from your database expiresIn: 3600, // 1 hour }); return Response.json({ sessionToken, expiresAt });}
The externalUserId is your user’s ID from your own database. BillingOS uses it to link the session to the right customer’s subscriptions and entitlements.
BillingOSProvider wraps your app and handles fetching the session token automatically.
app/providers.tsx
Copy
"use client";import { BillingOSProvider } from "@billingos/sdk";export function Providers({ children }: { children: React.ReactNode }) { return ( <BillingOSProvider sessionTokenUrl="/api/billingos-session"> {children} </BillingOSProvider> );}
app/layout.tsx
Copy
import { Providers } from "./providers";export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html> <body> <Providers>{children}</Providers> </body> </html> );}
That’s all the setup. The SDK now:
Fetches a session token from your endpoint when the app loads
Attaches the token to every API call
Refreshes the token automatically before it expires
Injects required CSS on mount (no separate CSS import needed)
Next.js App Router requires "use client" for components that use React context. That’s why we create a separate Providers wrapper — your layout stays a Server Component.