Booms Protocol — BSP Draft 0.1
Status: draft, published 2026-09-12 — not a standard. The word "standard" is earned at L4: two implementations that never shared a vendor stack completing issue → redeem → settle → reverse against each other. Until then this is a working spec plus a working reference implementation.
One-sentence definition: BSP is the shared contract that lets any issuer create a portable, machine-readable dollar reward and lets any wallet, merchant, or agent apply, attribute, and settle it without sharing a vendor.
BSP is an open, wallet-neutral protocol for issuing, discovering, quoting, authorizing, redeeming, attributing, settling, and reversing portable rewards. It is not a loyalty program, not a required wallet, and not a cryptocurrency. Booms Rewards is one network that implements BSP. Anyone else can implement BSP without permission. Supersedes UALP Draft v0.1 (frozen for history at /.well-known/ualp.json).
The wedge: a shopping agent that can read a standardized reward, compare effective price across merchants, buy, attribute the sale, and settle — without a custom deal per merchant. That agent is the reason this protocol exists. It is not "another points wallet."
What BSP standardizes
- What the reward is, who issued it, who may hold or spend it
- Where it can be discovered and quoted
- How it is authorized and applied at checkout
- How value is attributed and settled
- How it is expired, refunded, or reversed
Business rules stay with the issuer (earn rates, eligible SKUs, stacking, blackout dates). BSP standardizes the object and the handshake, not every program's marketing rules. What it is not: a points currency with a floating price, a requirement to store value in one company's ledger, a replacement for card networks, a guarantee every reward works at every merchant, or governance-by-tweet.
The Reward object
{
"id": "urn:bsp:reward:2f9c…",
"type": "bsp.Reward",
"spec": "bsp/0.1",
"amount": { "value": "8.40", "currency": "USD" },
"state": "issued",
"issuer": "https://merchant.example",
"holder": "https://customer.example",
"redeemable": true,
"constraints": {
"merchants": ["https://merchant.example"],
"min_basket": "25.00",
"expires_at": "2026-12-31T23:59:59Z"
},
"attribution": {
"referrer": "https://agent.example",
"campaign": "fall-26"
},
"issued_at": "2026-09-12T07:21:00Z"
}
Fiat-denominated by default — a currency amount, not a speculative token. Identities are URIs (HTTPS preferred); no blockchain ID required. Also defined: Issuer, Holder, Merchant, Wallet, Quote, Authorization, Redemption, Settlement, Reversal, CommissionAllocation, Consent, Attribution.
Lifecycle — the actual protocol
| Step | Meaning |
|---|---|
| Issue | Issuer creates a signed Reward. Delivers a reference (email, pass, QR, API). |
| Discover | Wallet/agent asks a merchant: "Does this holder have applicable rewards?" |
| Quote | Merchant returns applicable amount for this basket, after constraints. Bound to a basket fingerprint — an agent can't shop a quote and redeem against a different cart. |
| Authorize | Holder (or agent with a signed consent) approves applying a specific quote. |
| Redeem | Merchant captures the reward against an order. State → redeemed / partial. Exactly-once: the issuer's ledger single-flights redemption, so double-spend is a ledger property, not a hope. |
| Settle | Obligations recorded: merchant subsidy, holder credit, affiliate/agent cut, network fee. Netted per period; adapters are card, ACH, wallet balance, or stablecoin. |
| Reverse | Cancel, refund, fraud, or expiration rolls state and settlement back coherently. |
Discovery, quote accuracy, authorization under load, settlement, reversals, double-spend, expiry, and fraud are the product — the JSON object is just the handshake.
Allocation — economics in the protocol, rates not frozen
{
"gross": { "value": "10.00", "currency": "USD" },
"allocations": [
{ "party": "holder_or_creator", "share": "0.75" },
{ "party": "network", "share": "0.25" }
]
}
BSP defines how value is split, not a mandatory 75/25. An issuer MAY use 90/10 or 100/0 on rewards they fully fund. A network (e.g. Booms Rewards) MAY require a fee to participate in its discovery/settlement graph. That fee is network policy, not a protocol constant.
Spend-anywhere is settlement value, not face value. Skip reserves and you don't have a network; you have a promise. The pilot profile records and attests obligations without prefunded reserves — stated, not smuggled.
Design principles
- Protocol ≠ company. Spec is public. Competing implementations are expected.
- Wallet neutrality. Email, pass, bank app, retailer account, browser, agent memory, QR, or crypto wallet can hold a reference.
- Fiat-denominated by default. Crypto may be a settlement rail, never the unit.
- Issuer sovereignty. An issuer can restrict where a reward redeems. Portability is allowed, not forced.
- Agent-native. Discover → compare effective price → purchase → attribute → redeem → settle with no human dashboard.
- Reversible commerce. Returns, fraud, partial capture, expiration are first-class.
- No lock-in in the spec. Required fields stay small; extensions are namespaced.
Conformance levels
- L0 — Readable: parse and display a Reward.
- L1 — Wallet: receive, store, present a Reward reference.
- L2 — Merchant: full checkout handshake + reversals.
- L3 — Network: discovery directory, multi-party settlement, attribution.
- L4 — Independent interop: two implementations that never used the same vendor stack complete issue → redeem → settle → reverse.
L4 is the line between "a product with an API" and "a standard."
A 159-check suite exercises the canonical /bsp/v1/* wire against the actual reference-implementation code (run in workerd with test secrets; no production state): the full issue → discover → quote → authorize → redeem → settle → reverse lifecycle, exactly-once redemption, quote basket-binding, idempotency on all six mutating endpoints, the consent matrix, partial redemption and reversal, read endpoints, and the error catalog — with every returned signature cryptographically verified against the served JWKS. 159 passed, 0 failed (2026-09-12). The canonical wire is live at https://pay.brianbooms.com/bsp/v1, with an open sandbox (test key published in /.well-known/bsp.json).
A clean-room second implementation was built from the spec text alone — never allowed to see the reference code — and ran a 37-check lifecycle + adversarial suite: 37 passed, 0 failed, with every signature verified independently. It found 18 ambiguities (request envelopes, the Consent schema, state-transition signing chief among them); all 18 are pinned in the current spec revision. That second implementation was built by the same party, so it is not L4 — but the spec has now survived first contact with a blind builder. The earlier 42-check suite against the legacy merchant verbs caught two real bugs before publication (a malformed HMAC message on reversals and wrong HTTP statuses on auth failures); it is superseded by the 159-check canonical-wire suite. Honest gaps remaining: expiry-as-event untested, no load test, no second independent implementation.
What "implements BSP" means
A merchant "implements BSP" when it serves /.well-known/bsp.json and the seven verbs (discover → quote → authorize → redeem → settle → reverse, plus earn), signs objects per the JWS profile (Ed25519, JCS canonicalization, kid → JWKS), enforces idempotency keys and exactly-once redemption, binds quotes to basket fingerprints, and honors the mandate rule: no signed consent, no agent spend. Rate parity is non-negotiable: synthetic participants earn identically to humans.
Full spec: BSP Draft 0.1 (objects, endpoints, signature profile, worked examples) · Machine spec: https://brianbooms.com/.well-known/bsp.json · Live sandbox: https://pay.brianbooms.com/bsp/v1 (test key in /.well-known/bsp.json) · Walkthrough: lifecycle demo · For merchants: /rewards/partners/