# Advanced

> Multiple surfaces, the session lifecycle, credits and metering, and testing your integration — once the basics are wired.

Once the token route and Provider are wired and the agent can act, four things are worth knowing. None of them are extra setup — they're behaviours the runtime already has, and the shape of a larger integration.

## Multiple surfaces

Declare a `useSurface` on each route, next to the state that route already owns — not one global surface for the whole app. It's active only while its component is mounted, so as the user navigates the active surface swaps automatically and the agent always knows where they are and what's on screen:

```tsx
// app/tasks/page.tsx
useSurface({ label: "Tasks board", data: { remaining } });

// app/settings/page.tsx
useSurface({ label: "Settings", data: { plan } });
```

You name only the human `label`; the SDK derives a stable internal id from it, so there's nothing to keep unique across routes. Hang each route's [elements and actions](/docs/actions-surfaces) off the same component and they come and go with the surface.

## Session lifecycle

A voice session winds down on its own when no one's interacting, so an abandoned tab doesn't burn minutes: after about **45 seconds** of no interaction it goes idle, and if nothing happens for roughly **120 seconds** more, the session ends. This is automatic and not yours to manage — click the button again to start a fresh session. Don't build keep-alive logic around it. (Those are the defaults; the exact thresholds are set on our side, not a prop you configure.)

## Credits & metering

Voice usage is metered by the minute. When a workspace runs low the SDK surfaces a credit/banner state so the user isn't cut off without warning. For the self-serve product this is handled for you — billing and top-ups live in the portal, and you meter nothing in your own code.

## Testing your integration

`useAction`, `useSurface`, and `useElement` are ordinary React hooks, and the handlers you pass them are ordinary functions — unit-test those handlers directly, with no agent in the loop. The hooks themselves no-op without a Provider, so a hook test only needs to assert what your app does, not the wire. To confirm the agent actually perceives your annotations end to end, use the [Watch panel](/docs/watch) — its Catalogue tab is the ground truth for what's exposed.
