The OpenAI product feed specification defines the technical data structure required for product information to be processed correctly across shopping, product discovery, and advertising experiences within ChatGPT. This structure includes product titles, descriptions, prices, availability, images, variants, seller information, eligibility fields, and many other data points.
OpenAI documentation provides two primary methods for transferring product feeds: File Upload and API. The File Upload method is based on sending the complete catalog file through SFTP. The API method is used to create product feeds, retrieve feed metadata, and update products through API requests.
Which methods can be used to upload an OpenAI Product Feed?
| Method |
Use case |
Update model |
Technical structure |
| File Upload |
Sending the complete product catalog to OpenAI as a file |
Full snapshot |
File delivery through SFTP |
| API |
Creating feeds, retrieving feed metadata, and updating products through the API |
Product upsert / partial update |
REST API endpoints |
The File Upload method can be considered a complete catalog upload. OpenAI defines this structure as a full snapshot feed model that is treated as the source of truth. The API method is used to create feeds, retrieve existing feed information, and perform product updates through the API.
File Upload feed requirements
According to OpenAI’s File Upload documentation, the product feed is delivered to OpenAI through SFTP. For the file format, parquet is recommended. The jsonl.gz, csv.gz, and tsv.gz formats are also supported. The feed should use UTF-8 encoding, and the filename should remain consistent across updates.
| Topic |
OpenAI requirement |
| Delivery model |
Feeds are pushed to OpenAI through SFTP. |
| Feed model |
Full snapshot feed |
| Recommended update frequency |
At least daily |
| Recommended format |
parquet, preferably with compression |
| Other supported formats |
jsonl.gz, csv.gz, tsv.gz |
| Encoding |
UTF-8 |
| Filename |
A stable filename should be used, and the same file path and filename should be overwritten with each update. |
| Sharding |
The shard set should remain stable, and the same shard files should be updated. |
| Shard size |
Up to 500,000 products per shard is recommended, and shard files should ideally remain below approximately 500 MB. |
Full snapshot logic
With the File Upload method, OpenAI treats the feed as a complete catalog snapshot. Each update should therefore reflect the current state of the catalog.
| Scenario |
Implementation |
| The product will remain in the catalog |
The product record is included in the full snapshot. |
| The product should not appear in ChatGPT Search |
is_eligible_search=false is submitted. |
| The product should be removed completely |
The product is omitted from the next full snapshot. |
| The feed will be validated |
You can begin with a sample containing approximately 100 products. |
| First full snapshot |
Required fields should be checked across all rows. |
Common ingestion errors in OpenAI Product Feeds
| Error type |
Description |
| Missing required field |
Required fields are empty or missing for certain products. |
| Unsupported field name |
Field names that are not included in the OpenAI product feed specification or outdated field names are used. |
| Malformed field value |
Fields such as price, availability, URL, date, or boolean are not submitted in the expected format. |
| Unstable ID |
The item_id value changes over time. |
| Inaccessible URL |
The product URL or image URL does not return an HTTP 200 response. |
File Upload product schema structure
The OpenAI File Upload product specification is defined as a flat-file schema. The stable schema is the supported path for production File Upload integrations.
| Schema section |
Content |
| OpenAI Flags |
ChatGPT Search, checkout, and ads eligibility fields |
| Basic Product Data |
Product ID, title, description, and URL |
| Item Information |
Brand, category, material, dimensions, weight, and age group |
| Media |
Primary image, additional images, video, and 3D model |
| Price & Promotions |
Price, sale price, and promotion dates |
| Availability & Inventory |
Availability, preorder date, and expiration date |
| Variants |
Group ID, color, size, and variant dictionary |
| Fulfillment |
Shipping and digital product information |
| Merchant Info |
Seller name, seller URL, and policy URLs |
| Returns |
Return and exchange information |
| Performance Signals |
Popularity and return rate |
| Compliance |
Warnings and age restrictions |
| Reviews and Q&A |
Review count, star rating, and store rating |
OpenAI Flags fields
OpenAI Flags control whether a product can be used in ChatGPT Search, checkout, or advertising experiences.
| Field |
Type |
Supported values |
Requirement |
Description |
is_eligible_search |
Boolean |
true, false |
Required |
Determines whether the product can appear in ChatGPT Search results. |
is_eligible_checkout |
Boolean |
true, false |
Required |
Indicates whether the product is eligible for direct purchase within ChatGPT. |
is_ads_eligible |
Boolean |
true, false |
Required for Ads; optional for non-Ads feeds |
Determines whether the product should be processed for ChatGPT Ads. |
OpenAI Product Feed Basic Product Data fields
The Basic Product Data section contains the product’s core identity and the information required to direct users to the product detail page. The item_id, title, description, and url fields are required in the File Upload schema.
| Field |
Type |
Requirement |
Rule / Note |
item_id |
String |
Required |
Merchant product ID; must be unique at the variant level, remain stable, and contain no more than 100 characters. |
gtin |
String |
Optional |
GTIN, UPC, or ISBN; 8–14 digits; hyphens and spaces should not be used. |
mpn |
String |
Optional |
Manufacturer part number; maximum 70 characters. |
title |
String |
Required |
Product title; maximum 150 characters; all-caps text should not be used. |
description |
String |
Required |
Plain-text product description; maximum 5,000 characters. |
url |
URL |
Required |
Product detail page URL; should return HTTP 200, and HTTPS is recommended. |
Item Information fields
| Field |
Type |
Requirement |
Rule / Note |
brand |
String |
Required |
Product brand; maximum 70 characters. |
condition |
String |
Optional |
Example: new; lowercase string. |
product_category |
String |
Optional |
Category path; the > separator is recommended. |
material |
String |
Optional |
Primary material; maximum 100 characters. |
dimensions |
String |
Optional |
LxWxH unit format. |
length, width, height |
String |
Optional |
Individual dimension fields should be used together. |
dimensions_unit |
String |
Conditional |
Required when length, width, or height is provided. |
weight |
String |
Optional |
Product weight. |
item_weight_unit |
String |
Conditional |
Required when weight is provided. |
age_group |
Enum |
Optional |
newborn, infant, toddler, kids, adult |
ads_metadata |
Object |
Optional |
String key-value JSON object for ads metadata. |
Media fields
The Media section includes the primary product image and additional media assets. In the File Upload schema, image_url is specified as a required field.
| Field |
Type |
Requirement |
Rule / Note |
image_url |
URL |
Required |
Primary product image; JPEG/PNG; HTTPS is recommended. |
additional_image_urls |
String |
Optional |
Comma-separated list of additional image URLs. |
video_url |
URL |
Optional |
Must be publicly accessible. |
model_3d_url |
URL |
Optional |
GLB/GLTF is recommended. |
Price & Promotions fields
The Price & Promotions section is used for standard prices, sale prices, and promotion dates. The price field is required and must include a currency code.
| Field |
Type |
Requirement |
Rule / Note |
price |
Number + currency |
Required |
Example: 79.99 USD; must include a currency code. |
sale_price |
Number + currency |
Optional |
Must be less than or equal to the price value. |
sale_price_start_date |
Date |
Optional |
ISO 8601 format. |
sale_price_end_date |
Date |
Optional |
ISO 8601 format. |
unit_pricing_measure / base_measure |
Number + unit |
Optional |
The two fields should be used together. |
pricing_trend |
String |
Optional |
Maximum 80 characters. |
Availability & Inventory fields
The Availability & Inventory section defines the product’s stock and purchase availability. The availability field is required and should be submitted using lowercase enum values.
| Field |
Type |
Supported values |
Requirement |
Rule / Note |
availability |
Enum |
in_stock, out_of_stock, pre_order, backorder, unknown |
Required |
Lowercase string. |
availability_date |
Date |
ISO 8601 |
Required for preorder |
Must be a future date. |
expiration_date |
Date |
ISO 8601 |
Optional |
Must be a future date. |
pickup_method |
Enum |
in_store, reserve, not_supported |
Optional |
Lowercase string. |
pickup_sla |
Number + duration |
Example: 1 day |
Conditional |
Can be used when pickup_method is provided. |
Variants fields
The Variants section is used to define versions of the same product based on color, size, or other attributes.
| Field |
Type |
Requirement |
Rule / Note |
group_id |
String |
Recommended |
Shared group ID across variants. |
listing_has_variations |
Boolean |
Recommended |
true or false. |
variant_dict |
Object |
Recommended |
Example: {"color":"Blue","size":"10"} |
item_group_title |
String |
Optional |
Group product title; maximum 150 characters. |
color |
String |
Optional |
Maximum 40 characters. |
size |
String |
Recommended for apparel |
Maximum 20 characters. |
size_system |
Country code |
Recommended for apparel |
ISO 3166 two-letter country code. |
gender |
String |
Optional |
Lowercase string. |
offer_id |
String |
Optional |
Must be unique within the feed. |
Fulfillment fields
| Field |
Type |
Requirement |
Format / Note |
shipping |
String |
Optional |
country:region:service_class:price:min_handling_days:max_handling_days:min_transit_days:max_transit_days |
is_digital |
Boolean |
Optional |
true or false. |
Merchant Info fields
The Merchant Info section is used for seller information, seller URLs, and policy URLs.
| Field |
Type |
Requirement |
Rule / Note |
seller_name |
String |
Required / Display |
Maximum 70 characters. |
marketplace_seller |
String |
Optional |
Marketplace seller of record. |
seller_url |
URL |
Required |
HTTPS is recommended. |
seller_privacy_policy |
URL |
Conditional for checkout |
May be required when is_eligible_checkout=true. |
seller_tos |
URL |
Conditional for checkout |
May be required when is_eligible_checkout=true. |
Returns, reviews, and compliance fields
| Section |
Field |
Requirement |
Note |
| Returns |
accepts_returns |
Optional |
true or false. |
| Returns |
return_deadline_in_days |
Optional |
Positive integer. |
| Returns |
accepts_exchanges |
Optional |
true or false. |
| Returns |
return_policy |
Required |
HTTPS is recommended. |
| Performance Signals |
popularity_score |
Optional |
0–5 scale or merchant-defined. |
| Performance Signals |
return_rate |
Optional |
0–100%. |
| Compliance |
warning / warning_url |
Recommended for checkout |
If a URL is provided, it should return HTTP 200. |
| Compliance |
age_restriction |
Recommended |
Positive integer. |
| Reviews |
review_count |
Optional |
Non-negative integer. |
| Reviews |
star_rating |
Optional |
0–5 scale. |
| Reviews |
store_review_count |
Optional |
Non-negative integer. |
| Reviews |
store_star_rating |
Optional |
0–5 scale. |
API feed structure
The OpenAI API feed structure uses the Feeds endpoints to create product feeds and retrieve feed metadata. In the API documentation, the GET /product_feeds/{id} endpoint returns feed metadata, while POST /product_feeds creates a new product feed.
| Endpoint |
Method |
Purpose |
/product_feeds/{id} |
GET |
Returns metadata for a specific feed. |
/product_feeds |
POST |
Creates a new product feed. |
GET /product_feeds/{id}
| Field |
Type |
Required |
Description |
id |
string |
Yes |
Product feed identifier. |
The response may include the id, target_country, and updated_at fields. The target_country value is an ISO 3166 two-letter country code.
POST /product_feeds
| Field |
Type |
Required |
Description |
target_country |
string |
No |
ISO 3166 two-letter country code. |
The response includes the feed id, target_country, and updated_at fields. An invalid payload may return 400 Bad Request.
API Products endpoints
The Products API is used to retrieve products within a specific feed or upsert product updates. The PATCH /product_feeds/{id}/products endpoint matches products using the id field. Products that are not included in the request remain unchanged.
| Endpoint |
Method |
Purpose |
/product_feeds/{id}/products |
GET |
Returns products contained in the feed. |
/product_feeds/{id}/products |
PATCH |
Upserts products. |
PATCH /product_feeds/{id}/products
| Field |
Type |
Required |
Description |
id |
string |
Yes |
Feed identifier. |
target_country |
string |
No |
ISO 3166 two-letter country code. |
products |
Product[] |
Yes |
Product array for the product feed. |
The response includes the id and accepted fields. If the payload is invalid, the endpoint may return 400 Bad Request. If the feed cannot be found, it may return 404 Not Found.
API Product schema
Unlike the File Upload flat-file structure, the API Product schema uses nested product and variant objects. At the Product level, id and variants are required. At the Variant level, id and title are required fields.
Product object
| Field |
Type |
Required |
Description |
id |
string |
Yes |
Stable global product identifier. |
title |
string |
No |
Product title. |
description |
Description |
No |
Product description content. |
url |
string (uri) |
No |
Canonical product URL. |
media |
Media[] |
No |
Product-level media assets. |
variants |
Variant[] |
Yes |
Product variants. |
Variant object
| Field |
Type |
Required |
Description |
id |
string |
Yes |
Stable global variant identifier. |
title |
string |
Yes |
Variant title. |
description |
Description |
No |
Variant description content. |
url |
string (uri) |
No |
Variant URL. |
barcodes |
Barcode[] |
No |
Variant barcode values. |
price |
Price |
No |
Active sale price. |
list_price |
Price |
No |
Reference price before the discount. |
unit_price |
UnitPrice |
No |
Unit pricing metadata. |
availability |
Availability |
No |
Variant availability. |
categories |
Category[] |
No |
Variant categories. |
condition |
Condition |
No |
Item condition. |
variant_options |
VariantOption[] |
No |
Example: color, size. |
media |
Media[] |
No |
The first media item is treated as the primary asset. |
seller |
Seller |
No |
Seller metadata. |
API nested objects
The API Product schema includes nested objects such as Description, Availability, Price, Media, VariantOption, Category, Seller, and Link.
| Object |
Field |
Required |
Description |
| Description |
plain |
No |
Plain-text description. |
| Description |
html |
No |
HTML description. |
| Description |
markdown |
No |
Markdown description. |
| Availability |
available |
No |
Indicates whether the variant can be purchased. |
| Availability |
status |
No |
in_stock, backorder, preorder, out_of_stock, discontinued |
| Price |
amount |
Yes |
ISO 4217 minor units. |
| Price |
currency |
Yes |
Three-letter currency code. |
| Media |
type |
Yes |
Media type. |
| Media |
url |
Yes |
Media URL. |
| Media |
alt_text |
No |
Alternative text. |
| VariantOption |
name |
Yes |
Example: color or size. |
| VariantOption |
value |
Yes |
Selected option value. |
| Category |
value |
Yes |
Category label or path. |
| Category |
taxonomy |
No |
Example: google_product_category, shopify, or merchant. |
| Seller |
name |
No |
Seller name. |
| Seller |
links |
No |
Seller-related links. |
| Link |
type |
Yes |
privacy_policy, terms_of_service, refund_policy, shipping_policy, faq |
| Link |
url |
Yes |
Link destination URL. |
Differences between the File Upload and API schemas
| Topic |
File Upload |
API |
| Data model |
Flat-file schema |
Nested JSON object |
| Delivery |
SFTP |
REST API |
| Update model |
Full snapshot |
Upsert / partial product changes |
| Product ID field |
item_id |
Product id, Variant id |
| Variant structure |
Flat fields: group_id, variant_dict, color, size |
variants[] array and variant_options[] |
| Price |
Number + currency string such as 79.99 USD |
Minor units + currency object |
| Description |
Plain-text string |
plain, html, or markdown |
| Images |
image_url, additional_image_urls |
media[] |
| Category |
product_category |
categories[] + taxonomy |
| Update effect |
The snapshot is treated as the source of truth. |
Products not included in the request remain unchanged. |
Minimum technical checklist
| Check |
Expected status |
| Has the feed method been selected? |
File Upload or API |
| If File Upload is used, is SFTP ready? |
Yes |
| Is the file format supported? |
parquet, jsonl.gz, csv.gz, tsv.gz |
| Is the encoding correct? |
UTF-8 |
| Is the filename stable? |
Yes |
| Are all required fields present for every product? |
Yes |
Are the item_id or API id fields stable? |
Yes |
| Does the product URL return HTTP 200? |
Yes |
| Is the primary image URL accessible? |
Yes |
| Does the price include a currency code? |
Yes |
| Do availability values comply with the supported enums? |
Yes |
Are products intended for advertising submitted with is_ads_eligible=true? |
Yes, where required |
| Are group and variant fields populated for products with variants? |
Yes |
| Are seller and return policy fields included? |
Yes |
| Has the test sample passed validation? |
Yes |
Source documentation for the OpenAI Product Feed specification
Optifeed note
The OpenAI product feed specification requires regular validation for both technical field compliance and product data freshness. Optifeed helps e-commerce brands manage product titles, descriptions, prices, availability, variants, categories, images, and metadata fields according to the requirements of different advertising and AI shopping channels.
Before beginning your OpenAI feed preparation, you can explore the broader role of product feeds in AI shopping by reading Product Feeds and AI Shopping and How to Prepare an AI Shopping-Ready Product Feed.

Zafer Kavaklı
Co-Founder at Optifeed
Zafer Kavaklı is co-founder of Woom Digital and Optifeed. He is an experienced digital marketer who has been working in the field since 2012. He started his career as a digital marketing intern at Teknosa and then worked at Modanisa as a digital marketing specialist. After that he worked as digital marketing manager at ebebek. Following these roles, he ventured into entrepreneurship by establishing his own performance marketing agency named Woom Digital. Zafer has embarked on a new business venture in the SaaS sector, creating a product management tool named Optifeed.