← All packs
Product Feed & Merchant Center Compliance
verifiedGet your products into Google Shopping and keep them from being rejected.
You run an online store and want your products listed on Google.
How you actually use this
You don’t install a library or wire up an SDK. Your own coding agent builds the code in your project, and you keep it — no runtime dependency on us.
Step 1
Download and unzip
You get a folder: the docs that tell an agent what to build, a starting skeleton, and the test suite that decides when it's done.
Step 2
Open it in Claude Code or Cursor
Point your coding agent at the folder. Nothing to install, no account with us, no API key.
Step 3
Paste one prompt
The pack contains the exact prompt. Paste it as your first message and leave it alone — it works through the build itself, choosing a cheaper or stronger model per task.
Step 4
Run ./verify.sh
One command. It prints a pass or fail for every check. Green means the build is done — the same script we ran to produce the receipt on this page.
Typical build: about 44 minutes of your agent working, mostly unattended. Then you integrate the working module into your app the way you would any code you’d written yourself.
Technically: A Google Shopping product feed that survives the reviewer: spec-valid RSS 2.0 output validated offline against the transcribed product data spec, a feed-to-landing-page price and availability consistency crawler, GS1-correct GTIN handling with honest identifier_exists semantics, on-page structured data generated from the same source as the feed, and a diagnostic that reports each named disapproval cause — including the one it cannot check.
Execution receipt2 of 3 runs passed- Model
- claude-sonnet-5
- Run at
- 2026-08-03T09:35:07+00:00
- Pack version
- 0e752e2f6168
- Tokens in / out
- 20,264,043 / 260,954 · per-run mean · billed input includes 19,193,503 cache reads, priced far below fresh input
- Wall time
- 43.7 min · per-run mean
- Run cost
- $11.76 · what this verification run cost us at API pricing, per build pass · your plan and model prices differ
- Deploy
- not deployed
Acceptance checks
- node-version✓ PASS
- install✓ PASS
- typecheck✓ PASS
- tests-gtin✓ PASS
- tests-identifiers✓ PASS
- tests-validate2 of 3 runs
- tests-rss✓ PASS
- tests-structured-data✓ PASS
- tests-consistency✓ PASS
- tests-diagnose✓ PASS
- consistency-clean✓ PASS
- consistency-drift✓ PASS
- disapproval-cause-coverage✓ PASS
- feed-doctor-cli✓ PASS
- next-build✓ PASS
Versions lock
nextjs-feed
| node | 24.18.1 |
| next | 16.2.12 |
| react | 19.2.8 |
| react-dom | 19.2.8 |
| typescript | 6.0.3 |
| cheerio | 1.2.0 |
| vitest | 4.1.10 |
| @types/node | 24.13.3 |
| @types/react | 19.2.18 |
| @types/react-dom | 19.2.4 |
Scaffold integrity
1 scaffold file modified or deleted by the buyer-agent during verification
The thing that gets your products disapproved is usually not in your feed. The #1 data-related disapproval cause is the feed disagreeing with the landing page Google crawls — a mismatch that is invisible to every validator that only looks at the file, and that no agent builds a check for, because it is not a property of the feed. This pack builds the whole surface: RSS 2.0 output validated offline against Google's product data spec shipped as versioned data, a consistency crawler that compares price, currency, sale window and availability against your real pages, GS1-correct GTIN handling, honest identifier_exists semantics, and page structured data generated from the same object as the feed so the two cannot drift. This pack is currently draft: no clean-room receipt has been published for it yet. When one is, this line will read N of M clean-room builds passed with all 15 acceptance checks — and until it does, treat everything below about the build as design intent, not evidence. What is already true today is that the acceptance suite runs hermetically: no Merchant Center account, no Google API, no network.
Example use cases
- A Rails/Django/Next.js store with a custom storefront that has no platform-supplied Google channel — the merchant is hand-writing a feed template and finding out what is wrong from Merchant Center Diagnostics, one three-day review cycle at a time.
- An agency running Shopping feeds for a dozen clients — the same
feed-doctor command, wired into each client's CI, turns "the client emailed saying products vanished" into a build failure on the deploy that caused it. - A headless commerce build where prices live in one service and pages render in another — exactly the architecture where feed and landing page drift apart quietly, and exactly the one where a consistency crawler pays for itself in a week.
- A handmade/vintage seller with no GTINs — custom goods, antiques and pre-1970 books are the case
identifier_exists exists for, and the case everyone gets backwards in both directions. - A store adding a second target country — the conditional rules (apparel attributes, shipping, tax, currency) are country-scoped, and the pack makes running one pipeline per country a config change rather than a fork.
Why this pack
No "always" claims — agents are stochastic, Google's rules move, and a passing check is not an approval. This is what the pack pre-solves, what it costs, and what you give up.
| Bare agent, no pack | Feed-management SaaS (DataFeedWatch / Productsup / Feedonomics class) | Platform channel app (Shopify "Google & YouTube", BigCommerce equivalent) | Hand-rolled in-house | This pack |
|---|
| Cost | "Free" (agent time only) | Recurring subscription, commonly scaling with SKU count or channel count | Free, if you are on that platform | Engineering time — days to weeks | $129 one-time |
| Time to a correct feed | Unknown. An agent asked to "generate a Google Shopping feed" has no reason to know the landing-page comparison exists | Fast — this is their product, and for a large catalogue on many channels they are genuinely the right answer | Fast, and it is maintained by the platform | Slow — the failure modes are discovered from Diagnostics, not from tests | 2–3 sessions on a $20/mo agent plan, per the pack's own budget (estimate; no receipt yet) |
| Correctness risk | High and silent — see the bug classes below | Low on the feed itself; feed↔page consistency depends on which tier and features you buy | Low for a stock storefront; it reads your platform's own product data, so the page and the feed share a source | High until you have independently rediscovered the failure modes below | Bounded by verify.sh's 15 checks, run against a local storefront with planted drift. No published pass rate yet |
| Lock-in | None, and no guardrails | Real — your transformation rules live in their UI, and leaving means rebuilding them | Real but cheap — you are already on the platform | None | None. Plain TypeScript in your repo, one class to change where your catalogue comes from |
| Honest verdict | — | If you are a large multi-channel retailer, buy the SaaS. This pack does not replace a feed-management platform | If you run a stock Shopify or BigCommerce store, use the free official app first. It is better than this pack for that case | — | For custom and headless storefronts, and for anyone who wants the consistency check inside their own CI rather than inside someone's dashboard |
What a bare agent typically ships that this pack pre-solves (specific bug classes, not a claim that every agent hits every one):
- Valid XML, invalid feed. The output parses, the namespace looks right, and it is non-conforming: an
id over 50 characters, an availability value Google retired, a price with a currency symbol in it, a missing availability_date on a preorder. Well-formedness checks pass all of these. A near-miss namespace URI (https:// instead of http://) is the sharpest version — the file parses perfectly and Google ignores every g: attribute in it. - The consistency check that never gets written. Price mismatch between feed and landing page is ranked the #1 data-related disapproval cause, and structured-data inconsistency between feed and page markup the #2 (Productsup, 2025-12-10). Neither is a property of the feed, so an agent reasoning about "is my feed correct" never gets near them. This pack ships the crawler and a fixture storefront with planted drift to prove it works.
identifier_exists, wrong in the expensive direction. An agent whose loop is "make the missing-GTIN error go away" sets identifier_exists: no on mass-produced goods. Google downgraded that error from a disapproval to a warning in late 2023, which makes it cheap to get wrong and hard to notice — the feed is accepted, the products just quietly underperform. Invalid-GTIN errors were found affecting 48.43% of merchants (and about 4% of submitted products) in DataFeedWatch's Multichannel Marketing Report 2023, as reported by Search Engine Land, 2023-10-31.- Structured data that disagrees with the feed it just generated. The agent writes the feed, then writes the product page, computing the price a second time with a second rounding rule — and, when a sale is running, putting the regular price on the page while the feed advertises the sale price. Both look right in isolation. This pack makes them two projections of one object, and the acceptance suite feeds the generated markup back through the checker for every item to prove they cannot diverge.
- A checksum-only GTIN validator. GS1 mod-10 written left-to-right with a fixed weight is correct for one GTIN length and quietly wrong for the other three. And a restricted-prefix GTIN (
2…, 02…, 04… — in-store and variable-measure ranges) is arithmetically valid, so a checksum-only check waves it straight through to a rejection.
Scale envelope
Derived from the shipped architecture and the pinned stack, not from a load test. Nothing here is receipt-measured; the pack has no receipt yet, and where a number is an estimate it says so.
- Feed generation is O(n) string building, in memory. At a typical ~700 B to 1.5 KB of XML per item, a 50,000-item feed is roughly 35–75 MB of string — fine for Node's default heap on a small container. First ceiling: about 100,000 items, where the whole-feed-in-memory approach starts to matter more than anything else in the pipeline. Estimate.
- Upgrade path past that ceiling: stream the feed instead of building it (the builder is one function and the
<item> loop is the only part that changes), or split by google_product_category into several data sources — Merchant Center accepts multiple. Google's own documented ceiling for a feed file is far higher (4 GB), so this is a Node ceiling, not a Google one. - The crawler is the real constraint, and it is time, not memory. At the default concurrency of 4 and a 200 ms page fetch, that is ~20 pages/second: 10,000 products in roughly 8–9 minutes, 100,000 in about 1.4 hours. Estimate — your page latency is the whole variable.
- Upgrade path for the crawl: raise
concurrency to whatever your own origin tolerates (it is a parameter, and you are crawling yourself, so the limit is your infrastructure and your WAF, not a third party's rate limit); or stop crawling everything — crawl the items that changed since the last run, plus a rotating sample. That is the change most catalogues over ~20,000 items should make on day one. - Validation is pure CPU over a JSON rule set. It is not the bottleneck at any catalogue size a Node process can hold.
- Storage: none. The pack persists nothing between runs, which is why there is no database in the stack and why
verify.sh needs no Docker. - One feed per target country is an architectural boundary, not a limitation to route around: the conditional rules and the currency check are country-scoped. Three countries is three configs through one pipeline.
What this comfortably covers as shipped: a single-country catalogue in the hundreds-to-tens-of-thousands of SKUs, with the doctor run in CI on every deploy and on a daily cron. What it isn't sized for out of the box: six-figure catalogues crawled in full every night, or multi-channel feed transformation across Google, Meta, Amazon and TikTok — the second one is what the feed-management SaaS category exists for, and this pack does not pretend otherwise.
On token savings: we are not publishing one. Every dollar figure in this catalogue that we stand behind comes from a harness receipt, and this pack does not have one yet. Buy it for the bug classes above — particularly the two that are invisible to any feed-only validator — not for a build-cost estimate we would have to invent.
Verified against
- claude-opus-5
- claude-sonnet-5
- claude-haiku-4-5
Supported stacks
- nextjs-feed
| node | 24.18.1 |
| next | 16.2.12 |
| react | 19.2.8 |
| react-dom | 19.2.8 |
| typescript | 6.0.3 |
| cheerio | 1.2.0 |
| vitest | 4.1.10 |
| @types/node | 24.13.3 |
| @types/react | 19.2.18 |
| @types/react-dom | 19.2.4 |
Estimated buyer token cost
1,331,000 tokens for one build pass (estimate, not a guarantee).
FAQ
What if the build fails?
verify.sh is the arbiter, and it is deterministic and hermetic — the product data spec is read from a file on disk, never fetched, and the storefront the consistency checker crawls is a local HTTP server the suite starts itself. No Google account, no API key, no network, no Docker. Full refund within 14 days of purchase if verify.sh fails on a supported configuration (the pinned stack and a model from the pack's matrix) — reply to your Stripe receipt email with the verify output attached. If your agent modified a frozen file (test/, verify/, spec/, verify.sh or the pinned configs) to get a check to pass, that falls outside the guarantee; the fix is to fix the implementation, not the checker.
Does this guarantee Google approves my products?
No, and any pack that tells you otherwise is selling you something it cannot deliver. Passing all 15 checks means two things: your feed conforms to the product data specification as this pack transcribed it on 2026-08-02, and it agrees with your landing pages at the moment you ran the check. It does not cover Google's Shopping ads policies — restricted products, misrepresentation, content and claims judged across your whole site. That review is a judgement about meaning, and no static checker can make it. The pack is built to say so out loud: policy-violation is marked unverifiable in the shipped rule data, the CLI prints a NOT CHECKED section on every run including clean ones, and one of the 15 acceptance checks exists purely to assert that no rule ever quietly claims to check it. A tool that reported "0 policy problems" would be more dangerous than no tool.
Google changes its spec constantly — doesn't this rot?
Your built app does not rot; it runs on pinned versions and keeps generating the same feed. What goes stale is the transcription's agreement with Google, and that is why the spec is shipped as data with a retrieved date rather than as rules buried in code. MIGRATION.md contains a copy-paste prompt that has your own agent read the current spec pages, diff them against the shipped file, edit only that file, and re-run the acceptance suite until green — which is the entire argument for the suite existing. Our own commitment: packs listed for sale are re-verified against current platform rules on our schedule (quarterly, plus whenever an authority announces a mandate); every re-verified version is free to prior buyers; we do not promise a delivery date, and we delist rather than sell a pack we can no longer verify. One-time purchase, free updates, no SLA.
What models does this need?
Written for claude-opus-5, claude-sonnet-5 and claude-haiku-4-5. Because this pack is draft, that is the intended matrix rather than a verified one — there is no receipt yet naming the model the clean-room runs used. Tasks are pre-tagged cheap/standard/capable in TASKS.md and routed accordingly: six of the fourteen tasks are cheap-tier, seven standard, and exactly one — the final verification pass — is Opus. The PRD's estimate is 2–3 agent sessions inside a $20/mo plan, whose binding constraint is prompt volume in Claude's 5-hour rolling window and weekly cap rather than raw tokens.
Isn't this what DataFeedWatch or Productsup already do?
For a large multi-channel retailer, yes — and you should buy the SaaS. Those platforms do feed transformation across Google, Meta, Amazon and a dozen other channels, with a UI your marketing team can use without a deploy. This pack is a different shape: it puts the checks in your repo and your CI, as code you own, for a single channel. The case it wins is the custom or headless storefront where the mismatch originates — where the feed and the page are generated by different services and drift apart between deploys. It is also $129 once rather than a subscription, which matters at small catalogue sizes and stops mattering at large ones.
I'm on Shopify — do I need this?
Probably not, and we would rather say so. Shopify's official free "Google & YouTube" channel app syncs your products to Merchant Center reading the same product data that renders your pages, which structurally avoids the biggest failure this pack protects against. Use it first. The cases where this pack still earns its price on a Shopify store: a headless front end where pages are rendered outside Shopify, prices computed by a service the channel app cannot see, or a compliance requirement to gate deploys on a feed check inside your own CI.
Can I customize the pack after the build?
Yes. Where your catalogue comes from is one class behind the CatalogSource interface — Shopify Admin API, your own Postgres, a nightly CSV. The spec rules are a JSON file, so tightening or relaxing a rule for your category is an edit, not a refactor. The disapproval-cause taxonomy is in that same file, so adding a cause you care about (and a rule that detects it) is additive. The one thing we ask you not to do is add a rule claiming to check policy — the acceptance suite will fail you, on purpose.
Do I own the code?
Yes. Once built it is your repo — plain TypeScript, one HTML/XML parsing dependency, and a JSON rule file, with no runtime call back to this pack or to OneShot. The only external service in the picture is Google Merchant Center itself, which you would be using anyway, and with which we have no affiliate or commercial relationship of any kind.
Specific problems this pack pre-solves
Prescribed services
Disclosure: some links on this page are affiliate links. We may earn a commission if you sign up through them, at no extra cost to you. We only link to services the pack actually verified against.