You've set up Meta Automotive Inventory Ads. The catalogue uploaded cleanly, the Pixel is firing, and the campaign is spending. But the dynamic retargeting — the whole point of AIA, showing a shopper the exact vehicle they looked at — barely delivers. Your catalogue "match rate" in Commerce Manager is low, and Events Manager quietly warns that content IDs from your website aren't found in the catalogue.
This is the single most common reason vehicle dynamic ads underperform, and it's almost never a budget or creative problem. It's an identity problem: the ID in your feed and the ID your Pixel sends are two different strings for the same vehicle.
How Meta actually matches an ad to a shopper
Dynamic ads work off a join. When someone views a vehicle on your site, your Meta Pixel fires a ViewContent (and later AddToCart/Lead) event carrying a content_ids value — the ID of the vehicle they looked at. To retarget them, Meta looks up that content_ids in your catalogue and pulls the matching item's images, price and title into the ad.
The join key is exact-string. Meta does not fuzzy-match, normalise, or guess. If your Pixel sends content_ids: ["147823"] and the same vehicle sits in your catalogue under vehicle_id: "STOCK-147823-FTC", that is a miss. No matching item, no dynamic ad — the shopper either sees a generic ad or nothing at all.
id in your feed must be byte-for-byte identical to the content_ids your Pixel reports for the same vehicle.
Why the two drift apart for vehicles
On a normal ecommerce store the Pixel and the feed usually agree, because the same platform generates both. Vehicles are different. The feed and the website are frequently driven by different systems:
- Your feed ID tends to come from your DMS or stock-management system — an internal reference like
STK-58821or a compound of make/model/reg. - Your Pixel's content ID is usually whatever your website theme puts in the URL, or a slug the CMS generates — because that's the value sitting in the page's data layer when the Pixel fires.
Because the vehicle's page URL is the one thing both the shopper and the Pixel definitely touch, the URL is almost always where the "real" identity lives. So the reliable fix isn't to re-plumb your Pixel — it's to make the feed ID match the URL.
Reading the ID out of your URL
Look at how your vehicle detail pages are structured. UK dealer sites usually fall into one of a few shapes:
/used-cars/147823-ford-transit-custom→ the ID is147823(leading number before the slug)/stock/vehicle/147823→ the ID is the last path segment/vehicles/ford-transit-custom?vehicle=147823→ the ID is thevehiclequery parameter/used/CV21ABC→ the ID is the registration (some platforms key on reg, not a stock number)
Whatever the shape, the number or code that changes per vehicle is what your Pixel is almost certainly reporting as content_ids — because it's the part of the URL the page is built around. That value is what your feed's id needs to become.
Confirm it before you change anything: open a live vehicle page, run Meta's Pixel Helper (or watch the Test Events tab in Events Manager), and read the exact content_ids value off the ViewContent event. That string is your target. Don't assume the format — copy it.
Rewriting the feed ID to match
Once you know the target format, you rebuild the feed's id from the vehicle's link (the page URL) rather than from the raw DMS reference. In practice that's a small extraction rule: take the URL, pull out the segment that carries the ID, and write it into the id field.
In Trajekt this is a feed rule you set once and it runs on every update:
- Source field:
link(the vehicle's page URL) - Extract: the ID segment — e.g. the number immediately after
/used-cars/, or the value of the?vehicle=parameter - Write to:
id(and keepitem_group_idaligned so variants group correctly)
The result: a vehicle at /used-cars/147823-ford-transit-custom ships to Meta as id: 147823 — exactly what the Pixel reports when a shopper views that page. The join now succeeds, and dynamic retargeting starts serving the right vehicle to the right person.
Two things to keep steady once it's working:
- Don't let the ID change over time. If a vehicle's ID flips between feed runs, Meta treats it as a new item and loses the history (and any learning) attached to the old one. Derive it from the stable part of the URL, not from anything seasonal like price or a promo slug.
- Keep it consistent across channels where it helps, but not blindly. Meta needs the ID to match its Pixel; Google Vehicle Ads matches on different signals and is far more forgiving. If you run both from one source, it's fine for Meta's ID to be URL-derived — just make the change in the Meta output, and test Google separately rather than assuming one rule suits both.
Fix the match without touching your website
Trajekt reads your vehicle inventory once and rewrites the Meta feed ID from your URL structure — so your Pixel and catalogue finally agree, and dynamic retargeting actually fires.
Start free →How to check it worked
Give Meta a few hours to re-ingest the catalogue after the ID change, then:
- Commerce Manager → your catalogue → Diagnostics: the "content IDs from your website don't match your catalogue" warning should clear.
- Events Manager → your Pixel → the vehicle event: the match-rate / "products found in catalogue" figure should climb toward 100%.
- The campaign itself: dynamic retargeting impressions and click-through pick up, because Meta can now build a personalised ad for each viewed vehicle instead of falling back to a generic one.
If the diagnostic still complains, re-read the Pixel Helper value — the mismatch is usually a small formatting difference (a prefix, a trailing slug, upper vs lower case). Match it exactly and the warning clears.
The bigger point
Vehicle advertising lives and dies on identity. Every downstream feature — dynamic retargeting, catalogue sales campaigns, lookalikes built off viewers — depends on Meta being able to tie a page view to a catalogue item. That tie is a single string, and for most dealers the correct value is already sitting in plain sight in the URL. Rebuild the feed ID from it, and the platform does the rest.