Skip to main content
The createSessionRouteHandler shipped with the App Kit SDK is a drop-in session route for any host that uses the Fetch API standard (Next.js, Hono, Cloudflare Workers, Bun, Deno, modern Node). The default handler is unauthenticated. Most apps need to customize it in these areas:
  • Authenticate so only signed-in users can mint sessions.
  • Log or inspect session minting failures.
  • Mint sessions from a host that does not use the Fetch API.

Add authentication

On Fetch-compatible hosts, create the handler once with createSessionRouteHandler and register it as POST /api/onramp/sessions in your router. See the embed widget quickstart for a full example.
Add an authorize callback. The callback runs before the body is validated and can return true (allow), false (reject with 401), or throw a KitError (rejected with the corresponding status):
You can also validate that the request body matches the signed-in user:
The handler’s body validation runs after authorize returns, so an unauthenticated request is rejected with 401 before any payload is parsed.

Customize error handling

createSessionRouteHandler maps thrown errors to HTTP status codes automatically. Using the same server and handleOnrampSession from above, pass an onError callback:
onError runs after the error is mapped to a response, so the response is still returned. The callback is for observability. It does not change the status code or body. See the error handling reference for the full error to status mapping.

Use a non-Fetch host

createSessionRouteHandler only works on runtimes that pass standard Request objects. Express and Fastify pass their own request and response objects, so call server.onramp.createSession() directly instead. You’re now responsible for the error mapping the Fetch handler did automatically. Map KitError.type to HTTP status the same way createSessionRouteHandler does. See the HTTP status code mapping for the full mapping. Shape error response bodies to match your API.
Add authentication in front of this route, like any other endpoint in your app.

Limit the tokens and blockchains the widget supports

By default, the Onramp widget shows its full catalog of supported tokens and blockchains. If your app only handles a subset, pass an assets object on the session request to narrow what the widget’s selector displays.
You can set any of three fields:
  • tokens: an array of token symbols such as USDC, EURC, or ETH. The widget shows those tokens on every blockchain that supports them.
  • chains: an array of blockchains, matched by either the network id (arc, base, ethereum) or the display label (Arc, Base, Ethereum). Matching is case-insensitive. The widget shows every supported token, restricted to those blockchains.
  • pairs: an array of exact token and blockchain combinations. Use this when you need finer control than tokens and chains allow.
If you set more than one field, the widget only shows options that match every field you set. Omit assets to show the full set of supported tokens and blockchains. See Supported blockchains and tokens for the current list.
assets scopes what the selector displays. It doesn’t override the widget’s eligibility, geo, or quote logic. A token or blockchain listed in assets can still be unavailable for a specific user if they’re geo-blocked or otherwise ineligible.

Allow your page to embed the widget

The widget page enforces a frame-ancestors Content Security Policy so only approved parent sites can embed it. The allowlist is built from a referrerDomain you set when constructing the server kit. Pass it as a bare hostname on createAppServerKit:
Keep the following in mind when setting referrerDomain:
  • Format: Use a single bare hostname such as app.example.com or localhost. Don’t include a scheme, port, or path.
  • Source: Derive referrerDomain server-side from your app’s per-environment config. A browser-supplied Origin or Referer header would let attackers widen the allowlist.
  • Sandbox: referrerDomain isn’t enforced. Set it anyway to verify your wiring before promoting to production.
  • Production: Debit card, Apple Pay, and Google Pay flows fail with a 403 if the domain isn’t registered in your KYB’s web_url entries.