Channel comparison
Microsoft Advertising vs OpenAI: feed requirements compared
Microsoft Advertising follows Google's specification closely, so an OpenAI feed differs from it in exactly the ways it differs from Google: six renamed fields, a price string carrying its own currency, a rebuilt variant structure, and delivery by SFTP push rather than a scheduled fetch.
Where the two specifications diverge
The 10 attributes one channel treats differently from the other. Everything else is identical and is listed further down.
| Attribute | Microsoft Advertising | OpenAI | What that means |
|---|---|---|---|
| brand | Required in some cases | Required | Stricter on OpenAI. |
| custom_label_0 | Optional custom_label_0 | Optional ads_metadata | The field is named differently on each channel. |
| google_product_category | Recommended google_product_category | Optional product_category | Stricter on Microsoft Advertising. The field is named differently on each channel. |
| gtin | Required in some cases | Optional | Stricter on Microsoft Advertising. |
| id | Required id | Required item_id | The field is named differently on each channel. |
| identifier_exists | Optional | Not supported | Only Microsoft Advertising accepts it. |
| image_link | Required image_link | Required image_url | The field is named differently on each channel. |
| item_group_id | Required in some cases item_group_id | Optional group_id | Stricter on Microsoft Advertising. The field is named differently on each channel. |
| link | Required link | Required url | The field is named differently on each channel. |
| mpn | Required in some cases | Optional | Stricter on Microsoft Advertising. |
Differences a table cannot show
Requirement levels are the easy part. These are the differences in values, structure and delivery that break a feed copied from one channel to the other.
A pushed snapshot replaces a fetched URL
Microsoft fetches a TSV or XML file from a URL you host, daily. OpenAI expects full catalogue snapshots pushed to an SFTP endpoint it issues, at least daily. Nothing about your Microsoft setup transfers to that, and a failed push is silent where a failed fetch is reported back to you.
Six fields are renamed
item_id, url, image_url, group_id, product_category and ads_metadata replace id, link, image_link, item_group_id, google_product_category and the custom labels. The values are the same; the column names are not, and there are enough of them that the file looks unfamiliar.
Price carries its currency
Microsoft follows the Google convention of an amount with the currency configured alongside. OpenAI wants "79.99 USD" as a single string. It is a small rule that has to be applied consistently to prices and sale prices alike.
brand goes from conditional to required
Microsoft expects brand as part of the identifier chain, so it is conditional. OpenAI requires it outright. A catalogue that leans on gtin alone to satisfy Microsoft will have brand gaps that OpenAI will not accept.
The variant model is different, not renamed
Microsoft uses item_group_id exactly as Google does. OpenAI wants group_id plus a listing_has_variations flag and a variant_dict describing what varies. This is the one part of the migration that is genuinely new logic.
File formats barely overlap
Microsoft takes TSV and XML. OpenAI prefers Parquet with zstd compression and also accepts gzipped JSONL, CSV and TSV. Compressed TSV is the one route that exists on both sides, and it is not the format OpenAI prefers.
Reusing one feed for the other channel
What actually has to change, in the order it is worth doing.
-
Stand up the SFTP push first
Get a snapshot landing on the endpoint on a schedule, and alert on the job. This is the only part of the work that has no equivalent in your current pipeline.
-
Rename the six fields at generation time
Map from one internal representation to each channel's names rather than maintaining a second mapping. Two independent mappings of the same catalogue drift.
-
Reformat price into amount plus ISO code
Decimal amount, space, uppercase currency code, applied to price and sale price alike. Check zero-decimal currencies and any thousands separator your formatter might introduce.
-
Fill the brand gaps before you launch
Count the items with no usable brand value. Microsoft tolerated them wherever a valid gtin was present; OpenAI requires brand regardless, and vendor is not always the right source for it.
-
Build group_id, listing_has_variations and variant_dict
Group from the Shopify product id, flag products with more than one variant, and build the dictionary from the option names and values Shopify already holds.
-
Choose the output format deliberately
Parquet with zstd is preferred and is the right answer for a large catalogue. Gzipped TSV is the path of least resistance if you already generate TSV for Microsoft, and it is a legitimate starting point.
Every attribute, side by side
All 16 attributes documented in this knowledge base, as Microsoft Advertising and OpenAI each treat them.
| Attribute | Microsoft Advertising | OpenAI |
|---|---|---|
| availability | Required availability | Required availability |
| brand | Required in some cases brand | Required brand |
| condition | Optional condition | Optional condition |
| custom_label_0 | Optional custom_label_0 | Optional ads_metadata |
| description | Required description | Required description |
| google_product_category | Recommended google_product_category | Optional product_category |
| gtin | Required in some cases gtin | Optional gtin |
| id | Required id | Required item_id |
| identifier_exists | Optional identifier_exists | Not supported — |
| image_link | Required image_link | Required image_url |
| item_group_id | Required in some cases item_group_id | Optional group_id |
| link | Required link | Required url |
| mpn | Required in some cases mpn | Optional mpn |
| price | Required price | Required price |
| sale_price | Optional sale_price | Optional sale_price |
| title | Required title | Required title |
Frequently asked questions
Can a Microsoft Advertising feed be reused for OpenAI?
The values can, the file cannot. Six core fields are renamed, price has to carry its currency code, variants need a different structure, seller_name is required, and the feed is pushed over SFTP rather than fetched.
What format does OpenAI prefer for a product feed?
Parquet with zstd compression, with gzipped JSONL, CSV and TSV also accepted. If you already generate TSV for Microsoft, compressed TSV is the shortest path to a first working push.
Does OpenAI use the Google product taxonomy?
It takes a product_category attribute, so the category values you already maintain for Microsoft have somewhere to go. The field name differs, which is easy to miss in an otherwise familiar mapping.
Is brand required for an OpenAI feed?
Yes. Microsoft treats brand as conditional, satisfied in combination with other identifiers, but OpenAI requires it on every item, so gaps that were tolerated will not be.
Both specifications in full
- Microsoft Advertising Microsoft Advertising runs product ads across Bing, Yahoo and the Microsoft Audience Network from a catalogue uploaded to Microsoft Merchant Center. Its feed specification is closely modelled on Google's, which makes it the cheapest additional channel to launch once a Google Shopping feed already exists.
- OpenAI OpenAI ingests a merchant product feed so ChatGPT can surface products in shopping answers and complete purchases through Instant Checkout. It is the one major channel that does not fetch a feed URL you host: you push full catalogue snapshots to an OpenAI SFTP endpoint, and the most recently processed snapshot is retained for up to 14 days.
Errors on either channel
- Missing value: brand The "Missing value: brand" issue means a channel expects a brand name for a product and the feed did not supply one, or supplied a placeholder it treats as empty. On Shopify it usually means the vendor field is blank, or holds a supplier or internal category rather than the brand a shopper would recognise.
- Duplicate product id A duplicate id error means two or more rows in a feed claim the same identifier, so the channel cannot tell which one describes the item and keeps only the last it processed. On Shopify it usually means the feed was built per product rather than per variant, or that a SKU used as the id is blank or reused across variants.
Related concepts
- Variant-level feed A variant-level feed emits one row for each purchasable variant rather than one row per product, because sales channels treat every size, colour and material as a separately buyable item with its own price, stock and barcode. A Shopify product with four sizes in three colours is one product in the admin and twelve items to a channel.
- Product identifiers Product identifiers are the values that let a sales channel recognise that your listing and someone else's describe the same physical product: a GTIN, or a manufacturer part number together with a brand. They matter because a channel that can identify a product can attach reviews, specifications and competing offers to it, and one that cannot has to treat your listing as an unknown object.
- Feed scheduling Feed scheduling is the arrangement where a sales channel fetches a feed from a fixed URL on a repeating timetable instead of the merchant uploading a file. It matters because the interval between regenerations is the window in which a channel can be wrong about a price or a stock level, and most mismatch disapprovals are caused by that window being too wide rather than by a bad mapping.
Primary sources
Channel specifications change. These are the official documents this page is based on.