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

# Portal sessions

> Mint the short-lived token that @unitpay/react consumes to render customer-facing billing UI.

Portal sessions are the bridge from your server to the browser. You mint a token here with your secret key, hand it to your frontend, and [`@unitpay/react`](/react/introduction) exchanges it for a customer-scoped billing UI — no secret key ever leaves your backend.

<Info>
  The token is a short-lived JWT scoped to one customer. Pass it to [`<UnitPayProvider portalToken={…}>`](/react/provider); every hook and component in the React SDK reads the customer from it.
</Info>

## unitpay.portalSessions.create

Mints a portal session for one customer and returns the token to embed in your frontend.

**Parameters** — `CreatePortalSessionParams`:

<ParamField body="customerId" type="string" required>
  The customer this session grants access to.
</ParamField>

<ParamField body="ttlSeconds" type="number" default="3600">
  Token lifetime in seconds. Min `60`, max `86400`.
</ParamField>

**Returns** — `Promise<PortalSession>`:

<ResponseField name="token" type="string">
  The JWT to pass to `<UnitPayProvider portalToken={…}>`.
</ResponseField>

<ResponseField name="expiresAt" type="string">
  ISO-8601 timestamp when the token expires.
</ResponseField>

Mint the token in a server route and return only the token to the browser:

```ts app/api/portal-session/route.ts theme={null}
import { UnitPay } from '@unitpay/node';

const unitpay = new UnitPay({ apiKey: process.env.UNITPAY_API_KEY });

export async function POST(req: Request) {
  const { customerId } = await getSession(req); // your auth

  const session = await unitpay.portalSessions.create({
    customerId,
    ttlSeconds: 3600,
  });

  return Response.json({ token: session.token });
}
```

## unitpay.portalSessions.revoke

Invalidates portal tokens before they expire — for logout, or when a customer's access changes. Revoke a single session by its `jti`, or every active session for a customer.

**Parameters** — `RevokePortalSessionParams` (one of):

<ParamField body="jti" type="string">
  Revoke a single session by its JWT ID.
</ParamField>

<ParamField body="customerId" type="string">
  Revoke all active sessions for this customer.
</ParamField>

**Returns** — `Promise<void>`.

```ts theme={null}
// Revoke every session for a customer (e.g. on account suspension)
await unitpay.portalSessions.revoke({ customerId: 'cus_123' });
```

## See also

<CardGroup cols={2}>
  <Card title="React SDK" icon="react" href="/react/introduction">
    Build the customer-facing billing UI the token powers.
  </Card>

  <Card title="UnitPayProvider" icon="plug" href="/react/provider">
    Where the portal token is consumed.
  </Card>
</CardGroup>
