ChatGPT product feed for Shopify: how to set it up
How to get a Shopify catalogue into ChatGPT Ads — why Shopify's built-in ChatGPT channel isn't it, what the export lacks, and how to keep the feed from expiring.
If you run a Shopify store and want your products in ChatGPT ads, the first thing to know is that there are two different product feeds connecting Shopify to ChatGPT — and the one Shopify switches on for you is not the one Ads Manager uses.
This covers which is which, why Shopify can't hand Ads Manager a feed on its own, and the three realistic ways to build one that stays live.
Two feeds, two purposes#
| Shopify's ChatGPT channel | Ads Manager product feed | |
|---|---|---|
| What it's for | Organic product discovery in ChatGPT | Paid product ads |
| Where it comes from | Shopify Catalog, synced by Shopify | A file you supply to Ads Manager |
| Cost | Shopify says no fees | You pay for ads |
| Set up by | Shopify, on by default for eligible stores | You |
| Checkout | On your own store | On your own store |
Shopify's ChatGPT channel is part of what it calls agentic storefronts. Shopify describes it as "a discovery-focused referrer platform": your products can surface in ChatGPT conversations, and shoppers who click through complete the purchase on your own checkout. It is on by default for eligible stores, needs you to sell to US customers, and pulls product data from Shopify Catalog.
None of that reaches Ads Manager. Shopify's documentation doesn't mention OpenAI Ads Manager, and OpenAI's help documentation says that during the beta, products in an Ads Manager feed are eligible for ads only and don't appear in organic ChatGPT conversations. The two systems don't share a feed.
So if you are wondering why your ad account's Feeds page is empty when your products already show up in ChatGPT, that is why. You need a second feed.
Why Shopify can't give you the file#
OpenAI's Ads Manager accepts a feed three ways — a file upload, a hosted URL, or SFTP — and in each case it wants a delimited file: UTF-8 CSV, tab-separated TXT or TSV, or gzipped versions of those. JSON, XML, RSS and spreadsheets are not accepted.
Shopify does not produce that file natively. I went looking in Shopify's documentation for a hosted, delimited product feed at a URL and found none. The three things that look close are all something else:
- The Google & YouTube channel syncs products to Google Merchant Center. Shopify says the channel "is managed by Google", and it is not a file you can point Ads Manager at.
- Contextual product feeds are a push API for sales-channel apps, delivered by webhooks — not a file.
- Shopify Catalog feeds agentic channels like the ChatGPT channel above, and isn't something you can export to Ads Manager.
That leaves three routes.
Route 1: convert the product export (for testing only)#
Products → Export gives you a CSV. It is tempting to rename a few columns and upload it. It won't work as-is:
- There is no product ID, variant ID or product URL column — only
URL handle. - Variant rows leave the title and description blank; only the first row of each product has them.
- Extra images take extra rows, with only the handle filled in.
- Shopify's
PriceandCompare-at pricerun the opposite way to the feed'spriceandsale_price.
Each of those is fixable in a spreadsheet for a small catalogue. The field mapping guide covers every column.
The real problem is time. OpenAI's documentation says it retains its most recently processed record for a product "for up to 14 days", and the help centre puts it more bluntly: items expire after two weeks. A file you upload by hand is a campaign that stops serving a fortnight later unless you remember to upload again. Use this route to test the format, not to run ads.
Route 2: a feed app with a hosted URL#
The practical option for most stores is a feed app from the Shopify App Store that generates a file at a URL, which you then give to Ads Manager.
I'm not going to recommend a specific app — the category is crowded and changes quickly. What matters is that the app can do all of these:
- Output a delimited file — CSV or TSV, not XML. XML is a common format for Google Shopping feeds, and OpenAI does not accept it, so check the output format before anything else.
- Write one row per variant, with the variant ID as
idand the product ID asitem_group_id. - Handle compare-at prices correctly — higher price in
price, lower insale_price. - Refresh at least daily. OpenAI recommends a full snapshot "at least daily".
- Build one feed per market if you sell in more than one currency, using each market's actual prices.
- Use Google-compatible column names (
id,link,image_link) or OpenAI's own (item_id,url,image_url) — consistently, not mixed.
If an app does all six, the rest is configuration.
Route 3: build it yourself#
If you have a developer, Shopify's Admin GraphQL API has everything a feed needs — variant IDs, plain-text descriptions, prices, compare-at prices, availability, barcodes, the taxonomy category and per-market prices. A scheduled job can query it, write the file, and either host it at a URL or push it to the SFTP location Ads Manager gives you.
Two things specific to building it:
Use Shopify's per-market prices; don't convert them yourself. Shopify's own guidance is not to compute international prices from base prices, because markets can use price lists and rounding rules. Query the variant's contextualPricing for each country you sell to.
Keep IDs stable. Use the variant's numeric legacyResourceId as the item ID and never change it. A changed ID looks like a deleted product plus a brand-new one.
OpenAI also documents a Delta Feeds API for updating titles, prices and availability of existing products between full uploads. It is enabled per ad account, so check whether yours has it before designing around it.
Connecting it in Ads Manager#
Tools → Feeds → Create Feed. Give it a name and choose how products arrive.

For routes 2 and 3, choose Hosted URL or SFTP connection — both let the catalogue refresh without you. You can change this later; each feed's menu offers all three methods.
Ads eligibility. OpenAI's help centre says feeds created through Ads Manager make products ads-eligible by default unless an item is marked otherwise. If you use OpenAI's own column names, the developer documentation is stricter: set is_ads_eligible to true on every product you want in ads. Doing that costs nothing and removes the ambiguity.
Then wait. Processing takes anywhere from a few minutes to a few hours. Check Upload History afterwards — it lists missing required columns and rows that failed validation. Rejected rows don't block the rest of the file, which is convenient but means a 10% rejection rate can pass unnoticed unless you read the report.
Selling in more than one country#
If you use Shopify Markets, build one feed per market rather than one feed for everything:
- OpenAI reads only the first country in
target_countries. - Where a feed has market-specific processing configured, OpenAI rejects products priced in a currency the feed isn't set up for.
- Shopify's international prices aren't a simple conversion of your base prices.
A US feed in USD and a Canadian feed in CAD, each with its own market's prices, matches both systems. Check the country availability list before building feeds for markets where you can't buy ads yet.
Checklist#
- Accept that Shopify's ChatGPT channel and Ads Manager need separate feeds.
- Choose how you'll produce a delimited file: an app, your own job, or — for testing only — a converted export.
- Map fields correctly, especially IDs, variant URLs and compare-at prices.
- Connect it by hosted URL or SFTP so it refreshes at least daily.
- Set
is_ads_eligibletotrueif you use OpenAI's column names. - Read Upload History after every change.
- One feed per market.
Then the feed can power a campaign. The product feed campaigns guide covers product filters, ad templates and why the Products tab looks empty at first.
I build LLM Pixels, a Shopify app for ChatGPT Ads conversion tracking.