> ## 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.

# Imperative API

> Reach the underlying UnitPayClient for ad-hoc and non-React billing calls.

import LearnHooksTip from '/snippets/learn-hooks-tip.mdx';

The typed mutation hooks (`useChangePlan`, `useTopUp`, `useAttachAddon`, …) cover the common flows and integrate with React Query cache / loading / error state. `useBilling` is the escape hatch for everything else — imperative calls from event handlers, async flows, and non-render contexts.

<LearnHooksTip />

Every hook returns `isLoading: boolean` and `error: Error | null` (see [Introduction](/react/introduction)); the section below lists this hook's specific returns.

## useBilling

Returns the underlying `UnitPayClient` bound to the active portal token. Use it for ad-hoc imperative calls and non-render contexts — event handlers, async flows, anything not tied to the render lifecycle. For form submissions and anything that should integrate with React Query cache / loading / error state, prefer the dedicated mutation hooks where they exist.

**Parameters** — none.

<Warning>
  `useBilling` **throws** if no `portalToken` is set on `<UnitPayProvider>`. This surfaces the misconfiguration at first use rather than letting calls silently no-op. Only call it under a provider configured with a portal token.
</Warning>

**Returns**

* `UnitPayClient` — the imperative client instance. It exposes resource accessors (e.g. `billing.subscription(id)`, `billing.usage`) plus settlement helpers like `handleSettlement`.

```tsx theme={null}
import { useBilling } from '@unitpay/react';
import { useRouter } from 'next/navigation';

export default function ChangePlanButton({ subId, newPlanId }: { subId: string; newPlanId: string }) {
  const billing = useBilling();
  const router = useRouter();

  async function handleChange() {
    const result = await billing.subscription(subId).change({ newPlanId });
    billing.handleSettlement(result, {
      onChargedInline: () => router.push('/billing'),
    });
  }

  return <button onClick={handleChange}>Switch plan</button>;
}
```

<Tip>
  Reach for a dedicated hook first — `useBilling` is the escape hatch for flows the typed hooks don't cover.
</Tip>

## See also

<CardGroup cols={2}>
  <Card title="Settlement model" icon="arrows-split-up-and-left" href="/react/settlement">
    The `handleSettlement` outcome kinds and their callbacks.
  </Card>

  <Card title="Provider" icon="plug" href="/react/provider">
    Configure the `portalToken` `useBilling` binds to.
  </Card>
</CardGroup>
