Evidence
447 of 1,239 US product recalls since 2024 already refund an owner who sends one photo of the product made safe. Here is what Remedy does with that photo, measured, with the file behind every number.
6 stops in this tab, about two minutes. Escape ends it.
Start with a photo, then go further
The first step is the one the home page gives: Try a photo. The stops after it take about five minutes. A paid sandbox receipt, without sending a payout: the recorded receipt.
Try a photo, as on the home page: run Brightline's sample charger with its cord cut through the six checks and send its $34.99 refund as a real PayPal sandbox payout, or open a recorded receipt without sending one. In the sample shop, buy the charger, claim it with the sample photo, and watch the refund go back to the original PayPal purchase.
Every recall, read as a checklist20 s
On the home page, type any product into the headline. The closest recalls answer with what each one asks: what to cut or mark, and the refund.
The power bank recall's official remedy (CPSC 27056), word for word, and the checklist Claude read from it, with how sure it is of each field. Press Switch to Technical, top right, for the batch trace and the raw CPSC record.
The firm's side60 s
Brightline Home, a fictional sample firm: the claims queue, the recall plan that updates itself from PayPal's payout events, and the monthly report.
For developers and AI agents40 s
A free key and a live playground, and a recorded session of an AI assistant using the MCP tools to find a recall and open a claim.
The numbers, and where they come from30 s
The CPSC count, the extraction benchmark and the recorded photo checks, each with its source file.
Every payout runs in the PayPal sandbox. Brightline Home is a fictional sample firm. Remedy is not affiliated with the CPSC or any recalling firm.
Results
- 447 of 1,239US product recalls since January 2024 refund an owner for a photo of the product made safe.54 in 2024, 242 in 2026 so far. CPSC Recalls API and each recall’s proof rule.
- 113 of 130real CPSC remedies read with every field right by Claude with a self-check.Keyword rules: 73 of 130. Draft labels
- 7 of 7reused, copied or unclear photos stopped before any AI call: a new photo asked for, or a person at the firm.A photo of a mug for the power bank recall: right product scored 0.02, not paid.
- 0recalls mention PayPal or Venmo. The photo goes to an email address in 498 of the 525 recalls whose remedy names a photo and a refund.80.9% of all recalls cover fewer than 50,000 units.
Each section below opens on a press; a link to any part of it opens it too.
Error rates, on photos with a known answer
0 of 46 paid when they should not have been; 1 of 4 held for a person or a new photo when they could have been paid, 4 decisions on one photo.
Every recorded decision where the right answer is known: 50 decisions on 29 photos, 43 by the model and 7 settled in code before any model call: the same 7 recorded runs as the photo checks’ 7 of 7 stopped by code alone.
0 of 46
paid when it should not have been
A decision to pay a photo whose known answer is no payment: a copy, a look-alike, another product, or one not yet made safe, like a charger opened up with its cord still attached, and photos by other photographers of intact chargers, a cut cable with no charger and an unrelated cable. 28 photos.
1 of 4
held for a person or a new photo when it could have been paid
A photo whose known answer is to pay, sent to a person at the firm or asked for a new photo instead: the sample charger with its cord cut, an owner’s own photo of a product made safe. 1 photo.
That is 4 decisions on one photo, the sample charger with its cord cut, whose right-product score of 0.80 to 0.82 is under the 0.85 pass mark, so only the two reviewers verify it: 3 of 4, and 1 went to a person at the firm.
16 of 18
readings right on real CPSC recalls
The CPSC’s own photos of 3 recalled products made safe, from 2 recalls, 3 trials each at the claim path’s setting: right product 9 of 9, made safe 7 of 9. What it read
Why a code check runs before the model: with the official-picture match switched off, the model alone would have paid for the recall’s own published picture in 3 of 7 runs. On every claim the match runs first and answers that picture in a median of 98 ms with no model call, the hash comparison itself 2 ms, with no payment, so these runs count in neither rate.
Counted by src/components/evidence/errors.ts from content/verify/sweep-results.json (18 decisions: 6 photos, 3 trials each, at the claim path’s setting, Claude Opus 5.5 at medium effort, run Nov 6, 2026), content/verify/sweep-sample.json (19: Brightline’s sample charger, 13 photos, 1 trials each at the same setting, run Nov 10, 2026), content/presets/recorded/*.json (5) and content/public/verify-runs.json (8; a run that repeats a preset’s model answer is counted once). Known answers: content/verify/fixtures/cases.json and content/presets/index.json. Across all 4 model settings in the sweep, paid when it should not have been: 0 of 72.
What changes, and what is at stake
$471.1 million in refunds at the lowest stated prices; $261.2 million to $442.8 million of it goes unclaimed.
| Wait | What the page says, whose page, and when |
|---|---|
| 10 to 15 business days | “Once your registration is confirmed, your refund will be issued via check within 10-15 business days.” Real Time Results, a recall administrator's claim portal (Cuisinart grill recall), read November 8, 2026. |
| 4 to 6 weeks | “Please allow 4 to 6 weeks.” Deale International's own recall page (CasaClean steam cleaner), dated July 17, 2025, read November 8, 2026. |
| No time stated | PayPal or a gift card: “You will receive your refund fastest using PayPal”, with an email confirmation in 48 to 72 hours. Merkury Innovations' own recall page (Hot + Cool fan), recall dated June 11, 2026; page read November 8, 2026. |
| 16 to 19 seconds | Remedy, in the PayPal sandbox: from approval to a PayPal payout reaching the owner, 12 runs. PayPal marked the refund to the original PayPal purchase COMPLETED at once; PayPal says a refund takes 3 to 5 business days to reach the buyer. |
- $471.1 million
- in refunds these recalls offer at the lowest stated price: 16,705,640 units across the 442 of 447 recalls that refund a photo of the product made safe and whose CPSC record states both units and a price. The two largest recalls, 24309 and 25394, are $184.0 million of the $471.1 million (39.1%), and the median recall offers $68,000.
- $261.2 million to $442.8 million
- of those refunds stays unclaimed, at two published rates that measure different things: $261.2 million at the 44.55% the CPSC reports as its FY2025 average correction rate across recalls, measured by a method revised in FY2024; $442.8 million if about 6 in 100 recalled units come back, the CPSC’s figure for how many products return after a recall.
- $4.7 million
- goes back to owners for each extra point of return, one more product in every 100.
Counted from the CPSC records and each recall’s proof rule; pro-rated refunds and recalls that state no price are left out, not estimated. The method and the largest recalls
One photo, two firms
A photo already claimed at one firm is held at the next before any model call; only a hash and a row id cross. In a replay of the docket's pattern, the pool held 308 of 400 copies of one claimed photo. Measured on 117 reused copies of 9 photos: the two hashes together catch 108 of 117 across firms, with 0 unrelated matches; the difference hash alone catches 74 at its 4-bit threshold across firms (85 at 10 bits), with 0 unrelated matches.
Every claim photo is checked against every photo already claimed, at any firm, by its hashes alone. Here is that check across two firms, recorded with no model call. Both firms and their recalls are fictional samples.
1. At Brightline Home Sample recall BH-2026-01

The photo of the cut cord is verified and paid. The claim keeps one row for later checks: the photo’s hash.
337bfb9f4e7f3e0f2. What crosses between firms
Only a row id that opens nothing at the other firm and the 64-bit hash. No photo, claimant, amount or recall reaches Fernway Home.
{ ref, dhash }3. At Fernway Home Sample recall FW-2026-01
The same photo is held for a person before any model call, in 103 ms: “This photo matches one sent with a claim on another recall, so a person at the firm will take a look.”
With Brightline Home’s hash left out of the pool, the same photo goes on to the model step, so the hold comes from the shared hash.
Recorded by scripts/public/record-network-run.ts into content/public/network-run.json, through the verifier a claim uses (src/lib/verify) with the pool the claim route reads from image_hash; tests/network-run.test.ts runs it again. Photo: Dmitry G, Wikimedia Commons, public domain.
The docket’s pattern, replayed
A comment on the CPSC’s 2026 docket on recall claims (CPSC-2026-0067) describes one device filing over 400 claims with photos taken from the same vantage point. This replays that pattern in code, not the real claims: one photo already claimed at Brightline Home, 400 copies of it made with the changes measured below (one to three each, saved again, resized, cropped, turned, brightened, screenshotted or mirrored), filed by turns at Brightline Home and Fernway Home through the claim path’s hash step, with no model call.
The pool held 308 of 400 before any model call. Fernway Home, which had never seen the photo, held 160 of its 200: its first by Brightline’s hash, and each held copy then joined the pool, as the claim route keeps every claim not asked for a new photo. Code asked for a new photo on 14 more (9 shrunk too far for the photo-quality check). The 78 that went on to the model step are all phone screenshots, which the own-photo check reads for a screen; their answers are not replayed, and they are left out of the pool, which can only lower the count. None was paid. A claim took a median of 55 ms.
Recorded by scripts/public/docket-replay.ts (seed 20138) to content/public/docket-replay.json; tests/docket-replay.test.ts makes and files the first claims again.
What the pool catches, measured. Measured on 117 reused copies of 9 photos: the two hashes together catch 108 of 117 across firms, with 0 unrelated matches; the difference hash alone catches 74 at its 4-bit threshold across firms (85 at 10 bits), with 0 unrelated matches. Only the phone screenshot copies get past both. A copy that gets past the hashes is still read by the vision check and the other five checks.
Where the idea comes from. Microsoft PhotoDNA makes a hash of an image that cannot be turned back into the image and compares it with the hashes of known images; Microsoft offers it free to qualified organizations and donated it to the National Center for Missing & Exploited Children. StopNCII makes the hash on the person's own device, sends only the hash, never the image, and its partner platforms look for matches. Remedy's pool is open code, holds recall photos, and shares only two 64-bit hashes and a row id between firms.
- Who may write
- Firms connected to Remedy, each with a key tied to its firm (scope hash-pool:register), issued when the firm connects. Claims a firm takes on Remedy add their photo's hash as they are checked. A self-serve sandbox key can check but not register, so the pool holds only photos a firm has handled.
- Who may read
- Anyone, with or without a key: POST /api/v1/hash-pool/check answers whether a hash is within range of one already in the pool or a published recall picture.
- What crosses
- Only the 64-bit hashes and an opaque ref. No photo, no name, no contact and no firm: the registering firm is kept in Remedy's own audit ledger, never in the pool row or an answer.
A connected firm joins the same check through two documented calls, from its own systems: register the hash of a photo it has paid on, with its own firm key, and ask about a hash before it pays, with no key at all. Here are four real calls made with curl from outside the app on November 9, 2026, with their answers as the server gave them. They were recorded against a local build of this code; each command is printed with this server’s address, so it runs as shown.
1. A self-serve key tries to register
A self-serve sandbox key from the Developers page tries to register the same hash: only a key tied to a connected firm may write to the pool.
curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer rm_test_..." -d '{"dhash":"337bfb9f4e7f3e0f","recall_number":"BH-2026-01","ref":"partner-demo-1"}' /api/v1/hash-pool/register{ "data": null, "meta": { "request_id": "req_d4ecbcb675a34ed28531", "version": "2026-11-05" }, "error": { "code": "forbidden", "message": "This key can check hashes but not register them. Registering is for firms connected to Remedy, each with a key tied to its firm (scope hash-pool:register), so the shared pool holds only photos a firm has paid on. Request id: req_d4ecbcb675a34ed28531", "docs": "/developers/docs#errors-forbidden" } }2. Brightline registers the hash with its firm key
Brightline Home has paid a claim on this photo and registers its hash for its own recall, with its own firm key and opaque ref.
curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer rm_test_..." -d '{"dhash":"337bfb9f4e7f3e0f","recall_number":"BH-2026-01","ref":"partner-demo-1"}' /api/v1/hash-pool/register{ "registered": true, "ref": "partner-demo-1", "dhash": "337bfb9f4e7f3e0f", "note": "In the pool. A photo within 4 bits of this hash, sent on any other recall at any firm, is now held for a person." }3. Fernway asks about the same photo
Fernway Home receives the same photo on its own recall and asks the pool with the hash alone.
curl -X POST -H "Content-Type: application/json" -d '{"dhash":"337bfb9f4e7f3e0f","recall_number":"FW-2026-01"}' /api/v1/hash-pool/check{ "hit": true, "distance": 0, "threshold_bits": 4, "ref": "partner-demo-1", "source": "partner", "pool": { "claim_rows": 0, "partner_rows": 1, "published_pictures": 1779 } }4. Fernway asks about a photo of a mug
A photo of a mug, never claimed anywhere, asked the same way: no hit.
curl -X POST -H "Content-Type: application/json" -d '{"dhash":"22626e3a339458d1","recall_number":"FW-2026-01"}' /api/v1/hash-pool/check{ "hit": false, "distance": null, "threshold_bits": null, "ref": null, "source": null, "pool": { "claim_rows": 0, "partner_rows": 1, "published_pictures": 1779 } }
What crossed: the 64-bit hash and an opaque ref that opens nothing and names no firm. Each key is masked here; the firm that registered is kept in Remedy’s audit ledger, never on the pool row. Recorded by scripts/public/record-hash-pool-call.ts into content/public/hash-pool-call.json; tests/hash-pool.test.ts checks the same comparison with no database. Both endpoints are in the API docs.
The same hash against a reused photo
The 9 photos in the repo with a known answer, each put through 13 changes a reuser makes, give 117 copies. With both hashes at the thresholds in use, 108 of 117 are caught across firms, with 0 unrelated matches. The difference hash alone, against the source photo’s stored hash, catches 74 of 117 at 4 bits (every other recall and firm) and 85 at 10 bits (the same recall’s earlier claims). Against the 1,776 published pictures of other recalls and the other 8 photos, none of the 117 copies comes within 4 bits of a picture it is not a copy of (0 of 117); 23 come within 10, which is why that wider threshold is used only within one recall. The nearest unrelated picture is 6 bits away.
A second hash for crops and turns
Beside the dHash, every claim photo gets a second 64-bit hash of its center (70 percent of each side, the lowest frequencies of a DCT), compared in 13 framings: as stored, a little wider for a crop, turned back a few degrees, and mirrored. On the same 117 copies it catches 108 at 6 bits, and either hash catches 108 of 117 at the thresholds in use (4 bits for the dHash across firms, 6 for the second), with 0 unrelated matches against the same 1,776 published pictures and 8 photos. Its threshold is set from this run: its nearest unrelated picture is 8 bits away, so 6 bits keeps a margin of2, and a wider threshold would start to hold photos nobody had sent before. The second hash is matched against earlier claim photos and registered pool hashes, where a photo is reused; published pictures stay on the dHash.
| Threshold | dHash alone | Second hash alone | Either |
|---|---|---|---|
| 4 bits | 74 caught, 0 unrelated | 107 caught, 0 unrelated | 108 caught, 0 unrelated |
| 6 bits | 79 caught, 1 unrelated | 108 caught, 0 unrelated | 109 caught, 1 unrelated |
| 8 bits | 83 caught, 4 unrelated | 108 caught, 1 unrelated | 109 caught, 4 unrelated |
| 10 bits | 85 caught, 23 unrelated | 108 caught, 9 unrelated | 109 caught, 31 unrelated |
| 12 bits | 93 caught, 53 unrelated | 108 caught, 15 unrelated | 109 caught, 64 unrelated |
4 bits
dHash 74 caught, 0 unrelated; second hash 107, 0; either 108, 0
6 bits
dHash 79 caught, 1 unrelated; second hash 108, 0; either 109, 1
8 bits
dHash 83 caught, 4 unrelated; second hash 108, 1; either 109, 4
10 bits
dHash 85 caught, 23 unrelated; second hash 108, 9; either 109, 31
12 bits
dHash 93 caught, 53 unrelated; second hash 108, 15; either 109, 64
| The change | Caught at 10 bits | Caught at 4 bits | Second hash at 6 bits | Bits from the source |
|---|---|---|---|---|
| Saved again as JPEGquality 85 | 9 of 9 | 9 of 9 | 9 of 9 | 0 |
| Saved again as JPEGquality 60 | 9 of 9 | 9 of 9 | 9 of 9 | 0 |
| Saved again as JPEGquality 35 | 9 of 9 | 9 of 9 | 9 of 9 | 0, up to 1 |
| Resizedhalf the width | 9 of 9 | 9 of 9 | 9 of 9 | 0, up to 2 |
| Resizeda quarter of the width | 9 of 9 | 9 of 9 | 9 of 9 | 0, up to 2 |
| Cropped4 percent off every edge | 6 of 9 | 1 of 9 | 9 of 9 | 8, up to 12 |
| Cropped10 percent off every edge | 0 of 9 | 0 of 9 | 9 of 9 | 21, up to 25 |
| Turned2 degrees, white fill | 6 of 9 | 1 of 9 | 9 of 9 | 8, up to 14 |
| Turned5 degrees, white fill | 0 of 9 | 0 of 9 | 9 of 9 | 14, up to 24 |
| Brightened15 percent lighter | 9 of 9 | 9 of 9 | 9 of 9 | 1, up to 2 |
| Darkened15 percent darker | 9 of 9 | 9 of 9 | 9 of 9 | 0, up to 1 |
| Phone screenshotfit to 1170 px on a 1170 by 2532 screen, 24 px bars | 1 of 9 | 0 of 9 | 0 of 9 | 21, up to 32 |
| Mirroredflipped left to right | 9 of 9 | 9 of 9 | 9 of 9 | 0, up to 1 |
Saved again as JPEGquality 85
9 of 9 at 10 bits, 9 of 9 at 4, 9 of 9 by the second hash; 0 bits from the source
Saved again as JPEGquality 60
9 of 9 at 10 bits, 9 of 9 at 4, 9 of 9 by the second hash; 0 bits from the source
Saved again as JPEGquality 35
9 of 9 at 10 bits, 9 of 9 at 4, 9 of 9 by the second hash; 0, up to 1 bits from the source
Resizedhalf the width
9 of 9 at 10 bits, 9 of 9 at 4, 9 of 9 by the second hash; 0, up to 2 bits from the source
Resizeda quarter of the width
9 of 9 at 10 bits, 9 of 9 at 4, 9 of 9 by the second hash; 0, up to 2 bits from the source
Cropped4 percent off every edge
6 of 9 at 10 bits, 1 of 9 at 4, 9 of 9 by the second hash; 8, up to 12 bits from the source
Cropped10 percent off every edge
0 of 9 at 10 bits, 0 of 9 at 4, 9 of 9 by the second hash; 21, up to 25 bits from the source
Turned2 degrees, white fill
6 of 9 at 10 bits, 1 of 9 at 4, 9 of 9 by the second hash; 8, up to 14 bits from the source
Turned5 degrees, white fill
0 of 9 at 10 bits, 0 of 9 at 4, 9 of 9 by the second hash; 14, up to 24 bits from the source
Brightened15 percent lighter
9 of 9 at 10 bits, 9 of 9 at 4, 9 of 9 by the second hash; 1, up to 2 bits from the source
Darkened15 percent darker
9 of 9 at 10 bits, 9 of 9 at 4, 9 of 9 by the second hash; 0, up to 1 bits from the source
Phone screenshotfit to 1170 px on a 1170 by 2532 screen, 24 px bars
1 of 9 at 10 bits, 0 of 9 at 4, 0 of 9 by the second hash; 21, up to 32 bits from the source
Mirroredflipped left to right
9 of 9 at 10 bits, 9 of 9 at 4, 9 of 9 by the second hash; 0, up to 1 bits from the source
A copy the hash misses is not paid on that alone. The hash is one part of one check of six. A cropped or turned copy still meets the rest of the own-photo check, where the model looks for the signs of a screen, a print or a downloaded picture, and the other five checks; when a check is unsure, the two reviewers read it, and the Product reviewer is asked whether it is a camera photo of a real object. Every published picture of a recall is in the pool for claims on that recall, and the 1,779 distinct enough to tell their recall apart (of 1,825 stored) for claims on every other recall.
Measured in code, with no model call: scripts/public/hash-reuse-run.ts hashes each copy the way a claim photo is hashed (src/lib/verify/dhash.ts and src/lib/verify/phash.ts; the published pictures’ second hashes come from their committed thumbnails, content/recalls/image-phashes.json) and writes content/public/hash-reuse-run.json with every distance; tests/hash-reuse-run.test.ts makes the copies again and checks the counts. It measures these 9 photos and these 13 changes. Photos: the sample charger (Dmitry G, Wikimedia Commons, public domain), three Wikimedia Commons photos (credits in content/verify/fixtures/credits.json) and the CPSC’s own made-safe examples for recalls 26125 and 25007.
Why a pool across firms. On the CPSC’s 2026 docket on recall claims that are not genuine, a recall administrator reported one person filing 767 registrations under one name and one group registering over 2,200 products at about $100 each, and Truepic reported one device filing over 400 claims with photos from identical vantage points, each claim legitimate when reviewed alone (a recall administrator's comment, June 2026; Truepic's comment, May 2026). A photo reused across firms is only visible to a check that sees both firms’ claims, which is what the hash pool is.
A photo taken now
A recall setting that opens the camera instead of the photo library, and what it does and does not prove.
A firm can set a recall to ask for a photo taken now. The claim page’s photo button then opens the phone’s rear camera (capture="environment"), the photo library and the sample photo are not offered, and the claim records that the camera was asked for. It is off on the sample recalls, so a visitor on a laptop can try a saved photo. The claim page with it on
What it does. On a phone, the photo is taken at the moment of the claim, so a picture saved from somewhere else is not one tap away. A recall administrator told the CPSC’s 2026 docket on recall claims that it now often requires live capture (a recall administrator's comment, June 2026).
What it does not prove. The browser treats capture as a request: a desktop browser may still show a file picker, and a camera can photograph a screen or a printout. It does not sign the image the way a capture attestation product does. So every photo still goes through the hash pool, the own-photo check’s reading of screens and prints, and the other five checks, with the setting on or off.
What is first here
Three things, each set beside the nearest existing thing, from its own page.
A photo of the product made safe, checked against a rule read from the official CPSC remedy text, then paid through PayPal in the same flow.
The nearest product verifies that the capture is real and the serial fits, and leaves the decision to the firm's agents without paying; the one patent application on this flow had a person's review as its primary path and was abandoned in 2018.
Truepic Vision for recall and warranty claimsUS 2016/0350756 A1Real Time Results claim portals
A pool of photo hashes shared across firms, so a photo already paid at one firm is held at the next before any model call, with only two 64-bit hashes and a row id crossing.
The nearest shared-signal network is built on device and capture signals for lenders and insurers; the nearest recall tool checks one claim live at the moment it is made.
Truepic Risk NetworkA recall administrator's live photo capture
The refund goes back to the original PayPal purchase inside PayPal's 180-day window, else out as a payout, and a payout nobody accepts becomes a re-notice task in the firm's plan.
PayPal and Venmo are already reimbursement rails at the largest administrator, so the rail is not new; the step from a verified photo to that money in one flow, and the unclaimed payout turned into a task, are.
Each comparison, with its source and date: How it compares. The two-reviewer design and where it comes from: Photo checks.
Where each part lives
Checks and payment, the owner's screens, who it helps, three ideas, and sources and labels, each with the pages that show it.
- Checks and payment
Claude Opus 5.5 reads every remedy into a structured proof rule and checks photos against it; plain code makes the decision and PayPal pays.
A proof ruleRefund to the purchaseAPI docsStatusOperationsHow it is built
- The owner's screens
Phone first for owners, every rule and decision with an Info button, Plain and Technical views, and light and dark themes.
- Who it helps
447 recalls since 2024 already refund a photo of the product made safe, and more each year. Their portals pay by check in days; Remedy's PayPal payout lands in seconds.
- Three ideas
Each firm that joins makes the others safer, the refund goes back the way it was paid, and a payout nobody accepts becomes a task in the recall plan.
- Sources and labels
This page and its guided tour, every figure linked to its source file, and what is real and what is a sample, labeled.
Reading the remedy, measured
Three readers took the same 130 real CPSC remedies, and each field was scored.
Every check depends on reading the remedy right. Three readers took the same 130 real CPSC remedies, and each field was scored.
Draft: scored against draft labels; final labels are being checked by hand.
| Field | Keyword rules | Claude Opus 5.5 | Claude with a self-check |
|---|---|---|---|
| Every field right | 56.2% (73) | 84.6% (110) | 86.9% (113) |
| Photo required | 99.2% | 99.2% | 100% |
| What to do | 79.2% | 95.4% | 95.4% |
| Words to write | 99.2% | 100% | 100% |
| What the photo shows | 88.5% | 95.4% | 96.9% |
| What you get | 91.5% | 97.7% | 97.7% |
| Refund amount | 100% | 99.2% | 99.2% |
| How it is sent | 80.8% | 93.8% | 94.6% |
| Photo-refund remedies only | 63% | 90% | 91% |
| Cost for the 130 | $0.00 | $1.44 | $1.66 |
How it was scored, and what the labels are
A stratified random sample of 100 photo-refund remedies and 30 others from the CPSC data, which we did not write. Exact match per field: booleans and enums equal; actions and must_show as sets; marker_text equal ignoring case, quote marks and spacing (null equals null only); refund_amount equal to the cent (null equals null only). allFieldsCorrect needs all seven. Actions and must_show also get micro precision, recall and F1.
The labels come from a separate Claude pass at high effort that quotes its evidence, cross-checked by deterministic rules. No label has been confirmed by a person yet, so the Claude scores partly measure agreement between two Claude passes; the keyword rules’ score does not depend on who labelled.
- Keyword rules. Regular expressions over the remedy text: what an engineer would write first. No AI.
- Claude Opus 5.5. Structured output at medium effort, one pass.
- Claude with a self-check. The same, then a second pass that checks the draft against the remedy text and a deterministic lint. This is what Remedy uses.
All 583 stored rules (525 photo-refund recalls and the rest for the benchmark and recent recalls) took 1,166 calls through the Message Batches API: 4,153,921 input and 569,892 output tokens, $14.01 at batch prices, in 6.9 minutes.
Scored November 5, 2026. Files: content/recalls/benchmark/results.json, sample.json and labels.draft.json; the runner is scripts/recalls/bench.ts.
The photo checks, recorded
7 of 7 photos that needed a closer look stopped by code before any AI call.
Before any AI call, 7 of 7 recorded photos that needed a closer look were stopped by code: 6 asked for a new photo (the recall’s own pictures, turned and cropped copies, another recall’s picture, a blurry photo) and one photo already used on an earlier claim went to a person at the firm. The hash comparison itself takes a median of 2 ms (0.2 to 93.8 ms); reading the photo and answering takes a median of 98 ms (55 to 200 ms), across 7 recorded runs with no model call. Reading the CPSC’s own photos with that match off, the model was right on 16 of 18 readings.
Every recorded run, the model settings compared, and what the model read
Is it recalled? The label check, measured
Found the right recall for 2,201 of 2,216 label readings; 511 of 511 not-recalled products matched no recall.
An owner who does not know a product is recalled can photograph its label. Claude reads the brand, product, model numbers and UPC, each with the text it was read from; plain code then looks them up in every recall’s own codes, and a model number or UPC in a recall’s list settles it. Measured in code over all 1,239 recalls, with no AI call: for the 516 that list a model number or UPC, label readings built from their own codes found the right recall 2,201 times in 2,216 (147 of them a code that more than one recall lists, where the owner picks), and 511 of 511 products no recall lists matched no recall.
| Reading | Readings | Right answer |
|---|---|---|
| Brand and model number, as on a rating label | 821 | 814 found the recall |
| The model with spaces, dashes or case changed | 1,297 | 1,289 found the recall |
| The UPC alone | 81 | 81 found the recall |
| The UPC with its leading zero dropped | 17 | 17 found the recall |
| Each recall's model with its digits changed, with the brand | 483 | 483 matched no recall |
| Everyday products with their brand and model | 28 | 28 matched no recall |
Same brand and product with another model number never counts as a match: those 376 answers show the close recalls for the owner to compare. A photo eval of 30 real label pictures (26 CPSC recall pictures with the recall each must find, and 4 adapter labels no recall lists) has its answers written down first, in content/label/photo-eval-cases.json; one reading each costs about $0.77 in all. Try it with a sample label
What the AI never decides
Whether to pay, how much and by which route are decided in code; the claim limits, in plain rules.
Plain code decides
- Whether a claim is paid, sent to a person, or asked for a new photosrc/lib/verify/decide.ts
- Every pass mark, such as 0.85 for the right productsrc/lib/verify/checks.ts (LIMITS)
- The refund amount: the firm's or the purchase's, whichever is lowercomputeAmount in src/lib/verify/checks.ts; src/lib/payments/router.ts
- Which recall and proof rule apply: the claim's recall and its stored ruleruleFor in src/app/api/claims/_lib/recall.ts
- The marker word, model and lot ranges, claim limits, photo matches against every recall, and when the screen signs Claude lists outweigh its own labelsrc/lib/verify/checks.ts (CONTRADICTING_SIGNS), identifiers.ts, dhash.ts (CATALOG_MAX_DISTANCE)
- When money moves and to whom: the auto-approve cap, a refund to the purchase inside 180 days, or a payoutplanPayment in src/lib/payments/router.ts
- Deleting a photo that shows a person, and every owner's photo 90 days after the decisionsrc/lib/ops/photos.ts
Claude reads and describes
- Reads each remedy into a proof rule, once, before any claimsrc/lib/recall/proof-rule.ts (Message Batches API)
- Describes the photo: the match, each step, any writing or label, camera or screen, and any person in itsrc/lib/verify/vision.ts
- Two reviewers cite what they see when a check is unclear; a referee in code counts only votes whose evidence checks outsrc/lib/verify/reviewers.ts
- Reads unclear catalog rows; Claude Haiku 5.5 writes the monthly report's summary from SQL countssrc/lib/recall/scan.ts, src/lib/firm/narrative.ts
Claim limits, in plain rules
- One refund per person per recall. A second claim on the same recall that shares the payee, the PayPal purchase, the PayPal account that paid for it, or the network and browser goes to a person at the firm. A new email address alone does not reset it.
- Paid with no person, up to a limit. A verified claim at or under $50.00 is paid by the auto rule, up to $350.00 a day for each recall. Past that, verified claims wait in Needs review for a person to approve.
- Only hashes are compared. Each identity is kept as a keyed hash, never in the clear, and no firm sees another firm's claimants.
The sample firm’s settings; each firm sets its own. Counted in code by src/lib/firm/limits.ts and checked again when a claim is paid.
Measured in the sandbox
A photo check takes about 11 s; about 22 s when the two reviewers look; a PayPal payout 16 to 19 seconds after approval.
Timings from the owner’s claim flow, run end to end against the PayPal sandbox.
about 11 s
for one photo check by Claude Opus 5.5 at the claim path’s setting, the median of the recorded live checks: a median of 11.2 s, 6.4 to 20.7 s across 46 recorded live checks. When the product match is unclear, the two reviewers add a median of 10.7 s (8.6 to 13.9 s in 7 runs).
Counted from content/verify/sweep-results.json, content/verify/sweep-sample.json, content/presets/recorded/*.json
16 to 19 s
from approval to a PayPal payout reaching SUCCESS, in 12 sandbox runs.
PayPal sandbox, tests/e2e/claim.mjs and tests/e2e/try-payout.mjs
At once
for PayPal to mark a sample-shop purchase's refund to its original PayPal capture COMPLETED after the photo checked out (PayPal says a refund takes 3 to 5 business days to reach the buyer); a second claim on that purchase was refused.
PayPal sandbox, tests/e2e/claim-shop.mjs
98 ms
median for the free picture match to answer one photo, with no model call: server time inside the check, one claim at a time. The hash comparison itself takes a median of 2 ms (0.2 to 93.8 ms); reading the photo and answering takes a median of 98 ms (55 to 200 ms), across 7 recorded runs with no model call.
On the laptop that recorded the runs, content/public/verify-runs.json. With 100 claims at once, see Under load.
0.95
right-product score for the CPSC’s own 26125 photo, cut cord not confirmed, with the official-picture match off. Claude also saw it is the CPSC's picture; with the match on, that is answered in code before any model call.
PayPal sandbox, one live call in 12.3 s, content/presets/recorded/cpsc-example.technical.json
Sandbox payments measured November 5, 2026. Try each one: the presets, the sample shop (buy, claim, and get refunded to the original capture).
How it is tested
The suites behind every page, counted when they last ran.
630
unit tests pass with no keys and no database, as CI runs them: the proof rules, the six checks and the decision, perceptual hashing, payments and webhooks, the firm console, the API and MCP.
npm test, November 10, 2026. 61 more need what CI does not have: 21 a Postgres database, 38 a Claude key and 2 PayPal sandbox keys.
128
of 128 page views pass axe (WCAG 2.2 AA, serious and critical) with no sideways scroll: 32 pages, each at phone and desktop width, light and dark.
npm run e2e:a11y, November 9, 2026
8
tools on the MCP server, each answered by the same code as the API: ping, search_recalls, scan_catalog, check_label, get_proof_rule, verify_photo, open_claim, claim_status.
src/lib/mcp/tools.ts, checked by node tests/e2e/public.mjs
Every figure in this list is read from content/public/facts.json, written by scripts/facts.ts after the suites run. A unit test fails when the README or TESTING.md print a different one.
The data
1,239 recalls from the CPSC Recalls API, pulled Nov 5, 2026, and how each one is counted.
Every figure comes from the CPSC Recalls API, pulled Nov 5, 2026: 1,239 recalls from Jan 4, 2024 to Nov 5, 2026. A recall counts as a photo refund when its remedy text mentions a photo, picture or image and a refund (525). The headline then reads each one’s proof rule: 447 ask for a photo of the product made safe and pay a refund in money for it.
Run on the earlier snapshot behind our research note (1,227 recalls to October 29), the same classifier gives the same 523 photo-refund recalls.
Grounded in research
Published findings Remedy is built on, each with what Remedy does about it.
50% vs 6%
Recalls where the firm contacts its buyers directly see about 50% of products corrected by consumers, against 6% when the recall reaches them through a press release, by CPSC staff's recall data. The CPSC's own workshop report finds direct notice recalls the most effective.
In Remedy. A firm finds the buyers who paid it with PayPal through Transaction Search, or in its own sales file, and Remedy makes each one a personal claim link and a notice. The firm downloads them for its own mail tool and sends them itself.
72% vs 31%
In a behavioural experiment for the European Commission, 72% of people shown a direct recall notice decided to act on it, against 31% shown a generic one. Of those who took no action, 21% said the recall process was too much effort or time.
In Remedy. The claim is one page on a phone, no account and one photo, with the refund named in its first line.
About 70%
Vehicle recalls, where the maker mails each registered owner, fix about 70% of vehicles within 18 months, by NHTSA's figures. Consumer products have no owner registry, so the purchase record is the closest thing to one.
In Remedy. PayPal's own record of the purchase stands in for the registry: the buyer is found, and the refund goes back to that same payment inside 180 days.
U.S. Government Accountability Office, GAO-11-603, Auto Safety, June 2011
11.4%
Across 338 CPSC recalls from 2001 to 2013, the share of recalled products corrected was 11.4% higher on average when the firm offered a full remedy (a free repair, exchange or refund) instead of a partial one, all else equal. Recall effectiveness here is the share of affected products corrected, from the firms' CPSC progress reports. Experiments in the same study find owners see more benefit and feel more able to take part.
In Remedy. Each claim names the refund in its first line, and the remedy becomes up to four plain steps with a drawing for each.
Raithel, Hock and Mafael, Journal of the Academy of Marketing Science, 2024
14% to 31%
From a tax credit, not a recall: in an IRS field experiment with 35,050 tax filers who had not claimed the Earned Income Tax Credit after a first notice, a simpler second notice raised claiming from 14% to 23%, and showing the amount they could get more prominently raised it to 31%.
In Remedy. One page on a phone, no account, and one photo. The checks explain each result in plain words.
6 in 100
Recalled products that come back through a recall, on average, by the CPSC's measure: every finished claim adds to it.
In Remedy. A finished claim takes one photo: the check runs in about 11 seconds (the median of the recorded live checks) and the PayPal payout in about 19, measured in the sandbox.
CPSC Recall Effectiveness Workshop, 2017, as cited by Raithel, Hock and Mafael, 2024
400,000+
Products covered by the CPSC's January 2025 order to Amazon: email each buyer directly, and refund the full price to anyone who submits proof the product was destroyed or disposed of.
In Remedy. The same pattern for any firm: buyers who paid with PayPal are found through Transaction Search, and each proof photo is checked and refunded.
10 bits
The difference hash (dHash) treats two pictures more than 10 bits apart as different images, and 1 to 10 bits as variations of one, after tests on over 150,000 images.
In Remedy. A claim photo is matched within 10 bits to its own recall's pictures, and within 4 bits to every other recall's, in a catalog of 1,779 published pictures, across all recalls, distinct enough to tell their recall apart.
440 million
Active PayPal accounts at the end of September 2026.
In Remedy. Refunds go back to the original PayPal purchase inside 180 days, or out as a PayPal payout to an email or phone number, with no bank details asked.
PayPal Holdings, third-quarter 2026 results, October 27, 2026
More evidence
Every photo check recorded; cost, load and running it for real; what is at stake and who runs it first.
- Every photo check, recordedEach recorded run with its six checks, the model settings compared, and what the model read on the CPSC's own photos.
- Cost, load and running it for realHow each check stays cheap, one hundred visitors at once, and what a production deployment changes.
- What is at stake, and who runs it firstThe money method and its largest recalls, how Remedy compares with claim portals, and the 30-day pilot.