US CPSC recall database × live marketplace listings

recalled products you can buy right now

loading…

01 — What Deadstock does

A federal recall database on one side. A live shopping web on the other. We prove the gap between them.

The US government recalls dangerous products. Companies are supposed to pull them from shelves. Many never come off. Deadstock walks the gap in three moves.

Stacked government recall documents
Step 01

Pull every federal recall notice.

The CPSC recall database is public but opaque — thousands of PDFs and structured records describing what was pulled, when, and for what hazard. We ingest the last three years, normalize hazard type, and build a semantic query per record.

Warehouse fulfillment center at dusk
Step 02

Scrape what's for sale, right now.

The recall list is static. What's on shelves is not. Apify's Amazon actor pulls fresh listings against every recall query — title, price, image, seller, review count. Cached to disk minutes before demo so the venue wifi can't kill it.

Two identical cardboard boxes, one marked with a red sticker
Step 03

Match meaning, not words.

Elasticsearch semantic_text joins the two sides. A recall says "clothing storage unit." The listing says "chest of drawers." Zero keyword overlap — but the embeddings put them next to each other. Same data, same index, two queries side by side.

02 — Why Elastic + Apify

A vector database matches. A search engine matches and aggregates. That's the whole argument.

Apify answers a question nobody has an API for: what is for sale right now, on the actual page a shopper sees. The recall database is public and static. Live inventory is not. Actors handle the scraping surface — pagination, anti-bot, structured extraction — so we can pull an Amazon search page as JSON in seconds.

Elastic then does two things a vector store alone can't. First, semantic_text matches meaning across vocabularies that never overlap — dresser, chest of drawers, clothing storage unit — the join a keyword index will never make. Second, ES|QL runs regulator-grade aggregations over the same index: how many recalled products are still listed, grouped by hazard, by retailer, by how long ago the recall was issued. Semantic search + aggregations over one index is the specific thing Elastic does.

The Kibana Agent Builder is the interface layer. Two tools — index_search for semantic lookup, ES|QL for the aggregate questions — and one agent that decides which to call. Judges ask a question out loud, the agent answers it against data scraped minutes ago.

Recall notice

EnHomee 15-Drawer 51-inch Dressers — unstable if not anchored to the wall, posing tip-over and entrapment hazards.

Live listing

15 Drawer Dresser for Bedroom, Tall Fabric Chest of Drawers with Side Pockets, Sturdy Metal Frame, Wood Top, Closet Organizer for Nursery

keyword search → zero meaningful overlap. finds nothing.
semantic_text → instant match. embeddings know the words are the same thing.
03 — Live evidence

Every card below is a recall on the left and a for-sale listing on the right — matched by the same index, scraped minutes ago.

Toggle the match mode to see what a plain keyword index would return vs. what semantic_text catches. Filter by retailer or hazard type. Every card links to the original CPSC notice — always verify before drawing conclusions.

04 — Architecture

Under the hood — eight scripts, three indices, and one agent.

A pair of diagrams: the shape at a glance, then every wire, index, and tool call. Cached to disk at every stage so the venue wifi can't kill the demo.

Deadstock high-level system architecture
Diagram 01 — The shape CPSC recalls flow in from one side, Apify actors scrape retail listings from the other. Elastic's semantic_text joins them into deadstock-matches. The Agent Builder agent answers questions on top.
Deadstock detailed pipeline architecture
Diagram 02 — Every wire Numbered pipeline scripts cache to data/ at every stage, three indices carry the pinned inference id, and three Agent Builder tools sit on top of deadstock-matches — one index_search, two parameterized ES|QL.
05 — How to read this

A lead generator for regulators, not a verdict.

Deadstock makes accusations for a living. The guardrails aren't a disclaimer — they're the design.

  • Rule 01 Every match shows a confidence tier. High / medium / low, printed on the card. Low-confidence matches say so out loud.
  • Rule 02 Language is "likely match" — never "is." A listing may be a corrected version, a different variant, or a different seller reusing a title. The algorithm doesn't know. It flags patterns.
  • Rule 03 Every card links to the CPSC notice. A viewer can verify us in fifteen seconds on their phone. That's the point.
  • Rule 04 We describe patterns, not people. No name-and-shame from the stage. Show the listing, describe the shape.
  • Rule 05 The ask is "this deserves a look" — not "this company is breaking the law." Deadstock is a lead generator for regulators, not a compliance tool and not a verdict.
An investigator's desk with a loupe, notebook, and pinned research

Built in a single evening. Open-sourced the same night.

Deadstock was built live for the Elastic + Apify Hack Night in Austin on July 31, 2026. If it's useful to you — regulators, safety researchers, journalists, or retailers — the code and the method are on GitHub.