CodeGym /Cursos /ChatGPT Apps /Product Feed: propósito, modelo de datos, campos clave y ...

Product Feed: propósito, modelo de datos, campos clave y política

ChatGPT Apps
Nivel 14 , Lección 1
Disponible

1. Por qué necesitas un Product Feed

Si lo comparamos con el e‑commerce clásico, el Product Feed es algo intermedio entre:

  • un «escaparate» de productos (catálogo con precios, disponibilidad, enlaces y multimedia);
  • y un contrato técnico que describe qué SKU está dispuesto el comerciante a mostrar y/o vender a través de ChatGPT.

OpenAI en su especificación afirma explícitamente que el feed es la fuente única de la verdad sobre los productos, en la que se apoyan la búsqueda, las recomendaciones y la preparación de datos para el checkout.

En una tienda online convencional, el usuario navega por páginas, recorre categorías, filtra, etc. En el AI‑commerce es al revés: el usuario simplemente le dice al modelo «encuéntrame un regalo digital de hasta 30 dólares para un amigo desarrollador al que le gustan los juegos de mesa», y ChatGPT decide qué SKU de tu Product Feed encajan, en qué orden mostrarlos y cómo presentarlo en forma de tarjetas y con el posterior Instant Checkout.

Por eso el Product Feed resuelve varias tareas a la vez.

En primer lugar, le da a ChatGPT datos estructurados para la búsqueda. El modelo se apoya no solo en el nombre y la descripción del producto, sino también en categorías, etiquetas, precio, disponibilidad, localización y restricciones por país.

En segundo lugar, es la fuente de datos para el checkout. Cuando ChatGPT empieza a preparar una checkout_session, del feed se toman los ID de SKU, el precio, la moneda, el seller URL y otra información comercial.

Y, por último, el Product Feed es un contrato formal entre tú y la plataforma. Dices explícitamente: «aquí está la lista de SKU, estos se pueden usar solo para búsqueda (discovery) y estos otros se pueden tramitar mediante Instant Checkout».

Para visualizarlo, es útil dibujar un esquema simple.

flowchart TD
  A[GiftGenius DB] --> B[Feed Builder]
  B --> C["Product Feed (CSV/JSON/...)"]
  C --> D[OpenAI Ingestion]
  D --> E[Índice de búsqueda + ranking]
  E --> F[ChatGPT/Agent selecciona regalos]
  F --> G["Instant Checkout (ACP)"]

A la izquierda está tu base de datos interna, donde vive el catálogo «real». A la derecha, ChatGPT, que se muestra al usuario. En medio, el Product Feed y los mecanismos de ingesta e indexación. Todo lo que hacemos en esta lección está justo entre A y D.

2. Formatos y «física» del Product Feed

La especificación de OpenAI es bastante flexible con el formato de los archivos: se admiten TSV, CSV, XML y JSON. Esto se hizo a propósito para que la mayoría de los sistemas existentes (desde monolitos caseros hasta Shopify) puedan exportar el feed sin trucos.

En el caso típico:

  • publicas un archivo o endpoint con el Product Feed en tu servidor HTTPS;
  • registras esa URL en el portal de ChatGPT Merchants;
  • OpenAI recupera periódicamente ese feed, lo valida e indexa los productos.

La documentación subraya que el feed debe actualizarse con regularidad (incluso cada 10–15 minutos) para que los usuarios vean precios y disponibilidad actuales, especialmente en rebajas y picos de demanda.

En el ejemplo didáctico de GiftGenius trabajaremos con formato JSON porque encaja bien con desarrolladores de TypeScript. Pero es importante entender que, a nivel de especificación, OpenAI no está atado a JSON; simplemente nos resulta más cómodo.

Un feed JSON sencillo podría verse así:

[
  {
    "id": "gg-coffee-sub-1m-usd",
    "title": "Suscripción de café de 1 mes",
    "description": "Caja mensual de café en grano para desarrolladores.",
    "price": 2900,
    "currency": "usd",
    "availability": "in_stock",
    "link": "https://giftgenius.app/gifts/coffee-subscription-1m",
    "image_link": "https://cdn.giftgenius.app/images/coffee-1m.png",
    "enable_search": true,
    "enable_checkout": true
  }
]

En la práctica habrá más campos; algunos son obligatorios y otros recomendados u opcionales. Veremos cómo está organizado.

3. Producto vs variante (SKU): cómo modelarlo

Una de las preguntas más frecuentes: «¿Cómo reflejar en el Product Feed tallas, paquetes, duraciones de suscripción y otras variantes de un mismo producto?»

La especificación del Product Feed trabaja con filas/registros, cada una de las cuales describe una configuración vendible. El patrón arquitectónico recomendado por la industria (y que encaja bien con el feed de OpenAI) es: cada configuración (talla, variante de suscripción, tarifa, región) es un registro separado del feed, es decir, un SKU independiente.

El producto base vive en tu modelo interno, y en el feed trabajas al nivel de SKU.

Por ejemplo, tienes un servicio con suscripciones de 1, 3 y 6 meses. Desde el punto de vista del product feed, son SKU distintos. Si un servicio puede comprarse en 20 condiciones diferentes, en tu product feed deberían existir 20 SKU.

En TypeScript se puede expresar aproximadamente así:

// Modelo interno de GiftGenius
export interface GiftProduct {
  id: string;              // product_123
  name: string;
  description: string;
  baseImageUrl: string;
}

// SKU que irá al Product Feed
export interface GiftSkuFeedItem {
  id: string;              // product_123_usd_1m
  productId: string;       // referencia a GiftProduct.id
  title: string;
  description: string;
  price: number;           // en unidades mínimas (centavos)
  currency: string;        // "usd"
}

Dentro de GiftGenius puede haber una relación de uno a muchos entre GiftProduct y GiftSkuFeedItem. En el feed entregas una lista «plana» de SKU.

Para que ChatGPT entienda qué SKU pertenecen a un mismo producto base (por ejemplo, suscripción de 1, 3 y 12 meses), a menudo se usa un campo de agrupación como item_group_id. Sin embargo, esto es un patrón arquitectónico, no un requisito estricto del estándar.

Por ejemplo:

{
  "id": "gg-coffee-sub-1m-usd",                // SKU de suscripción de 1 mes
  "item_group_id": "gg-coffee-sub",            // Tu producto
  "title": "Suscripción de café — 1 mes",
  "price": 2900,
  "currency": "usd",
  "enable_search": true,
  "enable_checkout": true
}

Y para la suscripción de 3 meses:

{
  "id": "gg-coffee-sub-3m-usd",                // SKU de suscripción de 3 meses
  "item_group_id": "gg-coffee-sub",            // El mismo id del producto
  "title": "Suscripción de café — 3 meses",
  "price": 7900,
  "currency": "usd",
  "enable_search": true,
  "enable_checkout": true
}

Este enfoque le facilita la vida tanto al modelo como a tu backend al crear pedidos: el ID del SKU se convierte en la clave única por la que siempre puedes encontrar la configuración exacta que compró el usuario.

4. Campos obligatorios del Product Feed y su impacto en el UX

En la especificación del Product Feed, OpenAI divide los campos en tres grupos: obligatorios (required), recomendados (recommended) y opcionales (optional).

Los nombres concretos y las listas hay que revisarlos siempre en la documentación vigente, pero para fines didácticos podemos basarnos en este conjunto «mínimo».

Campo Para qué sirve Qué pasa si falta
id
Identificador único del SKU dentro del comerciante El artículo no se puede identificar de forma unívoca
title
Título corto para la tarjeta Al modelo le costará entender qué producto es
description
Descripción ampliada Las respuestas serán más genéricas y menos personalizadas
price
Precio en unidades mínimas No se puede preparar el checkout
currency
Código de moneda ISO 4217, normalmente en minúsculas La plataforma no sabrá en qué moneda calcular
link
URL de la página del producto en el sitio del comerciante El usuario no podrá ir a tu sitio
availability
Estado de disponibilidad (in_stock, out_of_stock y otros) Se podrían mostrar productos no disponibles
enable_search
Si se puede usar el artículo en la búsqueda Sin true el artículo no aparecerá en los resultados
enable_checkout
Si se puede comprar vía Instant Checkout Solo habrá discovery/link‑out

Un matiz importante: enable_search y enable_checkout separan lógicamente los modos de operación.

Si enable_search = true y enable_checkout = false, el producto puede participar en la búsqueda, pero al intentar comprar, el usuario irá por tu enlace (link) a tu sitio, y no a Instant Checkout dentro de ChatGPT (donde ya tiene la tarjeta vinculada).

Si enable_checkout = true, entonces, si se cumplen las demás condiciones (región admitida, moneda, backend ACP válido), el producto puede comprarse directamente en ChatGPT en uno o dos clics (lo que eleva mucho la conversión).

Ejemplo de objeto GiftGenius «mínimamente apto» para checkout:

{
  "id": "gg-dev-notebook-plain-usd",
  "title": "Bloc de notas minimalista para desarrollador",
  "description": "Negro, sin líneas, 120 páginas. Para quienes escriben especificaciones a mano.",
  "price": 1500,
  "currency": "usd",
  "availability": "in_stock",
  "link": "https://giftgenius.app/gifts/dev-notebook",
  "image_link": "https://cdn.giftgenius.app/images/dev-notebook.png",
  "enable_search": true,
  "enable_checkout": true
}

Fíjate: incluso en el ejemplo añadimos imagen (image_link) — formalmente puede ser recomendada y no obligatoria, pero sin ella el UX será mucho peor.

5. Campos recomendados y opcionales: cómo hacer el feed «más atractivo»

Los campos obligatorios son «para que funcione». Pero si te quedas solo con eso, tendrás algo parecido a un CSV mínimo para contabilidad, no un escaparate de IA atractivo.

Los campos recomendados suelen incluir:

  • URL principal y adicionales de imágenes;
  • la categoría del producto (a menudo basada en una taxonomía, como «gifts > experiences > online courses»);
  • marca/nombre del comerciante;
  • atributos como color, talla y material;
  • banderas de contenido para adultos, restricciones de edad, etc.

Cuanto más rico describas el producto, más respuestas con sentido podrá generar el modelo. Por ejemplo, si indicas explícitamente que el bloc de notas está hecho de papel reciclado y «apoya a desarrolladores preocupados por el planeta», ChatGPT puede recomendarlo de forma consciente a quien pidiera regalos eco‑amigables.

En GiftGenius podríamos ampliar la descripción de un SKU así:

{
  "id": "gg-dev-notebook-plain-usd",
  "title": "Bloc de notas ecológico para desarrollador",
  "description": "Bloc de notas minimalista sin líneas, 120 páginas de papel reciclado.",
  "price": 1500,
  "currency": "usd",
  "availability": "in_stock",
  "link": "https://giftgenius.app/gifts/eco-dev-notebook",
  "image_link": "https://cdn.giftgenius.app/images/eco-dev-notebook.png",
  "category": "gifts > office > notebooks",
  "brand": "GiftGenius Originals",
  "enable_search": true,
  "enable_checkout": true
}

Atributos adicionales como category y brand no solo mejoran los resultados, sino que ayudan en analítica: puedes ver qué categorías convierten mejor a través de ChatGPT y cuáles peor.

Los campos opcionales suelen estar ligados a escenarios muy específicos (por ejemplo, parámetros geográficos de precio, de los que hablaremos aparte, o metadatos personalizados). Deben añadirse según madure el proyecto, no por cumplir una lista.

6. Flags comerciales y modo solo discovery

Dejemos clara la lógica de enable_search y enable_checkout, porque es el puente crítico hacia las siguientes lecciones sobre ACP e Instant Checkout.

Imagina que acabas de empezar como merchant de ChatGPT. Tienes un catálogo de regalos, pero el ACP‑backend y el Delegated Payment aún están en desarrollo. Quieres que ChatGPT ya pueda encontrar tus SKU y enviar a los usuarios a tu sitio para pagar.

En ese caso:

  • publicas un Product Feed con enable_search = true para los SKU necesarios;
  • dejas enable_checkout = false hasta que implementes y certifiques la integración ACP.

Así, ChatGPT podrá incluir tus regalos en las respuestas a los usuarios, mostrar tarjetas y ofrecer el enlace «Ir al sitio de GiftGenius», pero no construirá el UI interno de Instant Checkout.

Cuando implementes Agentic Checkout y Delegated Payment, podrás pasar ciertos productos al modo «listos para Instant Checkout» con solo establecer enable_checkout = true y cumplir además todos los requisitos de datos (precio, moneda, seller URL, etc.).

A nivel de especificaciones, los campos del Product Feed se usarán para rellenar line_items y el importe en la checkout_session.

De este modo, el feed se convierte en una palanca de ajuste fino: qué SKU y en qué condiciones ChatGPT tiene derecho a vender en tu nombre.

7. Locales, monedas, regiones y precios multirregión

Seguro que ya sabes que el mundo no se limita a en-US y dólares. En los módulos de localización ya hablamos de cómo locale y userLocation afectan a la lógica de negocio. Aquí pasa a primer plano: los productos en Alemania pueden tener otro precio que en EE. UU., y ciertos regalos quizá no puedan venderse en algunos países.

La especificación del Product Feed lo contempla mediante varios mecanismos.

Primero, la moneda: currency debe ser un código ISO 4217 válido (por ejemplo, usd, eur, gbp).

Segundo, se pueden usar campos que describen precio y disponibilidad geodependientes. La documentación presenta un ejemplo de atributos como geo_price y códigos regionales asociados basados en ISO 3166.

Hay dos enfoques arquitectónicos básicos.

Enfoque 1: un feed por región.

  • product-feed-us-en.json para EE. UU.;
  • product-feed-de-de.json para Alemania;
  • product-feed-br-pt.json para Brasil.

En cada feed todos los SKU ya están en la moneda y la locale deseadas. Es más simple para ChatGPT, pero más trabajo para ti al mantener varios feeds.

Enfoque 2: un feed único con campos geográficos.

Dentro de cada registro guardas un array de precios o atributos adicionales:

{
  "id": "gg-dev-notebook-multi",
  "title": "Bloc de notas ecológico para desarrollador",
  "description": "Refuerza tu amor por el código limpio y por el planeta.",
  "prices": [
    { "region": "US", "currency": "usd", "price": 1500 },
    { "region": "DE", "currency": "eur", "price": 1400 }
  ],
  "availability_by_region": [
    { "region": "US", "availability": "in_stock" },
    { "region": "DE", "availability": "out_of_stock" }
  ],
  "enable_search": true,
  "enable_checkout": true
}

La estructura exacta de los campos multirregión depende de la versión de la especificación, pero la idea es la misma: el feed debe permitir a la plataforma entender en qué países existe el SKU y cuánto cuesta allí.

Desde el punto de vista de GiftGenius, es importante pensar el mapeo entre:

  • locale y userLocation, que ChatGPT conoce;
  • y la parte del feed de la que hay que tomar precios y textos.

En escenarios comerciales, rara vez entregas un solo registro «para todo el mundo»; más bien creas distintos SKU por país, para cumplir más fácilmente impuestos, políticas y restricciones de productos.

8. Calidad de datos y política: sin esto, Instant Checkout no despega

El Product Feed no trata solo de formato, sino también de calidad de datos y cumplimiento de la política de OpenAI.

En cuanto a calidad, OpenAI exige explícitamente:

  • identificadores correctos y estables;
  • URL válidas con HTTPS y código de respuesta 200;
  • coherencia entre precio y moneda;
  • disponibilidad actualizada (no debe haber in_stock que en realidad ya no estén).

También hay requisitos de longitud de textos: por ejemplo, title no debe ser demasiado largo (cientos de caracteres), y description tiene un límite razonable (miles de caracteres), para que las tarjetas se vean ordenadas y no parezcan una novela.

Bloque aparte: Prohibited Products Policy. Es la lista de categorías de productos y servicios que no pueden venderse mediante Instant Checkout y/o en ChatGPT en general: cosas obvias como productos ilegales, armas, ciertos servicios médicos, etc. Los detalles hay que revisarlos siempre en la política vigente; lo relevante para nosotros es entender que el Product Feed se validará no solo por formato, sino también por admisibilidad del contenido.

Si tu catálogo contiene categorías ambiguas (por ejemplo, alcohol, juegos de azar o algo relacionado con niños), conviene tratarlas con especial atención. A menudo es más fácil dejarlas en modo enable_checkout = false y vender solo en tu sitio con toda la cobertura legal.

9. Práctica: montamos un Product Feed mínimo para GiftGenius

Apliquemos todo esto en la práctica y armemos un feed sencillo para tres SKU de GiftGenius. Imaginemos que tenemos:

  1. Bloc de notas ecológico para desarrollador.
  2. Suscripción de café de 1 mes.
  3. Vale de regalo para el curso «TypeScript para adultos».

Primero describimos el tipo de TypeScript que usaremos para generar el feed:

export interface GiftGeniusFeedItem {
  id: string;
  title: string;
  description: string;
  price: number;         // en centavos
  currency: "usd" | "eur";
  availability: "in_stock" | "out_of_stock";
  link: string;
  image_link?: string;
  enable_search: boolean;
  enable_checkout: boolean;
}

Ahora creamos en el código un array con varios elementos y luego lo serializamos a JSON:

export const giftGeniusFeed: GiftGeniusFeedItem[] = [
  {
    id: "gg-eco-notebook-usd",
    title: "Bloc de notas ecológico para desarrollador",
    description: "Bloc de notas minimalista sin líneas de papel reciclado.",
    price: 1500,
    currency: "usd",
    availability: "in_stock",
    link: "https://giftgenius.app/gifts/eco-dev-notebook",
    image_link: "https://cdn.giftgenius.app/images/eco-dev-notebook.png",
    enable_search: true,
    enable_checkout: true
  },
  {
    id: "gg-coffee-sub-1m-usd",
    title: "Suscripción de café para desarrollador — 1 mes",
    description: "Caja mensual de café en grano. Compatible con los plazos.",
    price: 2900,
    currency: "usd",
    availability: "in_stock",
    link: "https://giftgenius.app/gifts/coffee-subscription-1m",
    image_link: "https://cdn.giftgenius.app/images/coffee-1m.png",
    enable_search: true,
    enable_checkout: true
  },
  {
    id: "gg-ts-course-gift-usd",
    title: "Vale de regalo para curso de TypeScript",
    description: "Curso online para desarrolladores que por fin quieren entender los generics.",
    price: 9900,
    currency: "usd",
    availability: "in_stock",
    link: "https://giftgenius.app/gifts/ts-course",
    image_link: "https://cdn.giftgenius.app/images/ts-course.png",
    enable_search: true,
    enable_checkout: false // de momento solo discovery
  }
];

Luego puedes hacer una utilidad simple que genere cada N minutos el archivo product-feed.json a partir de esta estructura y lo publique en tu servidor HTTPS.

import { writeFile } from "node:fs/promises";
import { giftGeniusFeed } from "./feed-data";

// Generador JSON del feed más simple
async function buildProductFeed() {
  const json = JSON.stringify(giftGeniusFeed, null, 2);
  await writeFile("public/product-feed.json", json, "utf8");
}

buildProductFeed().catch(console.error);

Está claro que en un proyecto real no tendrás todo el feed en el código; en su lugar, los datos vendrán de la BD. Pero para empezar es útil armar al menos este ejemplo didáctico para probar el pipeline: generación → publicación → validación.

10. Anti‑ejemplo: cómo se ve un Product Feed «malo»

Para entender mejor los requisitos de la especificación y del UX, es útil ver un ejemplo de feed que formalmente casi funciona, pero en la práctica genera problemas:

{
  "id": "1",
  "title": "Regalo",
  "description": "Regalo genial",
  "price": 12.333333,
  "currency": "usdollars",
  "availability": "yes",
  "link": "http://giftgenius.local/gift/1",
  "enable_search": "true",
  "enable_checkout": "maybe"
}

Aquí se pueden contar varios problemas a la vez.

En primer lugar, id = "1" es un identificador pobre e inestable. Si alguna vez migras la BD o introduces sharding, estos identificadores se vuelven frágiles. Es mejor usar ID significativos y suficientemente largos, únicos dentro del merchant.

En segundo lugar, price está indicado como número decimal con cola interminable. Las especificaciones y los sistemas de pago suelen esperar el precio en unidades mínimas (centavos) como número entero, para evitar problemas de coma flotante y redondeo.

En tercer lugar, currency = "usdollars" y availability = "yes" no se ajustan a los formatos esperados (ISO 4217 y lista de estados permitidos).

En cuarto lugar, link apunta a http y a un dominio local; ambas cosas son inaceptables para producción real: la especificación exige HTTPS y accesibilidad pública.

En quinto lugar, los flags enable_search y enable_checkout deben ser booleanos, no cadenas. De lo contrario, el parser de OpenAI o no aceptará el feed o aplicará un valor por defecto que puede sorprenderte desagradablemente.

Estos problemas pueden llevar tanto a un error de validación duro (feed rechazado) como a algo peor: el feed se acepta formalmente, pero parte de los SKU se ignoran o funcionan de forma distinta a la esperada. Por eso conviene invertir en validación interna de tu lado.

11. Errores típicos al trabajar con Product Feed

Error nº 1: pensar en el feed como un «CSV puntual» para importación.
A veces los equipos ven el Product Feed como un archivo que generarán «una vez para la integración» y se olvidarán. En AI‑commerce no es así: el feed es una fuente de la verdad viva, que debe actualizarse regularmente. Si cambias precios, descatalogas productos o lanzas promociones, todo eso debe llegar a tiempo al feed. De lo contrario, ChatGPT recomendará cosas que ya no existen o a precio antiguo, y los usuarios, con razón, se enfadarán.

Error nº 2: mezclar el modelo de producto y el de SKU.
Un antipatrón popular es intentar reflejar un producto base con muchas opciones en un único registro del feed con un montón de campos «size1/size2/size3» o «duration1/duration2». El resultado: el modelo no entiende qué se vende y tu ACP‑backend sufre al desempaquetar esos campos en el momento del checkout. Mucho más simple y fiable: un SKU — un registro del feed, incluso si es una variante dentro del mismo producto.

Error nº 3: ignorar locales y regiones.
Los desarrolladores que hacen el primer MVP suelen poner currency = "usd" y enable_checkout = true para todo, sin pensar en que Instant Checkout puede no estar disponible en tu región o en que ciertos productos no se pueden vender en algunos países por política o ley. Luego, cuando sales a un mercado nuevo, todo empieza a romperse: los precios no cuadran, no se contemplan impuestos. Es mejor vincular desde el principio los SKU a regiones y monedas, incluso si por ahora solo tienes un mercado.

Error nº 4: tratar las descripciones como textos SEO del pasado.
Algunos equipos copian al Product Feed descripciones antiguas de sus sitios, a veces escritas para «keywords» y robots. Para ChatGPT eso es más perjudicial que útil: el modelo ya sabe escribir; lo que más valora son hechos estructurados, honestos y precisos. Mejor describir breve y al grano que llenar description de palabrería de marketing.

Error nº 5: no validar el feed por tu cuenta.
Confiar solo en la validación de OpenAI es receta para noches duras antes de los deadlines. Conviene crear un validador sencillo en tu backend o en CI que compruebe los esquemas de campos, valores permitidos, formatos de URL y monedas. Se puede hacer incluso en TypeScript, usando por ejemplo Zod o comprobaciones propias. Así detectarás problemas antes de subir el feed a producción.

Error nº 6: incluir en el Product Feed «todo lo que hay».
A veces apetece meter miles de SKU «por si acaso». En la práctica complica el debug, la analítica y el control de calidad. Es mucho más sensato empezar con un subconjunto acotado: solo aquellas categorías y SKU que estás listo para mantener y que realmente quieres vender a través de ChatGPT. El resto puede quedarse en modo discovery o incluso prescindir de la integración.

Error nº 7: no sincronizar el Product Feed y el ACP‑backend.
El feed y el ACP‑API son dos caras de la misma moneda. Si en el feed aparece un nuevo SKU y tu backend aún no sabe venderlo (o al revés, el SKU se quitó del feed, pero el backend cree que existe), tendrás desincronización, bugs complicados y tickets de soporte complejos. Es buena práctica tener un modelo de dominio de catálogo único y usarlo tanto para generar el feed como para procesar el checkout.

Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION