Skip to main content
Bankroll reads https://<your-origin>/.well-known/bankroll-status when it shows your tile. Answer with what you have on offer for the person asking and the tile gets a ring and your headline; answer nothing and it doesn’t. That is the whole effect: the document is decorative, per user, per moment, and grants nothing.

The request

  • GET /.well-known/bankroll-status, no ambient credentials, at most five same-origin redirects, 2 seconds, application/json, body ≤ 1 KiB. Anything else — slow, large, wrong type, unparseable — reads as “no offer”, never as an error.
  • If the user has already connected your app, the request carries Authorization: Bearer <token> naming the user, scoped to your origin — verify it with verifyToken(token, { audience: origin }) from @joinbankroll/sdk/server and answer for that wallet. It identifies; don’t treat it as a login. No token means a user who hasn’t connected you yet — respond with your generic new-user offer (a welcome bonus, a first-deposit match), the same answer for everyone.
  • Per-user answers must not be cached: send cache-control: no-store.

The response

offers is an ordered array; Bankroll shows the first entry and ignores the rest (keep it to a few — the whole body must stay under 1 KiB). The app asks once each time the Home screen mounts, draws a ring on your tile for the first offer, and clears it when the tile is tapped. An entry is an object with two optional members, or true for an offer with no details: Absent, null, [], false, or anything unrecognized means no offer.

Example

Nothing here is load-bearing: a bad token, a slow query, or an empty answer costs the user a ring, not a session. Don’t put state your app depends on behind it, and don’t tell an anonymous caller anything you wouldn’t print on a poster.