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

# Quickstart

> Accept your first payment in under 5 minutes.

This guide walks you through adding BillingOS to your app. By the end, you'll have a working pricing page with checkout.

<Info>
  **Prerequisites:** A BillingOS account with at least one product created in the dashboard.
</Info>

## Step 1: Install the packages

<CodeGroup>
  ```bash npm theme={null}
  npm install @billingos/sdk @tanstack/react-query
  ```

  ```bash pnpm theme={null}
  pnpm add @billingos/sdk @tanstack/react-query
  ```

  ```bash yarn theme={null}
  yarn add @billingos/sdk @tanstack/react-query
  ```
</CodeGroup>

For your server, install the Node SDK separately:

<CodeGroup>
  ```bash npm theme={null}
  npm install @billingos/node
  ```

  ```bash pnpm theme={null}
  pnpm add @billingos/node
  ```

  ```bash yarn theme={null}
  yarn add @billingos/node
  ```
</CodeGroup>

## Step 2: Create a session token endpoint

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:

```bash .env.local theme={null}
BILLINGOS_SECRET_KEY=sk_test_your_secret_key_here
```

Then create an endpoint that generates a token for the logged-in user:

<CodeGroup>
  ```typescript Next.js (App Router) [app/api/billingos-session/route.ts] theme={null}
  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 });
  }
  ```

  ```typescript Next.js (Pages Router) [pages/api/billingos-session.ts] theme={null}
  import { BillingOS } from "@billingos/node";
  import type { NextApiRequest, NextApiResponse } from "next";

  const billing = new BillingOS({
    secretKey: process.env.BILLINGOS_SECRET_KEY!,
  });

  export default async function handler(req: NextApiRequest, res: NextApiResponse) {
    const userId = await getLoggedInUserId(req);

    const { sessionToken, expiresAt } = await billing.createSessionToken({
      externalUserId: userId,
      expiresIn: 3600,
    });

    res.json({ sessionToken, expiresAt });
  }
  ```

  ```typescript Express [routes/billingos-session.ts] theme={null}
  import express from "express";
  import { BillingOS } from "@billingos/node";

  const billing = new BillingOS({
    secretKey: process.env.BILLINGOS_SECRET_KEY!,
  });

  const router = express.Router();

  router.get("/api/billingos-session", async (req, res) => {
    const userId = req.user.id;

    const { sessionToken, expiresAt } = await billing.createSessionToken({
      externalUserId: userId,
      expiresIn: 3600,
    });

    res.json({ sessionToken, expiresAt });
  });
  ```
</CodeGroup>

<Tip>
  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.
</Tip>

## Step 3: Add the provider

`BillingOSProvider` wraps your app and handles fetching the session token automatically.

```tsx app/providers.tsx theme={null}
"use client";

import { BillingOSProvider } from "@billingos/sdk";

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <BillingOSProvider sessionTokenUrl="/api/billingos-session">
      {children}
    </BillingOSProvider>
  );
}
```

```tsx app/layout.tsx theme={null}
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)

<Note>
  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.
</Note>

## Step 4: Add a pricing page

Drop in the `PricingTable` component. It fetches your products and renders a complete pricing page with built-in checkout.

```tsx app/pricing/page.tsx theme={null}
import { PricingTable } from "@billingos/sdk";

export default function PricingPage() {
  return (
    <div className="max-w-5xl mx-auto py-16 px-4">
      <PricingTable />
    </div>
  );
}
```

When a customer selects a plan, the checkout modal opens automatically — no extra code needed.

<img src="https://mintlify.s3.us-west-1.amazonaws.com/billingos/images/pricing-table.png" alt="PricingTable component" />

## Step 5: Test it

Start your dev server and visit `/pricing`:

```bash theme={null}
npm run dev
```

You should see your products displayed as pricing cards. Click any plan to open the checkout modal.

<Note>
  **Test card number:** Use `4242 4242 4242 4242` with any future expiry date and any CVC.
</Note>

***

## What's next?

<CardGroup cols={3}>
  <Card title="Show a pricing page" icon="tags" href="/guides/show-a-pricing-page">
    Customize your pricing table with filters, themes, and custom actions.
  </Card>

  <Card title="Manage subscriptions" icon="user-gear" href="/guides/manage-subscriptions">
    Add a self-service customer portal.
  </Card>

  <Card title="Gate features" icon="lock" href="/guides/gate-features">
    Control access to features based on plan.
  </Card>
</CardGroup>
