Skip to main content
bankroll.session() resolves the Bankroll session token — a signed JWT scoped to your app that identifies the current user. Send it to your server in the x-bankroll-token header and verify it there before trusting anything in it.
The first call may ask the user to connect your app; later calls resolve without re-prompting. Tokens are short-lived (~15 minutes) — the SDK caches the current one and mints a fresh one before it expires, and concurrent calls share one mint, so repeated calls are cheap.

Requiring a verified user

session({ identity: true }) resolves only once the user has been verified by Bankroll. A person can verify only once, so a verified session maps to one real person. That supports per-person — rather than per-account — enforcement on your side:
  • Multi-accounting — a second account for the same person can’t produce a second verified session.
  • Limits — deposit, loss, and time limits keyed to a person, not an account.
  • Eligibility & AML — verified age and region as inputs to your own compliance checks.
If the user isn’t verified yet, Bankroll runs them through verification and resolves once they finish; if they don’t complete it, the promise rejects with verification_declined. Plain session() works before verification — use it for free-to-play, and require { identity: true } before real-money play if your rules call for it.
An older Bankroll app that can’t run verification rejects { identity: true } with update_required.

Send it to your server

The token travels in the x-bankroll-token header. Decorate fetch once and every request carries it:
In a plain browser (status 'unavailable') requests go out bare and your server responds 401. Any other failure — including the user declining — propagates.

Verify it on your server

Never trust a session token that hasn’t been verified. In Node, verify with verifyToken:
It checks the RS256 signature against Bankroll’s public keys, the issuer, and that the token was minted for your origin. It accepts null/undefined and returns null on any failure, so one if (!session) covers missing, forged, expired, and wrong-app tokens alike. On other stacks, verify the JWT directly:
Always check aud equals your own origin, byte-for-byte — https, lowercase host, no default port, no trailing slash. The token is scoped to your app, so a token minted for a different app must not sign a user into yours. Also fetch the keys from the JWKS URL and cache them — never hard-code a key.
See the Quickstart for full verification snippets in Node.js, Ruby, and Python.

The session

A verified token gives you the session and the user inside it:
The session carries the envelope and the request’s geo — the user’s location for this session, not their residence. The user fields are durable per-person attributes.
Wire names: in the raw JWT, user.wallet is the sub claim and user.identity is delivered as kyc. The SDK exposes the friendly names; if you verify raw JWTs on another stack, read sub and kyc (treating an absent kyc as not-verified).

Gating eligibility

Real-money eligibility is a server-side decision, computed from the verified session — never from an unverified client value:
  • session.user.identity (truthy) — the user has cleared verification. false means not verified.
  • session.user.identity.age — the user’s verified age, for age-restricted play.
  • session.geo — the user’s region for this session, for where-you-can-play rules.

Handling a decline

session() rejects with a BankrollError whose code is consent_declined if the user declines the connection; session({ identity: true }) rejects verification_declined if they back out of verification. Catch either and show your own “connect to continue” state rather than surfacing an error.