@basis-theory/web-agentic
v1.1.3
Published
Browser SDK for Basis Theory Agentic Payments
Readme
@basis-theory/web-agentic
@basis-theory/web-agentic is the browser side of
Basis Theory Agentic Payments:
the customer-facing steps of the flow run here, and everything that needs a
private key stays on your server. The SDK includes AgenticVerification,
which runs the provider ceremonies that verify a customer and activate an
allowance rail.
This README covers installation and enough of the API to run a first verification. The complete reference — every option, error, and integration pattern — is in the SDK documentation.
Install
npm install @basis-theory/web-agenticTypeScript declarations are included, and the SDK has no runtime dependencies.
Or load the global bundle, which exports window.BasisTheoryAgentic. Releases
go to immutable versioned paths — pin an exact version (there is no latest)
and take its hash from the sibling sri.json:
<script
src="https://js.basistheory.com/web-agentic/1.0.0/index.js"
integrity="sha384-…"
crossorigin="anonymous"
></script>Runnable integrations for every pattern below are in examples/.
AgenticVerification
An allowance rail that requires verification is created in
pending_verification, and only a ceremony the provider itself owns can
activate it. AgenticVerification runs that ceremony: it advances the
verification state machine, renders every customer-facing step, and resolves
when the rail is active.
Quickstart
Create a public application in the
Basis Theory Portal with only the
agentic:allowance:verify permission. Runnable version:
examples/module/.
import { AgenticVerification } from '@basis-theory/web-agentic';
const av = AgenticVerification({
apiKey: 'key_test_us_pub_REPLACE_ME', // PUBLIC application key
apiBaseUrl: 'https://api.test.basistheory.com/agentic',
displayName: 'Example Agent',
});
// Read `provider` from the allowance rail — never infer it.
const result = await av.verifyAllowance('alw_...', { provider: 'vic' });
console.log(`Rail is ${result.status} on ${result.provider}`);If the customer abandons the flow, offer verification again — there is no cleanup step. Nothing the browser sends can activate a rail on its own; Basis Theory confirms every terminal transition with the provider server to server.
Never put a private key in a browser. Public keys are browser-safe by design; the SDK warns loudly if
apiKeycontains_pvt_.
| Environment | apiBaseUrl |
| ------------------------------ | ----------------------------------------------- |
| Production | https://api.basistheory.com/agentic (default) |
| Test | https://api.test.basistheory.com/agentic |
| Locally-run agentic-commerce | http://localhost:3001/api |
Browser requirements
- HTTPS top-level origin — ceremonies need a secure context. Locally:
cloudflared tunnel --url http://localhost:3000. - CSP —
frame-srcmust allow the origin of any ceremony iframe the verify response returns;connect-srcmust allow yourapiBaseUrlor custom transport endpoints; with the global bundle,script-srcmust permit the CDN script. The SDK loads no telemetry or external UI assets. - Popups — most ceremonies open a window from a user gesture; the built-in interstitials supply it. Content blockers can also stop hosted iframes.
Behavior worth knowing
verifyAllowance(allowanceId, { provider, rail?, displayName?, timeoutMs?, signal? })resolves{ status: 'active', rail, provider }.raildefaults to'agentic-token', and aborting thesignalrejects withVerificationCancelledError.- Calls are serialized — a second call while one is in flight throws. Verifying
an already-
activerail resolves without showing a ceremony. dispose()aborts any in-flight verification and tears down iframes, popups, listeners and the UI host; for a run in flight that teardown completes as the run settles. It is idempotent and leaves the instance usable, so a remount — React StrictMode, Fast Refresh — can verify again immediately, without awaiting the aborted run.- Device context is collected automatically on every start and restart;
collectDeviceContextis exported for custom transports.
The factory also accepts theming, headless, transport, and tuning options — Factory Options documents them all.
Events
onEvent receives these objects. Exceptions thrown by the callback are ignored
so observability cannot interrupt verification.
| type | Additional fields |
| --------------- | --------------------------------------------------------------- |
| state_change | allowanceId, action, status, nextActionType |
| ceremony_open | network; Visa events also include action |
| restart | reason: register_complete, state_invalid, or user_retry |
| error | error — the complete error value |
| success | allowanceId |
Errors
Errors created by the SDK extend AgenticVerificationError.
import {
ApiError,
VerificationCancelledError,
VerificationNotSupportedError,
} from '@basis-theory/web-agentic';
try {
await av.verifyAllowance('alw_...', { provider: 'vic' });
} catch (error) {
if (error instanceof VerificationCancelledError) return; // safe to offer again
if (error instanceof VerificationNotSupportedError) return; // offer another payment method
if (error instanceof ApiError) {
console.error(error.type, error.status, error.traceId); // quote traceId to support
}
throw error;
}ApiError.type is an open set — never switch exhaustively on it.
PopupBlockedError is recoverable from a new click, and the SDK retries
INVALID_OTP in place and 409 *_IN_PROGRESS with bounded backoff. Every
class and per-type behavior:
Handle Errors.
Customization
Every surface is replaceable without giving up the SDK's ownership of iframes, popups, protocols, and polling:
- Theming and copy —
appearance(six color knobs) andstringsrestyle the built-in Shadow DOM UI, which is isolated both ways and makes zero external requests. Customize the UI - Headless —
ui: falsewithhandlersbrings your own UI; passing a single handler withui: trueoverrides just that prompt. The one hard rule:confirmCeremonymust call the suppliedopenPopupsynchronously inside the click handler, before anyawait, or the browser revokes the user gesture. Bring Your Own UI ·examples/modal-states/ - Custom transport —
verifyandgetAllowanceroute API calls through your own backend instead of using a public key; ceremonies still run in the browser. Route API Calls Through Your Backend ·examples/backend/
Testing
In a test tenant, ceremonies run against Basis Theory-hosted mock pages
speaking the exact production protocols, and no request reaches a provider.
Tokenize 4242424242424242 (Visa) or 5555555555554444 (Mastercard) for the
happy paths; the
testing reference
lists the test source for every failure scenario. To run the examples:
yarn build, then npx serve . from the repo root.
Browser support
Evergreen Chrome, Edge, Firefox and Safari ≥ 16.4 (the WebAuthn baseline), on desktop and mobile web. Importing the SDK is SSR-safe, but constructing a client accesses the DOM: create the instance after mount or inside a client-only boundary, then dispose it on unmount. For webviews and native shells see Browser Support.
