More ways to earn
The verified-view loop is the core, but the same wallet and ledger carry three more claim surfaces. Each pays from a funding program, exactly once, at claim time — the mechanics differ, the guarantees don't.
1. Scan-to-claim
For surfaces where the viewer can't tap the ad itself — print, packaging, a screen across the room — the ad carries a scannable code and the claim moves to the viewer's phone.
- 1
The surface asks for a token. When the publisher's
delivery_reportincludes"claim_surface": true, the202response carries a signedclaim_tokento render as a QR code or short link. - 2
The token is short-lived and single-use: signed (HMAC-SHA256), bound to that view's nonce, publisher, and creative, and valid for 15 minutes.
- 3
The viewer scans and earns. Redeeming —
POST /v1/claims/redeemwith the wallet session — pays the award to the person who scanned, at the funding program'sscanrung rate. - 4
One view pays once. While a scan token is outstanding on a view, the device-claim path for that view is refused — so a view can never pay both the device holder and a scanner.
2. Receipt cashback
Merchants reward real purchases: the viewer photographs a receipt in the wallet, and the claim is verified without the receipt's contents ever leaving the phone in readable form.
- 1
The merchant enrolls with our team: a merchant ID, the funding program that pays, a cashback basis-point rate (
cashback_bps), and sensible caps per visit and per user per month. - 2
The wallet claims:
POST /v1/cashback/claims (wallet session + user token)
{ "merchant_id": "m_7", "subtotal_cents": 4200, "items_total_cents": 4600,
"receipt_hash": "…SHA-256 of the receipt image, computed on-device…",
"visit_at": "2026-09-27T18:30:00Z" }
→ { "id": "…", "merchant_id": "m_7", "receipt_hash": "…",
"subtotal_cents": 4200, "award_pts": 42, "program_id": "…",
"txn_id": "…", "visit_at": "…", "claimed_at": "…" }
- The hash is computed on the device; line items and payment details are never sent — only the subtotal, the hash, and when the visit happened.
- Idempotent: the same viewer resubmitting the same receipt gets the
existing claim back (
200). A different viewer submitting the same receipt gets409 receipt_already_claimed— one receipt, one reward. - The award is drawn from the merchant's funding program at claim time, like every other
surface (
source_kind: "cashback"in webhooks and earnings).
3. Out-of-home capture
Billboards, transit, and posters can't be clicked — but they can be photographed. A capture claim proves the viewer was in front of a real placement during its flight.
- 1
Sites and flights are set up with our team: a site (
name;kind— billboard, transit, poster, or other; latitude/longitude and a capture radius) and a flight (the creative, its advertiser, the creative's perceptual hash, the site, start/end, and the funding program). - 2
The wallet captures: the app computes the photo's 64-bit perceptual hash on-device and posts the claim — the photo itself is never uploaded.
POST /v1/ooh/claims (wallet session)
{ "phash": "9f3ac41bd207e855", "lat": 32.7767, "lon": -96.797,
"captured_at": "2026-09-27T18:30:00Z",
"creative_id": "adv_42:cre_7", "site_id": "site_3" }
- The claim matches when the hash matches a live flight's creative and the location is inside the site's radius at capture time.
- Outcomes are explicit:
422 no_matching_campaign,422 capture_limit_reached,429 velocity_exceeded,503when the funding program is exhausted. Resubmitting the same photo returns the existing claim (200). - Payouts land as
source_kind: "capture", drawn from the flight's program at claim time.
How these show up
All three surfaces pay into the same wallet and ledger as verified views. Viewers see them
in their earnings breakdown (filterable by app or device, over day / week / month / all
time); funders see each draw in their program transactions and in
points.issued webhooks, distinguished by source_kind
(scan, cashback, capture) and rung.