La spécification du flux produit OpenAI, champ par champ, avec exemples de rejet

Neuf champs obligatoires, formats stricts (prix, booléens), alias hérités : chaque règle du flux produit OpenAI avec un exemple valide et un rejeté.

Publié le 13 min de lecture

La spécification du flux produit OpenAI définit 9 champs obligatoires (item_id, title, description, url, brand, seller_name, image_url, availability, price), un ensemble de champs recommandés pour les variantes, les identifiants et les prix promotionnels, et des champs optionnels pour les attributs, les médias, la livraison, la publicité et le paiement. Les valeurs suivent des formats stricts : la monnaie en 79.99 USD, les booléens en true/false, les identifiants sous forme de chaînes. Une ligne qui enfreint une règle est inutilisable, et la documentation ne décrit aucun rapport d’erreur ligne par ligne.

Pourquoi la formulation exacte des règles compte

La page de présentation du dépôt de fichiers cite les trois causes d’échec les plus fréquentes : « missing required fields », « outdated or non-spec field names » et « malformed field values ». Ce sont trois problèmes de format : le produit est bon, la ligne ne l’est pas. Comme la documentation ne décrit aucun rapport d’erreur ligne par ligne, un marchand ne découvre une ligne mal formée qu’en remarquant qu’un produit n’apparaît jamais dans ChatGPT. C’est pourquoi chaque règle ci-dessous est accompagnée d’un exemple rejeté. Les citations sont reprises mot pour mot de la spécification du flux produit et de ses deux pages associées listées dans les sources.

Les 9 champs obligatoires

Une ligne qui omet l’un de ces champs, ou qui fournit une valeur vide ou non reconnue, est inutilisable. La spécification est explicite pour availability : une valeur omise, vide ou non reconnue rejette la ligne.

ChampTypeContrainte (d’après la spécification)Exemple valideExemple rejeté
item_idchaîne« Stable ID, unique per item or variant within your feed. Never reuse it for a different item. »TRAIL-BLK-10Un numéro de ligne de base de données qui change à chaque réimport
titlechaîne« Product name, including the selected variant when relevant. » 150 caractères maximum, texte brutTrail running shoes, black, size 10Un titre de 300 caractères bourré de mots-clés
descriptionchaîne« Factual product description for this item. » 5 000 caractères maximum, texte brutWaterproof trail shoes with a rubber outsole and mesh lining.<p>Waterproof <strong>trail</strong> shoes</p>
urlURL« Product detail page for the item, with the variant selected when possible. Keep it stable. » HTTP ou HTTPS absolue, accessible publiquementhttps://example.com/products/trail?color=black&size=10/products/trail (chemin relatif)
brandchaîne« Product brand as shown on the product page. » Une vraie marque, pas une valeur de remplissageNorthlinen/a
seller_namechaîne« Name of the seller supplying this offer. » Un vrai nom, pas une valeur de remplissageNorthline Outdoorunknown
image_urlURL« Main product image, showing this variant. Use a direct image URL, such as a JPEG or PNG. »https://example.com/images/trail-black.jpghttps://example.com/products/trail (une page, pas une image)
availabilityénumération« in_stock, out_of_stock, pre_order, backorder, or unknown. »in_stockavailable, preorder, In Stock
pricemonnaie« Regular item price in major currency units. » Format amount CURRENCY79.99 USD79,99, $79.99, 79.99, 1,079.99 USD

Trois détails de ce tableau causent l’essentiel des ennuis.

item_id doit survivre aux réimports. Un identifiant dérivé d’une position de ligne ou d’un horodatage transforme chaque instantané en nouveau catalogue. Utilisez le SKU ou l’identifiant de variante de la plateforme, sous forme de chaîne.

availability est une liste fermée. Google Shopping utilise preorder ; OpenAI utilise pre_order. Un flux copié depuis un export Google porte la mauvaise orthographe sur chaque produit en précommande.

price est une seule chaîne, pas deux colonnes. La spécification demande « a decimal amount in major units, a space, and an uppercase three-letter ISO 4217 currency code », avec « a decimal point, no thousands separators or exponent notation, and no more fractional digits than the currency permits ». Un prix exporté depuis un environnement français sous la forme 25,99 échoue sur le seul séparateur décimal.

Les champs recommandés

Ils ne sont pas obligatoires, mais une valeur mal formée dans un champ recommandé reste une valeur mal formée. Si vous ne pouvez pas renseigner un champ correctement, omettez-le.

Variantes : group_id, listing_has_variations, variant_dict

Les trois champs fonctionnent ensemble. group_id est un « Stable parent-listing ID shared by all variants. » La spécification ajoute : « Omitted or empty: uses item_id, which does not establish a variant group. » Un group_id copié depuis item_id ne produit donc aucun groupe, sans que rien ne le signale.

listing_has_variations doit valoir true sur chaque ligne de variante : « Omitted, empty, or false: no variant options are used. »

variant_dict associe des noms d’options à des valeurs sélectionnées, sous forme de chaînes. Il « Requires listing_has_variations=true and group_id different from item_id. » Les clés et les valeurs doivent être non vides, les mêmes noms d’options doivent être utilisés dans tout le groupe, et chaque combinaison d’options doit être unique. La spécification demande aussi de garder les attributs de premier niveau comme color et size cohérents avec les mêmes options dans variant_dict, parce que « Neither representation reconciles conflicting values for you. »

SituationRésultat
group_id = TRAIL, item_id = TRAIL-BLK-10, listing_has_variations = true, variant_dict = {"color":"Black","size":"10"}Groupe de variantes établi
group_id = TRAIL-BLK-10 (identique à item_id)Aucun groupe de variantes
group_id renseigné, listing_has_variations omisAucune option de variante utilisée
variant_dict = {}Traité comme une absence d’options
color = Blue au premier niveau, variant_dict.color = BlackValeurs contradictoires, non réconciliées

Identifiants : gtin, mpn, offer_id

gtin est « One assigned GTIN: exactly 8, 12, 13, or 14 digits, including a valid check digit. Preserve leading zeros; no spaces or dashes. » Deux conséquences : un GTIN avec une faute de frappe échoue au contrôle de la clé, et un GTIN exporté depuis un tableur qui a supprimé le zéro initial n’a plus la bonne longueur. Validez avant de téléverser.

mpn est le « Manufacturer-assigned part number, preserving its punctuation and casing. » La spécification est sans détour sur un raccourci courant : « do not invent a value to replace a missing GTIN. »

offer_id est un « Stable offer ID, unique within the feed. Use it to distinguish offers that share a product URL. » C’est une chaîne, donc les zéros initiaux sont conservés.

État et prix promotionnel

condition accepte new, refurbished ou used. Une valeur omise ou vide « may be treated as new », donc précisez toujours used ou refurbished quand cela s’applique.

sale_price est le « Current sale price: greater than zero, strictly less than price, and in the same currency. » Un prix promotionnel « Nonpositive, equal, higher, or different-currency » n’est pas utilisé. La spécification indique aussi quand le mettre à jour : « Submit the current price; update the feed when a sale starts or ends. » Ne programmez pas une promotion à l’avance en envoyant le futur prix.

pricesale_priceRésultat
79.99 USD59.99 USDUtilisé
79.99 USD79.99 USDNon utilisé (égal)
79.99 USD59.99 EURNon utilisé (devise différente)
79.99 USD0.00 USDNon utilisé (nul)

« true enables search eligibility; false disables it and checkout eligibility. Omitted or empty: true. » C’est l’interrupteur qui retire un produit rapidement : la page de présentation du dépôt recommande de passer is_eligible_search=false pour rendre un produit inéligible au prochain cycle de traitement, plutôt que de supprimer la ligne, parce qu’OpenAI « retains its most recently processed record for up to 14 days ».

Les champs optionnels, par groupe

Attributs de l’article

ChampRègle
product_category« Your category path, from broad to specific, separated by > », par exemple Apparel & Accessories > Shoes
materialMatériaux principaux de l’article
colorCouleur sélectionnée, cohérente avec l’image du produit
sizeLibellé de la taille sélectionnée ; utilisez variant_dict quand la taille distingue les variantes
gendermale, female ou unisex ; toute autre valeur équivaut à une absence de genre
age_groupnewborn, infant, toddler, kids ou adult ; « a product attribute, not a purchase-age restriction »
dimensionsObjet avec des chaînes décimales positives pour au moins deux des valeurs length, width, height, plus une unité (in, cm, ft, m, mm) ; un objet vide est invalide
weight et item_weight_unitPoids net positif sans emballage ; unité g, kg, oz ou lb ; l’unité est obligatoire avec le poids

Médias

additional_image_urls est un tableau en JSON ou en Parquet, et une chaîne séparée par des virgules en CSV ou en TSV. Les URL invalides sont omises. Si une URL d’image contient elle-même une virgule, la spécification demande de « Percent-encode commas as %2C in URL », sinon le délimiteur coupe l’URL en deux.

Livraison et retours

ChampRègle
shipping_priceFormat monétaire, même devise que price, non négatif ; « zero = no charge. Omitted/empty = unknown, not free »
shippingTuple country:region:service_class:price, en conservant la position vide de la région, par exemple US::Standard:5.00 USD
accepts_returnstrue ou false ; omis signifie non précisé
return_deadline_in_daysNombre entier positif, « Supply only with accepts_returns=true »
return_policyURL HTTP ou HTTPS publique vers les conditions de retour ou de vente ferme

Avis et notes

review_count est un nombre entier non négatif d’avis produit (pas d’avis sur le vendeur ou la boutique) ; zéro signifie aucun avis, omis signifie inconnu. star_rating est une chaîne décimale sur une échelle de 0 à 5 avec deux décimales, par exemple 4.50, et doit être accompagnée d’un review_count positif correspondant.

Informations sur le marchand

seller_url pointe vers la vitrine ou la page de profil du vendeur (pour les offres de place de marché, la page du vendeur concerné). marketplace_seller nomme la place de marché où le paiement a lieu et nécessite une configuration avec OpenAI.

Publicité

is_ads_eligible : « Set true for products Ads should process; false explicitly opts out. Omitted/empty: disabled unless feed-level default applies. » Renseignez-le explicitement plutôt que de compter sur une valeur par défaut. ads_metadata est un objet chaîne vers chaîne qui utilise les clés configurées pour votre intégration publicitaire, par exemple {"custom_label_0":"summer"} ; « Do not invent keys. »

Paiement

is_eligible_checkout « true opts in only when search eligibility also true and checkout enabled. Omitted/empty/false: disabled. Search=false overrides this. » Quand vous activez cette option, publiez seller_privacy_policy et seller_tos sous forme d’URL publiques ; les fournir « does not establish checkout readiness » à lui seul.

Ciblage géographique

target_countries est un tableau de codes ISO 3166-1 alpha-2 en majuscules « configured for feed. Omitted/empty does not mean worldwide. Requires market setup. » Ainsi ["US"] est valide, ["United States"] ou ["us"] ne le sont pas. store_country est le pays de la boutique du vendeur sous forme de code ISO, pas une surcharge régionale de prix ou de stock.

Les règles de données qui s’appliquent à tous les champs

Ces conventions viennent de la section « general conventions » de la spécification et s’appliquent quel que soit le format de fichier.

  • Omettez les valeurs inconnues. « Omit an unknown value. Unless a row says otherwise, an omitted field, JSON null, or an empty delimited cell supplies no value. »
  • Aucune valeur de remplissage. « Do not use placeholder strings such as null, unknown, or n/a; unknown is valid only where explicitly listed. » Le seul endroit où unknown est une valeur légale est availability.
  • Booléens. « For boolean fields, use JSON true or false, or the lowercase strings true and false in delimited files. » TRUE, 1, yes et Y ne sont pas des booléens.
  • Décimales. Point décimal, aucun séparateur de milliers, aucune notation exponentielle.
  • Identifiants sous forme de chaînes. « Keep identifiers as strings to preserve leading zeros. » Cela compte pour gtin, item_id, offer_id et mpn, et surtout en Parquet, où un outil d’écriture qui déduit une colonne entière supprime les zéros.
  • Texte et URL. « Use UTF-8 text and absolute HTTP or HTTPS URLs; prefer HTTPS. »
  • Guillemets en CSV. « In CSV, quote a cell containing commas, quotes, or newlines, and double each embedded quote. JSON objects in CSV or TSV cells must be serialized as JSON. » Un variant_dict dans une cellule CSV ressemble à "{""color"":""Black"",""size"":""10""}".
  • Stabilité d’une mise à jour à l’autre. Gardez item_id, group_id et offer_id stables quand le prix, le stock, le titre ou les images changent.

Les alias hérités

Les anciens noms sont encore acceptés, mais la spécification demande de « Send only one name per value » et précise quel nom l’emporte quand les deux sont présents : « item_id wins over id and sku; group_id wins over item_group_id; the enable_ flags win over their is_eligible_ names. » Utilisez les noms actuels et n’émettez jamais l’alias dans le même fichier.

Nom actuelAlias hérité
item_idid, sku
group_iditem_group_id
is_eligible_searchenable_search
is_eligible_checkoutenable_checkout
is_ads_eligibleis_eligible_ads
return_deadline_in_daysreturn_window

Si votre flux dérive d’un export Google Shopping, ce sont les noms Google (id, link, image_link, item_group_id) qu’il faut convertir. La comparaison Flux Google Shopping ou flux OpenAI détaille cette correspondance.

Une ligne JSONL valide

Une ligne par article. Cette ligne utilise les champs obligatoires, les champs de variante et quelques champs recommandés et optionnels. Notez que le titre sépare les détails de variante par une virgule, et que chaque booléen est un booléen JSON, pas une chaîne.

{"item_id":"TRAIL-BLK-10","group_id":"TRAIL","listing_has_variations":true,"variant_dict":{"color":"Black","size":"10"},"offer_id":"northline-TRAIL-BLK-10","title":"Trail running shoes, black, size 10","description":"Waterproof trail shoes with a rubber outsole and mesh lining. Lace closure, 320 g per shoe.","url":"https://example.com/products/trail?color=black&size=10&utm_medium=feed","brand":"Northline","seller_name":"Northline Outdoor","image_url":"https://example.com/images/trail-black.jpg","additional_image_urls":["https://example.com/images/trail-black-side.jpg"],"availability":"in_stock","price":"79.99 USD","sale_price":"59.99 USD","gtin":"00012345678905","condition":"new","color":"Black","size":"10","product_category":"Apparel & Accessories > Shoes","is_eligible_search":true,"is_ads_eligible":true,"target_countries":["US"]}

Le paramètre utm_medium=feed sur url suit la page des bonnes pratiques, qui suggère d’ajouter « feed attribution parameters to url (for example utm_medium=feed) » afin de distinguer les clics venant du flux dans vos outils d’analyse. La même page demande un texte « concise, factual copy » dans les titres et les descriptions, et de garder « title, url, description, media, availability, and price variant-specific when those values differ ».

Erreurs fréquentes

  • Exporter price et currency en deux colonnes, ou avec une virgule décimale locale.
  • Copier group_id depuis item_id, ce qui ne produit aucun groupe de variantes.
  • Écrire TRUE/FALSE ou 1/0 dans les colonnes booléennes.
  • Remplir brand ou seller_name avec n/a pour passer un contrôle « obligatoire » dans un outil interne ; la spécification traite cette valeur de remplissage comme invalide.
  • Laisser le HTML de l’éditeur de la boutique dans description.
  • Envoyer id et item_id dans le même fichier.
  • Laisser un tableur convertir gtin en nombre et supprimer le zéro initial.
  • Passer is_eligible_checkout=true sur un produit dont is_eligible_search vaut false.

Comment Convrail valide chaque règle avant la livraison

Convrail applique ces règles avant qu’un fichier n’atteigne OpenAI, de sorte qu’une ligne cassée vous est signalée au lieu de disparaître :

  • Les 9 champs obligatoires sont contrôlés en présence et en format sur chaque ligne : la monnaie en amount CURRENCY, availability face à la liste fermée, url et image_url comme URL HTTP ou HTTPS absolues pointant vers un JPEG ou un PNG direct. Convrail plafonne aussi item_id à 100 caractères et brand, seller_name et mpn à 70, et rejette les titres écrits entièrement en majuscules.
  • Les valeurs de remplissage (null, unknown, n/a) dans brand et seller_name sont rejetées.
  • Les champs conditionnels sont validés quand ils sont présents : sale_price strictement inférieur à price dans la même devise, group_id différent de item_id, is_eligible_checkout exigeant l’éligibilité à la recherche plus les deux URL de politique, target_countries en codes alpha-2 majuscules, star_rating entre 0 et 5.
  • La clé de contrôle du GTIN est vérifiée. Un GTIN invalide est omis plutôt qu’envoyé, la ligne reste donc valide ; l’omission est consignée dans le journal.
  • Le HTML est retiré des descriptions, et les booléens sont émis comme booléens JSON en JSONL et en Parquet, et comme chaînes en minuscules en CSV et en TSV.
  • Chaque rejet est enregistré avec l’item_id, le champ et la règle, dans un journal d’exécution qui compte aussi les articles lus, acceptés et rejetés.

Le même catalogue peut aussi être projeté en flux compatible Google. Si vos produits manquent déjà dans les résultats de ChatGPT, Pourquoi vos produits n’apparaissent pas dans les résultats shopping de ChatGPT relie chaque symptôme à une règle ci-dessus, et Parquet, JSONL ou CSV couvre les choix au niveau du fichier.

Prochaine étape

Connectez votre boutique et laissez Convrail valider votre catalogue face à chaque règle de cette page avant la première livraison : voir la page flux produit.

Sources

Questions fréquentes

Combien de champs sont obligatoires dans le flux produit OpenAI ?

Neuf : item_id, title, description, url, brand, seller_name, image_url, availability et price. Une ligne à laquelle il manque l'un d'eux, ou qui porte une valeur mal formée dans l'un d'eux, est inutilisable.

Comment écrire le prix dans un flux produit OpenAI ?

Le montant, une espace, puis le code ISO 4217 en majuscules, par exemple 79.99 USD. Point décimal, aucun séparateur de milliers, aucun symbole monétaire, et pas plus de décimales que la devise n'en autorise.

OpenAI accepte-t-il encore id, sku ou item_group_id ?

Oui, comme alias hérités de item_id et group_id, mais la spécification demande de n'envoyer qu'un seul nom par valeur. Utilisez les noms actuels dans tout nouveau flux et ne mélangez jamais les deux dans le même fichier.

sale_price peut-il être égal à price ?

Non. La spécification exige un sale_price supérieur à zéro, strictement inférieur à price et dans la même devise ; un prix promotionnel égal, supérieur, nul, négatif ou dans une autre devise n'est pas utilisé.

Que se passe-t-il si group_id est identique à item_id ?

Aucun groupe de variantes n'est créé. group_id doit être un identifiant stable de fiche parente, partagé par toutes les variantes et différent de chaque item_id, avec listing_has_variations à true sur chaque ligne de variante.

Mesurez le canal ChatGPT dès cette semaine

Gratuit pendant l'accès anticipé, le temps d'intégrer les premières boutiques. Laissez votre email et vous recevez le lien d'installation dès qu'une place s'ouvre.

Pas de newsletter. Un seul email avec le lien d'installation, rien d'autre.