ChatGPT Ads Shopping Feed Converter
ChatGPT Shopping Feed Converter is here
If you already run Google Shopping, you are most of the way to a ChatGPT Ads product feed. Of the 41 attributes in OpenAI's product feed specification, 30 have a direct Google Shopping equivalent. id becomes item_id, link becomes url, image_link becomes image_url, item_group_id becomes group_id. That part is a renaming exercise.
The other 11 attributes have no Google equivalent at all, and five of them are required. That is the reason a Merchant Center export can never be uploaded to OpenAI unchanged, and it is where most of an afternoon goes.
The five that block your upload
Three of these are eligibility flags, and they are the genuinely new idea in this format:
-
is_eligible_search— the product may appear in ChatGPT's shopping results -
is_eligible_checkout— the product may be bought inside ChatGPT -
is_ads_eligible— the product may be used in paid campaigns
Google has nothing like this. In Merchant Center, eligibility comes from your feed configuration and your campaign setup. In the OpenAI format it is per product, in the file. Every row carries its own three flags.
That is worth pausing on, because it changes what a feed is for. You can ship a catalogue where everything is search-eligible, only your best-margin lines are ads-eligible, and nothing is checkout-eligible until you have actually set up that integration. None of that needs a campaign change or a second feed. It is a column.
The other two required additions are duller but just as blocking:
-
seller_name— must match the merchant name registered on the ad account. A mismatch here is a common rejection, and the error will not tell you that is what happened. -
target_countries— ISO 3166 alpha-2, required on every row.
Your feed does not contain a target country, and that is not a mistake
Export a feed from Merchant Center and look for the country. It is not there.
That is correct behaviour: in Google Merchant Center the target country is feed-level configuration, set once when you create the feed. It is not product data, so it does not appear in product data. OpenAI wants it on every row.
You can usually recover it without looking anything up. The shipping attribute is formatted country:region:service:price, so DE:::4.90 EUR tells you the country is DE. The tax attribute follows the same shape.
One feed, one country
Here is the one that quietly ruins a rollout plan. target_countries is defined as a list, so it looks like you can write DE,AT and be done.
You cannot. OpenAI's specification states that only the first entry is used. Writing DE,AT targets Germany. Austria is silently ignored — no error, no warning, just a market that never sees your products.
So one feed covers one country. To advertise the same catalogue in Germany and Austria, you convert it twice and upload two files. Worth knowing before you build the plan rather than after, and worth naming your files by country, because two uploads called feed.txt are indistinguishable at exactly the moment it matters.
Four things that are conversions, not renames
Beyond the missing attributes, four values change shape:
-
Availability. Google writes
in stockwith a space. OpenAI wantsin_stock. Andpreorderbecomespre_order, which then makesavailability_daterequired — miss that and those rows drop. -
Prices need a currency code. Every price must carry ISO 4217, so
89.00becomes89.00 EUR. A bare number is not a price. - Descriptions must be plain text. HTML is not accepted. If your descriptions came out of a CMS, they almost certainly contain markup.
-
The file is tab delimited
.txt, UTF-8, one row per variant. Not CSV. Not XML. This is the first thing people get wrong when they try to reuse a Google file directly.
If you are exporting from Shopify instead
A Shopify export needs repair before any mapping happens, because of how Shopify writes variants.
Shopify repeats one product across several rows and leaves the product-level cells blank after the first row. Title, description, vendor and type appear once, then the following variant rows are mostly empty. Convert that naively and every variant after the first loses its title and description.
Three more Shopify-specific traps:
- Extra images appear as rows containing nothing but an image. They are not products and must be dropped.
-
Body (HTML)is markup and has to be flattened. - There is no product URL in a Shopify export, only a
Handle. The URL has to be built as your store domain plus/products/plus the handle. Sinceurlis required, forget this and every single row fails validation.
This is also why splitting a Shopify export into smaller files is riskier than it looks: cut between two rows of the same product and you have severed a variant group.
Uploaded feeds expire after 14 days
Manually uploaded items expire after 14 days. For a catalogue that changes — which is every real catalogue — point Ads Manager at a hosted URL or an SFTP feed instead of re-uploading by hand.
Combine that with one-feed-one-country and the manual approach scales badly fast: three markets is six uploads a month, forever, for as long as you keep doing it that way.
Doing it without the afternoon
All of the above is mechanical, which means it is the kind of thing that should not be done by hand.
We built a converter for our own use and published it: the ChatGPT Ads Product Feed Generator. Drop in a Shopify export, a Google Shopping feed or any product CSV and it detects the format, maps the fields, repairs Shopify's variant rows, normalises availability and currency, sets the eligibility flags, validates every row and hands back a file OpenAI Ads Manager accepts.
It runs entirely in your browser. Your catalogue is never uploaded anywhere — there is no server to upload it to — which matters if the file you are converting is a client's. Feeds up to 500 products are free.
If you would rather do it by hand, or want to check what a tool is doing on your behalf, the full field mapping guide lists every OpenAI attribute, its Google Shopping equivalent, and the eleven that have none.
Questions
How do I convert a Google Merchant Center feed to a ChatGPT Ads feed?
Rename the 30 attributes that have direct equivalents, then add the ones Google does not have: the three eligibility flags, seller_name and target_countries. Convert availability values to in_stock, out_of_stock or pre_order, add an ISO 4217 currency code to every price, flatten any HTML in descriptions, and export as tab-delimited .txt in UTF-8.
What format does the OpenAI product feed use?
A tab-delimited .txt file encoded in UTF-8, one row per variant, with a header row of attribute names. It is not comma separated and it is not XML.
How many fields are required?
Thirteen. Five of them have no Google Shopping equivalent, so they always have to be supplied during conversion.
Can one feed target multiple countries?
No. target_countries accepts a list but only the first entry is used, so one feed covers one country. Convert the catalogue once per market.
Does my product data get uploaded anywhere when I use the converter?
No. The converter is JavaScript running in your own browser. The file is read from disk into memory on your machine, converted there and written back out as a download. Closing the tab discards it.
Field definitions follow the OpenAI product feed specification. Not affiliated with, endorsed by, or sponsored by OpenAI, Shopify or Google.
