Skip to main content
The webview is a single-page React app you embed inside your native app via a WebView / Custom Tab. The URL is:
https://voucher.example.com/consumer#token=<JWT>
We also accept #access_token=<JWT> as a synonym, so partners that already mint OAuth-style fragments don’t need to special-case our handler.
Use the URL hash, not a query string. Query strings end up in server access logs and analytics; the hash fragment never leaves the user’s device.

What happens when the webview loads

  1. The page reads the JWT from location.hash (#token= or #access_token=).
  2. It calls GET /me with Authorization: Bearer <jwt> to bootstrap the user and your brand block (logo, displayName).
  3. The catalog renders, scoped to your partner’s allowlist (if configured).
  4. The same JWT authenticates every subsequent /me/* request.

Brand rendering

GET /me returns a partner object containing your brand assets. The webview swaps its default chrome (e.g. GPS pill) for your logo when this is present, so the embedded UI feels native to your app. To change the logo, update it in our admin UI — the webview reads current state on every page load, no deploy needed.

Token lifetime

  • JWTs should be short-lived (≤ 1 hour exp).
  • If the JWT expires while the user is in the webview, the next API call returns 401 invalid_token. The webview will show a “session expired” state and your app should re-mint a fresh JWT and reload.
  • There is no refresh-token flow between partner and us — the partner app is the identity source and re-mints on demand.

Building your own UI instead

If you’d rather render the voucher list in your own native UI, skip the webview entirely and call the Consumer API directly with the same JWT. You’ll still want to receive webhooks for redemption events.