Sample app — "Sign in with Blasts" in one file

A complete relying-party website you can run in under two minutes: connect invitation, sign-in ceremony, phone approval, local ES256 assertion verification against the public JWKS, and a real session cookie. One file. Zero dependencies. Node 18+ only.

server.js README.md package.json

Run it

1. Get sandbox keys (instant, free)

Open the Developer Console, sign in with your email, click New sandbox key. Copy the API key (pk_test_…) and signing secret (sk_test_…).

2. Start the server

# Windows (PowerShell)
$env:BLASTS_API_KEY="pk_test_YOUR_KEY"
$env:BLASTS_SIGNING_SECRET="sk_test_YOUR_SECRET"
node server.js

# macOS / Linux
BLASTS_API_KEY=pk_test_YOUR_KEY BLASTS_SIGNING_SECRET=sk_test_YOUR_SECRET node server.js

3. Sign in

Open http://localhost:3000 and sign in with the same email you used on the console — sandbox keys can only ring their creator's phone (that's a safety feature, not a limitation of your future live keys). First time through you'll approve the connection on your phone once, then sign in.

The sample calls the LIVE production API with your sandbox keys — sandbox is free (0 credits) and fenced to your own account. Nothing to deploy, nothing to configure.

What it demonstrates (copy this shape)

RuleWhere in server.js
Secrets stay server-side. API key, HMAC secret, and poll_secret never reach the browser — the page only sees the 6-digit display code and a request id, and polls your server, which polls us.blasts(), /auth/start, /auth/poll
The assertion is the login. No session until the ES256 JWT verifies — locally against the JWKS (cache ≤ 1 h) with iss/aud/exp/typ checks, or via POST /login/verify as the fallback. status:"approved" alone is never trusted; assertion_unavailable:true is monitoring, not authentication.verifyAssertionLocal()
Replay fenced. jti is deduped — a replayed assertion cannot mint a second session.seenJtis
Pairwise identity. sub is stable for (user, your app) and useless to correlate across apps — key your user table on it. The token never carries the email.session creation in /auth/poll

The flow, end to end

Browser                Your server                    api.blasts.app              User's phone
   │  email             │                                   │                          │
   ├───────────────────►│  POST /login/connect (HMAC)       │                          │
   │                    ├──────────────────────────────────►│──── consent invite ─────►│
   │   "check phone"    │◄── {status:"invited"} ────────────┤                          │
   │◄───────────────────┤                                   │        (user approves    │
   │  sign in again     │  POST /login/request (HMAC)       │         the connection)  │
   ├───────────────────►├──────────────────────────────────►│                          │
   │   6-digit code     │◄── {request_id, challenge,        │                          │
   │◄───────────────────┤     poll_secret (KEPT HERE)} ─────┤──── approval card ──────►│
   │  poll /auth/poll   │  POST /login/status (loop)        │   (user types the code)  │
   ├───────────────────►├──────────────────────────────────►│◄─────── approve ─────────┤
   │                    │◄── {status:"approved", assertion} ┤                          │
   │                    │  verify ES256 vs JWKS (local)     │                          │
   │  session cookie    │  mint session on VERIFIED claims  │                          │
   │◄───────────────────┤                                   │                          │

Full endpoint contracts: Login API guide · API reference · OpenAPI spec. Mobile SDKs (Swift/Kotlin/React Native) with the same ceremony embedded in-app are on the BlastsKit roadmap — this sample is the server-side pattern they all sit on.

Questions: AL@SavingsSites.com