A product feed OpenAI accepts, validated line by line

OpenAI drops malformed feed rows without telling you. Convrail syncs your catalog, checks every product against the official specification (field lengths, price format, image files, identifiers, placeholder values), exports the accepted rows in the format OpenAI expects and delivers them by SFTP. Rejected rows are listed with the reason and the fix.

The silent rejection problem

The OpenAI feed ingestion does not return an error report per row. A title in capital letters, HTML left in a description or a price written as "25,99" means the product is skipped, and nothing tells you. Merchants discover it weeks later when a product they sell every day never appears in ChatGPT. Convrail moves that check to your side of the fence: every row is validated before delivery, and every rejection is written to the run journal with the field, the rule and the correction.

✗ "25,99" as a price: the row is gone and so is the product
✓ caught before delivery: price must be "25.99 EUR"

The 9 required fields, with the exact limits

These are the rules Convrail enforces, taken from the OpenAI product feed specification. Each one is covered by an automated test.

Required fields of the OpenAI product feed and how Convrail validates them
FieldRuleTypical rejection
item_idRequired, stable, 100 characters maxVariant ID that changes on re-import
titleRequired, 150 characters max, not all capital letters"WIRELESS HEADPHONES XL"
descriptionRequired, 5,000 characters max, plain textHTML tags left from the store editor
urlRequired, valid http(s) URLRelative path
brandRequired, 70 characters maxEmpty vendor field
image_urlRequired, direct HTTP(S) link to a JPEG or PNG, HTTPS recommended.webp file, URL with credentials
price"<amount> <ISO-4217>", greater than 0"25,99", "25.99", "€25.99"
availabilityin_stock, out_of_stock, pre_order, backorder or unknown"available"
seller_nameRequired, real seller name, 70 characters maxMissing, "unknown"

Conditional and recommended fields are checked the same way when they are present, because a malformed optional field also drops the row.

Conditional and recommended fields validated by Convrail
FieldRuleTypical rejection
is_eligible_searchLowercase "true" or "false"; omitted means trueBoolean, "TRUE", "yes"
is_eligible_checkoutWhen "true": search eligibility plus seller_privacy_policy and seller_tos URLsCheckout enabled without policy URLs
is_ads_eligibleLowercase "true" or "false"; required for ads processing"1", "yes"
target_countriesUppercase ISO 3166-1 alpha-2 codes, configured with your OpenAI setup"France", "USA"
gtin8, 12, 13 or 14 digits with a valid check digitTypo in the barcode, dashes
sale_priceSame currency, strictly less than priceSale price equal to price
group_idStable and different from item_idgroup_id copied from item_id
brand, seller_nameReal values, never placeholders"n/a", "null", "unknown"

Also checked when present: mpn (70 characters max), availability_date (ISO 8601), star_rating and popularity_score (0 to 5), review_count and return_deadline_in_days (positive integers). When neither GTIN nor MPN exists, identifier_exists is set to "no". A GTIN with a wrong check digit is omitted rather than sent, so the row stays valid.

From catalog to delivered file

  1. Your catalog stays in sync

    Product webhooks keep Convrail’s copy of your catalog current. Changes are debounced for 30 seconds so a bulk edit triggers one rebuild, not a hundred. A full sync is available on demand.

  2. Each product becomes a feed item

    HTML is stripped from descriptions, prices are formatted with the store currency, variants are grouped under group_id, and your seller name, target countries and eligibility flags are applied from the feed settings.

  3. Every row is validated

    Accepted rows go into the file. Rejected rows are journaled with the field and the rule they broke. The count of rejections is visible in the app before the file leaves.

  4. The file is exported and sharded

    Formats: parquet, jsonl.gz, csv.gz or tsv.gz. Files are split at 500,000 items or roughly 450 MB, under the limits of the specification, with stable names (feed-organic-000.jsonl.gz) so each delivery overwrites the previous snapshot.

  5. Delivery by SFTP on your schedule

    Convrail connects to the SFTP endpoint from your OpenAI account at the hour you pick and uploads the shards. Failed deliveries retry, then open a health alert.

A journal for every run

Each run records the number of items read, accepted and rejected, the diff against the previous run (added, removed, changed) and the delivery status. The per-row errors are kept with the run, so you can trace when a product disappeared from the feed and why.

Run fieldMeaning
itemsTotal, itemsValid, itemsRejectedHow many rows were built, kept and dropped
added, removed, changedDiff against the previous run, computed from a hash of each row
errorsOne entry per rejected item: item_id, field, message
deliveryStatuspending, delivered or failed, with the attempt count

If you already have a Google Shopping feed

Most fields transfer, some do not. OpenAI expects is_eligible_search, is_eligible_checkout and target_countries that Google never asked for, uses seller_name instead of a merchant account, and formats booleans as lowercase strings. Convrail keeps a Google-compatible projection of your feed as well, so the same catalog serves both channels without maintaining two exports.

Frequently asked questions

Which formats does OpenAI accept for the product feed?

Parquet (recommended for large catalogs), gzipped JSON Lines, CSV and TSV. Convrail exports all four; parquet and jsonl.gz are the defaults.

How often is the feed delivered?

Once a day, at the hour you choose, as a complete snapshot with stable filenames so each delivery replaces the previous one. Intraday updates through the API are on the roadmap.

What happens to a product with an invalid row?

It is excluded from that delivery and listed in the run journal with the field and the rule it broke. Fix the product in your store and the next run picks it up.

Do I need a separate feed for ChatGPT Ads?

The specification allows the same items to serve organic results and ads through the `is_ads_eligible` flag. Convrail sets it from your feed settings; a distinct ads delivery target is planned.

How large can my catalog be?

Files are sharded at 500,000 items or about 450 MB each, within the limits of the specification. In our automated test, a 10,000-product catalog is validated, exported and delivered to SFTP in under a minute.

Where do my SFTP credentials live?

Encrypted at rest with AES-256-GCM, like every secret Convrail stores. They are decrypted only at delivery time.

Measure the ChatGPT channel this week

Free during early access while we onboard the first stores. Leave your email and we send the install link when your spot opens.

No newsletter. One email with the install link, nothing else.