Skip to main content
A Built-for-Bankroll app is a web app served from your own HTTPS origin — any framework.

Step 1 — Install the SDK and detect the host

Your app will run in three places: a plain browser, an outdated Bankroll app, and a current Bankroll host. bankroll.status() tells you which — synchronous, safe anywhere, including SSR (always 'unavailable' on the server).

Step 2 — Serve your manifest

Serve a manifest at /.well-known/bankroll.jwt on your app’s origin. It declares your app’s name and icon, the capabilities it uses, and the address that receives payments. It’s an Unsecured JWT (alg: none, empty signature) — Bankroll binds it to your app by fetching it from your origin, so there’s no key to manage. On Next.js, manifestRoute() is the whole route — you declare what’s yours and the SDK owns the format:
app/.well-known/bankroll.jwt/route.ts (Next.js)
On any other stack, build the two Base64URL segments yourself — see The manifest for Node, Ruby, and Python. Bankroll fetches this over HTTPS — if it’s missing or malformed, your app won’t be granted any capability. To show an icon, also serve a square PNG at /.well-known/bankroll-icon.png. See The manifest for every claim and rule.

Step 3 — Identify the user

The user’s verified session travels as a signed token in the x-bankroll-token header. The simplest way to send it is to decorate fetch once:
Client
Or attach it manually — bankroll.session() resolves the token (the SDK caches it and re-mints before expiry, so repeated calls are cheap):
Client (manual)
On your server, verify the token — never trust an unverified token from the client. session.user.wallet is the user’s stable id. On Next.js this is one call, with the audience taken from the request’s own host so there’s no origin constant to keep in step — see Next.js helpers:
app/api/session/route.ts (Next.js)
On any other stack, verify it directly:
Verify the audience equals your origin, byte-for-byte: https, lowercase host, no default port, no trailing slash (e.g. https://acme.example). The token is scoped to your app; a token minted for someone else’s app must not authenticate a user on yours.
See The session token for every claim and what it means.

Step 4 — Charge the user

Call bankroll.charge() with an amount in whole US cents. Bankroll shows the user the charge, moves the funds to the address your manifest fixes in capabilities.payments, and resolves with the settled payment’s signature. The call cannot name a recipient.
Client
Every failure is a BankrollError with a stable snake_case code. Handle insufficient_funds, payment_denied, and consent_declined as shown above without surfacing an error; propagate anything else. On your server, confirm the returned signature settled the expected amount to your payment address before granting value. See Payments.

Step 5 — Launch your app

Users open your app with a Bankroll deep link — your app’s URL, URL-encoded:
The SDK builds it for you:
When a user shares that link rather than you, pass their wallet and Bankroll credits them for anyone new who joins through it — see Share links:
Opening that link on a device with Bankroll installed launches the app and loads your site in the host webview. The URL must be HTTPS, and its origin must resolve to a valid manifest (Step 2).

Step 6 — Test the round trip

  1. Open your /play deep link on a device signed into Bankroll.
  2. Your site loads; your first session()/charge() call runs.
  3. session() returns a token your server verifies (Step 3).
  4. charge() returns a signature your server confirms (Step 4).

Going live

No registration or approval is required: once your manifest is served, your /play link opens your app for any Bankroll user. To pay users back — winnings, refunds — see Paying a user. Being bundled in the Bankroll app itself (featured, first-party placement) is a separate step that requires Bankroll approval — ask in the Built for Bankroll Discord.