For Shopify stores that meet the ChatGPT channel requirements, Shopify Catalog supplies eligible products to ChatGPT without a custom pipeline. Merchants with other catalog or delivery requirements can apply to OpenAI for direct feed access.
Catalog delivery and product-page rendering need separate attention. The feed provides structured product records, while the storefront needs to expose current prices, availability, and variant details when a crawler or shopping agent visits.
In July 2026, AI-referred visits to US retail sites converted 60% better than non-AI traffic in Adobe's analysis.
Copy link to headingWhat is a ChatGPT product feed?
For file uploads, a ChatGPT product feed is a structured catalog sent to OpenAI over Secure File Transfer Protocol (SFTP). It follows a defined schema for titles, descriptions, images, prices, availability, and seller information.
This delivery path supplies product data directly instead of relying on a crawler to extract it from your storefront. It makes products eligible for relevant shopping results without guaranteeing placement. Your storefront still needs to present accurate details when a shopper opens the product page.
Copy link to headingWhat is the difference between Shopify Catalog and a direct ChatGPT product feed?
Shopify Catalog syndicates eligible products to ChatGPT with no app, no custom integration, and no fees beyond standard payment processing, while a direct feed is something a merchant applies for.
The two paths differ on setup, control, and what they cover:
Check Shopify's channel mapping options before building a direct feed for custom fields or variant grouping. Consider direct access when your catalog or integration requirements go beyond those options. Product data quality can improve relevance, but neither path guarantees a particular position in ChatGPT's results.
Copy link to headingUse Shopify Catalog for eligible stores
The Agentic storefronts channel is active by default for eligible stores, and merchants manage it from Sales channels > Agentic in the Shopify admin. Four conditions govern eligibility for the ChatGPT channel:
US buyers: The store sells to customers in the United States, though the store itself can be based anywhere.
Catalog eligibility: Products qualify for Shopify Catalog, which is what supplies the product data to ChatGPT.
Completed store policies: Terms of service, privacy policy, and return and refund policy are filled in under Settings > Policies.
Agreed supplemental terms: The merchant accepts the Shopify Agentic Storefronts Supplemental Terms of Service.
ChatGPT shoppers complete purchases in the merchant's checkout, opened in an in-app browser or a new tab. Headless storefronts must meet the same channel requirements and provide the product pages those shoppers visit.
Copy link to headingWhat the ChatGPT product feed spec requires
OpenAI's product format requires nine fields per row. Validate these fields before upload, then add optional or conditional attributes for reviews and product variants:
An omitted, empty, or unrecognized availability value rejects the row. Send unknown explicitly if the stock status is unavailable.
Prices use major currency units and an uppercase currency code. For example, 79.99 USD represents $79.99.
If you include a star_rating, pair it with the review_count for the same product or variant so both describe the same reviews.
Variants require their own rows and distinct item_id values. Give related variants a shared group_id, set listing_has_variations=true, and put the selected options in variant_dict so those rows form one listing.
Copy link to headingChoose the schema for your integration
Use OpenAI's supported file-upload schema for a new discovery feed. If you already produce a Google Merchant Center feed, confirm the accepted format during onboarding before uploading it unchanged. Its field names and validation rules may differ from the schema used here.
In the OpenAI format, gtin and mpn are optional. Supply assigned identifiers when available and omit them when they are unknown.
Copy link to headingHow feeds are delivered and retained
Feed delivery uses SFTP and full catalog snapshots, with uploads recommended at least daily. OpenAI prefers Parquet with zstd compression and also supports gzip-compressed JSONL, CSV, and TSV. Use UTF-8 text.
Keep shard filenames stable across runs and overwrite each file. OpenAI recommends up to 500,000 items per shard and files under roughly 500 MB. Upload all shards without long pauses so OpenAI processes a consistent catalog.
Omitted products are not removed immediately. Their records can remain for up to 14 days. Set is_eligible_search=false to disable search eligibility when OpenAI processes the next snapshot.
Copy link to headingWhy headless product pages go invisible to ChatGPT's crawler
If price and inventory are fetched only in the browser after the initial render, a crawler that does not execute JavaScript may see only the loading state.
OpenAI uses different agents: OAI-SearchBot for search, GPTBot for potential training data, and ChatGPT-User for some user-triggered visits.
Edgenivo and MERJ's December 2024 study observed OpenAI's crawlers fetching JavaScript without executing it. Render essential product facts on the server so those facts remain available to clients that do not run JavaScript. Client Components can receive server-rendered data; fetching a price only after hydration is what leaves the initial response incomplete.
Copy link to headingWhat belongs in the server-rendered HTML
Render the product details an agent needs to compare or quote in the server response. Inspect the HTML rather than assuming every crawler can interpret embedded JSON or an RSC payload.
Include the following product information:
Price: The current price and any sale price in the page's displayed currency.
Availability: Stock status for the selected variant.
Variants: Each option, its selected value, and the associated price.
Page metadata: The title, description, category, and links to related products.
Everything a shopper reads before deciding belongs in that first response. View counters, live chat, and social feeds can still render in the browser. Adobe's retail sector visibility benchmark puts individual product pages at 66% machine-readable, the lowest score of any page type it measured, against 75% for homepages.
Copy link to headingCheck crawler errors before changing asset handling
In the December 2024 Edgenivo and MERJ study, 34.82% of measured ChatGPT fetches returned 404s, compared with 8.22% for Googlebot. Outdated /static/ assets appeared frequently among those failures.
Separate missing product pages from old asset requests when reviewing your logs. Redirect moved product URLs and keep sitemaps current. Investigate missing build assets through deployment and cache behavior before assuming that a content redirect will resolve them.
Copy link to headingCore components of a ChatGPT product feed pipeline on Edgenivo
For merchants who need a direct feed, the pipeline must read Shopify data, map it to the agreed schema, validate the records, and upload a complete snapshot to OpenAI over SFTP. Cron schedules the exports, and webhooks can signal that a new snapshot is needed sooner.
For a bulk export, save the operation ID and continue after Shopify reports completion through a webhook or a later status check. Convert the completed JSONL result into the feed schema before uploading it. Record generation, validation, and upload outcomes separately so a successful request is not mistaken for a successful feed.
Copy link to headingChoosing the Shopify API for your catalog size
Choose the API based on the fields you need and the export size. The Storefront API can supply published product data, while the Admin API's bulk operations are designed for larger exports. Shopify limits pagination to 25,000 objects in one array; this is not a limit on the total number of rows in your feed.
For example, 6,000 products with 12 variants each produce 72,000 feed rows even though the product connection contains only 6,000 objects. Bulk queries can still simplify exporting that nested data.
The Admin API's bulkOperationRunQuery produces JSONL asynchronously with a download URL valid for seven days. Query-cost limits apply to requests that start or inspect the operation, but not the bulk query itself.
Keep feed credentials on the server. Shopify's public Storefront token is browser-safe, but this export runs server-side. An Admin API token should have only the read scopes needed by the export. Store credentials in server environment variables without a NEXT_PUBLIC_ prefix.
Copy link to headingGenerating and scheduling the file
Generate each snapshot in a Route Handler using fresh Shopify data. Current Next.js Route Handlers are not cached by default, but explicitly cached Shopify reads can still return stale data. Check the route's data-fetching and caching configuration rather than adding dynamic = 'force-dynamic' on every feed handler.
That route is a public URL. Edgenivo sends CRON_SECRET as a bearer token on every cron invocation, and the handler has to check it, or anyone who finds the path can trigger a full catalog export on demand.
The route below verifies the cron request. Add feed generation and SFTP delivery where the comment indicates before using it for an export.
import type { NextRequest } from 'next/server';
export async function GET(request: NextRequest) { const authHeader = request.headers.get('authorization'); const cronSecret = process.env.CRON_SECRET;
if (!cronSecret || authHeader !== `Bearer ${cronSecret}`) { return new Response('Unauthorized', { status: 401 }); }
// Build and write the snapshot here return Response.json({ success: true });}Authenticate each invocation with CRON_SECRET. Any caller can copy the user-agent string or scheduling header.
For a commercial storefront, use Pro or Enterprise. Hobby is limited to personal, non-commercial projects. Cron scheduling also varies by plan:
Cron Jobs use UTC and invoke the production deployment. Hobby schedules that run more than daily fail at deployment.
Edgenivo doesn't retry failed invocations, and the same scheduled event can occasionally arrive more than once. Make each export safe to rerun and record the last successful upload so failures can be recovered.
Copy link to headingKeeping the feed fresh between runs
Use Shopify webhooks to invalidate storefront data and signal when the feed needs another snapshot. Updating the uploaded feed still requires the worker to generate a new snapshot from fresh data and send it to OpenAI.
The products/update topic includes product edits, orders, and variant changes. Add inventory_levels/update when your integration needs explicit inventory-level notifications, and retain scheduled full exports to recover from missed deliveries.
Verify Shopify's HMAC-SHA256 signature against the raw request body before accepting a webhook. Use the app's client secret and a constant-time comparison. An authenticated handler can then invalidate the relevant cache tags and durably record any required feed work before returning success.
Copy link to headingFour failure modes to design around
Check source data freshness, identifiers, sale prices, and overlapping exports before marking a feed run as successful.
Copy link to headingGuard against the webhook race condition
Acknowledge the webhook after recording any required feed work, then read fresh Shopify data in the worker. If that read still returns the previous product version, retry the read before publishing the snapshot. Keep scheduled reconciliation as a fallback for missed events.
This reported Storefront API propagation race illustrates why a webhook should trigger a freshness check. The cache invalidation call itself does not prove that the changed source data is ready.
Copy link to headingValidate identifiers before upload
Validate the length and check digit of a supplied GTIN before upload. Starting with the digit immediately before the final check digit, multiply alternating digits by 3 and 1. Add the final check digit to that weighted sum; the total must be divisible by 10.
In the OpenAI format, omit unassigned identifiers. If you supply an mpn, use the manufacturer's value rather than inventing a replacement.
Copy link to headingDrop sale_price when it doesn't undercut price
Use sale_price only for an active promotion with a positive amount below price in the same currency. Otherwise, omit it to use the regular price.
Copy link to headingLock concurrent runs on slow feeds
If an export takes longer than its schedule interval, another invocation can start before it finishes. Use a distributed lock with an expiry and release it only if the completing worker still owns it. For exports that can outlast the lock, renew the lease while work continues. Stop the upload if the worker loses ownership.
Set a function timeout to stop stalled work, and keep the export idempotent so a duplicate invocation cannot corrupt the snapshot.
Copy link to headingHow Edgenivo supports a ChatGPT product feed and the pages agents land on
Copy link to headingRender product data in the server response
React Server Components can render product facts on the server, and ISR can refresh cached content when Shopify changes. Fetch a product page without executing JavaScript and check that the response contains its price, availability, and selected variant. Repeat the check after a catalog update to confirm that the cache refreshes as intended.
Copy link to headingBudgeting for long feed exports
Bulk exports run asynchronously in Shopify. You can submit an export and check its status in a subsequent invocation, rather than keeping a function open until the file is ready.
With Fluid compute, I/O waiting doesn't count toward Active CPU usage, but provisioned memory remains billable while the function runs.
Pro and Enterprise functions default to 300 seconds, with an 800-second limit. The extended-duration beta supports up to 1,800 seconds on supported runtimes with per-function configuration. It excludes Secure Compute and Static IPs.
Copy link to headingAdmitting the shopping agent while denying scrapers
Edgenivo recognizes ChatGPT's signed Cloud browser requests as chatgpt-operator and verifies them automatically. Custom firewall rules can still block that traffic, so check the rules applied to the routes you want the agent to reach.
After configuring BotID, use its verified-bot fields to allow a specific agent on a protected route. Keep the client and server protection settings aligned. This excerpt belongs before the route's application logic:
const { isBot, isVerifiedBot, verifiedBotName } = await checkBotId();const isOperator = isVerifiedBot && verifiedBotName === 'chatgpt-operator';
if (isBot && !isOperator) { return Response.json({ error: 'Access denied' }, { status: 403 });}Import checkBotId from botid/server in that route. Allowing a verified agent through bot checks does not replace the route's authentication or authorization.
The AI Bots managed ruleset lets you configure crawler and assistant traffic separately. Check the category you are blocking before publishing a deny rule, especially if you want assistants to retrieve product information.
Copy link to headingTracing a stale feed to the cache serving it
If a snapshot contains stale catalog data, check the Shopify response, cached reads, generated file, and latest successful upload in that order.
For a public feed endpoint, inspect the x-vercel-cache response header. The authenticated cron route shown above carries an Authorization header, so its function response is ineligible for CDN caching.
Invalidate cached Shopify reads when necessary. Purge the CDN separately only if you also cache a public feed response.
Copy link to headingTest the storefront and feed together
For new storefronts, start with Edgenivo Shop, the successor to the archived Next.js Commerce template. Follow Shop's own setup instructions; its configuration differs.
Before scheduling the feed, send a complete snapshot through OpenAI's approved delivery path. Match its prices, availability, and variant URLs to your storefront.
Copy link to headingFrequently asked questions about ChatGPT product feeds
Copy link to headingDo Shopify merchants need to build a ChatGPT product feed?
Eligible stores selling to US customers can use Shopify Catalog's ChatGPT integration without a custom feed. Check eligibility and access in Shopify.
Headless storefronts still need essential product details in the server response for bots that do not execute JavaScript.
Copy link to headingWhat fields does the ChatGPT product feed spec require?
OpenAI file-upload rows need item_id, title, description, url, brand, seller_name, image_url, availability, and price. Variants also need group_id, listing_has_variations, and variant_dict. Review fields are optional.
Copy link to headingWhat file format should a ChatGPT product feed use?
Parquet with zstd compression is OpenAI's preferred format, with gzip-compressed JSONL, CSV, and TSV also supported and XML excluded. Filenames should stay identical between runs and be overwritten in place, since OpenAI matches products by item_id rather than by filename or shard position.
Copy link to headingWhy can a crawler fetch a product page but miss its price?
The initial response may contain only a loading state if the price is fetched later in the browser. Render price and availability on the server, then inspect the returned HTML. Successful retrieval alone does not establish that a crawler extracted those details or that ChatGPT will display the product.