Skip to main content
The widget is an enterprise/platform feature. It puts a live credit balance, optional recent transaction history, and an Add credits button in your product. The button opens a Locus-hosted Stripe Checkout, so end users top up their own balance and you never build billing UI. There are two builds with identical behavior: @withlocus/credits-react for React apps and @withlocus/credits-js for a plain script tag.
Your workspace needs secret and publishable keys. Evaluation workspaces can use the widget and customer top-ups; evaluation status does not enable payouts or Stripe Connect. Personal accounts use Credits in the dashboard instead and do not expose publishable keys or end-user balances.

How it authenticates

The widget runs in the browser, so it authenticates with your publishable key (lcrpk_…, safe to expose) plus a short-lived end-user token you mint server-side. The token is scoped to one user: it can read that user’s balance and ledger, open a top-up, and authenticate metered burns charged to that user’s balance. It is an end-user credential, not a tenant key or an lcac_… agent connection credential. Tokens expire after an hour at most, so mint one per page load or refresh as needed.
1

Mint a token on your server

Using your secret key, mint a token for the signed-in user:
2

Render the widget with it

Pass the publishable key and that token to the widget (below). Never put the secret key in the browser.

React

Prefer to build your own UI? The hook gives you the raw state:

Plain HTML / script tag

No build step: drop a script tag and a target element on the page.
balance() returns a handle with refresh() and destroy(). The ESM build (import { balance } from '@withlocus/credits-js') is available too.

Show transaction history

Set showPerCallPricing to show the five most recent entries from the signed-in user’s transaction history. The list includes metered charges, top-ups, allocations, and refunds. It refreshes with the balance and displays amounts in your credit denomination. Both React and plain JavaScript use the self-scoped GET /api/credits/me/ledger endpoint. The end-user token determines whose history is returned; a browser cannot select another externalUserId. Locus removes your base cost, markup, margin, tenant identifiers, and other internal pricing configuration from this response. For a custom React UI, call the exported helper with the same browser authentication:
See Own transaction history for cursor pagination and the complete response.

Render the provider catalog

Both browser packages export fetchCatalog. It follows opaque cursors and returns policy-filtered providers keyed by stable IDs:
The response contains only the user’s final credit/USD price. It cannot reveal your base cost, markup, margin, credentials, tenant identifiers, or payout configuration.

Customization

Both builds share the same options:
The widget shows the end-user only their balance and your credit prices. Base prices and your margin never reach the browser.

The end-user experience

1

Sees their balance

The widget renders the current balance in your credit denomination (e.g. 4,935 credits) and refreshes on a poll. When you enable showPerCallPricing, it also shows the five most recent transactions.
2

Clicks Add credits

A Locus-hosted Stripe Checkout opens in a popup for topupCredits worth of credits. Card data never touches your app.
3

Balance updates

On completion the popup closes, the balance refreshes, and onTopup fires. From then on their metered calls draw down this balance.

Funding & billing

The full money flow behind the button.

SDK reference

endUserToken, balance, and the rest.