@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
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
SetshowPerCallPricing 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:
Render the provider catalog
Both browser packages exportfetchCatalog. It follows opaque cursors and returns policy-filtered providers keyed by stable IDs:
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.