> For the complete documentation index, see [llms.txt](https://docs.tiun.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tiun.io/guides/time-based-billing/charge-for-time-based-sessions.md).

# Charge for time-based sessions

This guide walks you through wiring up a time-based paywall — the user connects a payment method, opens premium content, and is billed for the time they spend with it. By the end, you'll have a paywall, a billing session, and content metering.

***

## 1. Create a time-based product

Create a time-based product in the dashboard and copy its product ID. The full walkthrough is in [creating your first product](/guides/getting-started/creating-first-product.md) — choose **Time-based** as the product type.

***

## 2. Install and initialize the SDK

Install `@tiun/sdk` and call `tiun.init` once at startup. The [Quickstart](/quickstart.md) has the full install commands.

```javascript
import { tiun } from '@tiun/sdk';

tiun.init({
  snippetId: 'YOUR_SNIPPET_ID',
  language: 'en',
});
```

***

## 3. Start with the paywall visible

In time-based billing, the default state is **locked** — the user doesn't have access until they connect a payment method. Render your app with the paywall showing and premium content hidden. For the full mental model of how time-based access works, see [Time-based / How it works](/reference/time-based/how-it-works.md) in Reference.

***

## 4. Listen for paywall events

tiun tells your app when to show or hide the paywall through two events:

```javascript
tiun.on('paywallShow', () => {
  showPaywall();
  hidePremiumContent();
});

tiun.on('paywallHide', (data) => {
  hidePaywall();
  showPremiumContent();
  // data.sessionId is available for server-side verification
});
```

`paywallShow` fires when the user doesn't have access (no payment method yet, or session ended). `paywallHide` fires when access is granted and a [session](/reference/time-based/sessions.md) is active; the payload includes a `sessionId` you can pass to your backend for [server-side session verification](/guides/time-based-billing/verify-server-side.md). For the full event contract, see [Access](/reference/time-based/access.md) in Reference.

***

## 5. Start a billing session

Add a button on your paywall that opens the connect overlay. `tiun.start()` collects the user's payment method and starts their session.

```javascript
function onClickGetAccess() {
  tiun.start();
}
```

After the user connects, `paywallHide` fires and the user has access.

***

## 6. Manage content on route changes

Tell tiun what the user is viewing so it can meter and bill correctly. Call `setContent()` on every route or page change. The full list of content types, media types (audio / video), and metering behavior lives in [Protecting content](/reference/time-based/protecting-content.md) in Reference.

```javascript
function onRouteChange(path) {
  const isPaid = isPaidContent(path);

  tiun.setContent({
    type: isPaid ? 'active' : 'inactive',
    contentId: path,
  });
}
```

When content is `'inactive'`, the session pauses and the user is not billed. When it switches back to `'active'`, the session resumes.

***

## 7. Go live

If you've been testing in sandbox, set up **live as a separate environment** in the dashboard, then for production traffic:

1. Remove `sandbox: true` from your `tiun.init` (or set it to `false`).
2. Use your **live** snippet ID and live product ID (prefixed `p-live-`).
3. If you verify server-side, switch to the live API base URL and a live API key.

See [setting up your environment](/guides/getting-started/set-up-environment.md) for the full sandbox / live workflow.

***

## Full example

```javascript
import { tiun } from '@tiun/sdk';

tiun.init({
  snippetId: 'YOUR_SNIPPET_ID',
  language: 'en',
});

tiun.on('paywallShow', () => {
  showPaywall();
  hidePremiumContent();
});

tiun.on('paywallHide', (data) => {
  hidePaywall();
  showPremiumContent();
});

function getAccess() {
  tiun.start();
}

function onRouteChange(path) {
  const isPaid = isPaidContent(path);

  tiun.setContent({
    type: isPaid ? 'active' : 'inactive',
    contentId: path,
  });
}
```

***

For framework-specific implementations, see [React](/sdk/examples/react.md), [Vue](/sdk/examples/vue.md), and [Nuxt](/sdk/examples/nuxt.md) in the SDK reference.

If your backend serves premium content, also see [server-side session verification](/guides/time-based-billing/verify-server-side.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.tiun.io/guides/time-based-billing/charge-for-time-based-sessions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
