Commerce Guide

Promotions in ChatGPT Shopping in 2026: Why They Are API-Only, and What That Breaks

Most teams plan a nightly file feed with discounts as a column. OpenAI's spec does not allow it. Promotions are their own object, on their own endpoint, with only three discount types and a PATCH that never deletes.

Distk Editorial Oct 2026 11 min read

OpenAI's agentic commerce integration guide states that promotions data can only be provided via the API, even though it recommends delivering the full product feed by daily file upload. A promotion is its own object with four required fields: id, title, active_period and benefits. Benefits are limited to amount_off, percent_off and free_shipping, so buy-one-get-one, bundles and tiered offers have no direct representation. Money uses integer ISO 4217 minor units with a currency, not the amount-plus-code string used in file feeds. The PATCH endpoint upserts promotions matched by id and leaves any promotion not included unchanged, so ending a promotion means updating it, not omitting it. Products are targeted through applies_to with product and optional variant IDs, which only works if those IDs are stable. Feed onboarding in ChatGPT is currently limited to approved partners via chatgpt.com/merchants.

Why Are Promotions in ChatGPT Shopping API-Only in 2026?

Because OpenAI's integration guide says so in one plain sentence: "Promotions data can only be provided via the API." The same guide recommends providing the entire product feed once a day by file upload and sending updates through the API during the day. That pattern works for products. For promotions, the file-upload half does not exist, so a team planning a daily feed with discounts baked in has to build an API path regardless of feed size.

This is easy to miss because most commerce teams think of a sale as a column on a product row. In OpenAI's model, a promotion is its own object with its own endpoint, its own identity and its own time window, linked to products by reference. This guide is the promotions spoke in our guide to the Agentic Commerce Protocol product feed, and the usual gate applies: feed onboarding in ChatGPT is currently available to approved partners via chatgpt.com/merchants.

What Is a Promotion Object in 2026?

A promotion is a record with an identifier, a title, an active period, and one or more benefits, plus optional description, status, product targets and URL. Four fields are required: id, title, active_period and benefits. Everything that ties a promotion to particular products, the applies_to list, is optional in the schema.

FieldTypeRequiredWhat it does in 2026
idstringYesPromotion identifier; upserts are matched by it.
titlestringYesPromotion title.
descriptionDescriptionNoAt least one of plain, html or markdown when supplied.
statusPromotionStatusNoKnown values: draft, scheduled, active, expired, disabled.
active_periodDateTimeRangeYesRequired start_time and end_time.
benefitsPromotionBenefit[]YesOne or more of amount off, percent off, free shipping.
applies_toProductTarget[]NoProducts, and optionally specific variants, targeted.
urlstring (uri)NoCanonical promotion URL.

What Kinds of Discounts Can a Promotion Express in 2026?

Three, and only three. PromotionBenefit is a union of AmountOffBenefit, PercentOffBenefit and FreeShippingBenefit. That covers the large majority of retail promotions and excludes the structured ones that are common in Indian D2C, such as buy-two-get-one, bundle pricing, tiered spend thresholds and gift-with-purchase. Those either need to be expressed as one of the three types or left out of the promotion feed.

Benefit typeRequired fieldsExample use in 2026
amount_offtype, amount_off as a PriceA flat discount in currency.
percent_offtype, percent_off as a numberA percentage discount.
free_shippingtype onlyShipping waived.

Money inside a promotion follows the API convention, not the file-upload one. A Price is an integer amount in ISO 4217 minor units plus a currency. So a 200 rupee discount is the integer 20000 in minor units, not the string "200.00 INR". Reusing a file-feed price formatter here produces discounts a hundred times too large or too small.

How Do the Promotion Endpoints Work in 2026?

There are two: one to read and one to write. GET /product_feeds/{id}/promotions returns the promotions for a feed. PATCH /product_feeds/{id}/promotions upserts promotions into the feed, matched by id, and promotions not included in the request remain unchanged.

That last sentence shapes how you run promotions operationally. A PATCH is not a replace. Sending today's three live promotions does not remove yesterday's, because promotions not included are left untouched. Ending a promotion therefore means updating it, for example by changing its status or its active period, rather than omitting it from the next request.

ResponseWhen it is returnedWhat to do in 2026
200 OK on PATCHReturns id and an accepted booleanCheck accepted, not just the status code.
400 Bad RequestThe promotion payload is invalidValidate required fields and benefit shapes before sending.
404 Not FoundThe feed is not foundConfirm the feed ID belongs to your onboarded integration.

How Should Promotions Connect to Products in 2026?

Through applies_to, a list of ProductTarget objects. Each target requires a product_id and optionally lists variant_ids within that product. That means your promotion targets only work if your product IDs are stable, which is the same identity discipline the product feed specification asks for: never reuse an ID for a different item, and keep IDs stable when price, stock, title or images change.

A separate point applies to the product rows themselves. The file-upload specification supports a sale_price on a product, which must be greater than zero, strictly below the regular price, and in the same currency. That is a price on the product, not a promotion object. Teams should decide deliberately which mechanism represents a given discount, rather than sending both and leaving the platform to reconcile them, because the specification states that neither representation reconciles conflicting values for you in related cases such as variant attributes.

How Do Common Indian D2C Offers Map to the Three Benefit Types in 2026?

Some map cleanly, some map with a compromise, and some have no representation at all. The table below applies only the three documented benefit types to offers that Indian D2C brands commonly run. It is our mapping of the schema, not guidance OpenAI has published, and anything marked as a compromise should be checked with OpenAI during onboarding before you rely on it.

Offer you runClosest documented benefitFit in 2026
Flat 200 off on a productamount_offClean fit.
20 percent off sitewide or a categorypercent_off with applies_to listing the productsClean fit if you can enumerate the products.
Free delivery above no thresholdfree_shippingClean fit.
Free delivery above a minimum order valuefree_shippingCompromise: the schema has no threshold field.
Extra discount for prepaid ordersNoneNo representation; payment-method conditions are not in the schema.
Buy two get one freeNoneNo representation.
Bundle price for a comboNone as a promotionConsider listing the bundle as its own product with its own price.
Coupon code shared on InstagramNone documentedNo code field in the schema; do not assume code support.

The practical consequence for a festive-season calendar is that the offers you can describe to ChatGPT are a subset of the offers you actually run. That is not a reason to skip promotions, because the clean fits are usually the headline offers. It is a reason to decide in advance which offers you will represent, rather than discovering the gap when a Diwali campaign goes live.

What Does a Promotion Payload Look Like in 2026?

OpenAI's promotions page documents the schema but does not include a sample payload. The example below is our own illustration, assembled strictly from the documented field names, types and enum values, for a 15 percent discount on two variants of one product. Treat it as a shape to validate against the specification, not as an OpenAI example.

[
  {
    "id": "promo-diwali-15",
    "title": "Diwali 15% off",
    "status": "scheduled",
    "active_period": {
      "start_time": "2026-10-17T00:00:00+05:30",
      "end_time": "2026-10-24T23:59:59+05:30"
    },
    "benefits": [
      { "type": "percent_off", "percent_off": 15 }
    ],
    "applies_to": [
      { "product_id": "KURTA-COTTON", "variant_ids": ["KURTA-COTTON-M", "KURTA-COTTON-L"] }
    ]
  }
]

Two things in that illustration deserve a check against your own integration. The specification describes start_time and end_time only as start and end timestamps without fixing a format, so confirm the expected timestamp format during onboarding. And the request body is an array of promotions, so a single promotion is still sent inside a list.

Why Does API-Only Change the Build Plan in 2026?

Because the cheapest integration most teams plan, a nightly file export dropped on a server, cannot carry promotions at all. If discounts matter to your conversion, and for most Indian D2C brands during festive season they matter a great deal, then an API integration is not optional work for a later phase. It is part of the minimum build.

What Are the Common Mistakes With ChatGPT Promotions in 2026?

Key Takeaways for 2026

Distk helps D2C and e-commerce teams in India and internationally map their real promotion calendar onto what AI shopping surfaces can actually express, and plan the API work that file feeds cannot cover. If festive-season discounts are part of your ChatGPT plan for 2026, that mapping is where we start. For the full field reference on products, see our ChatGPT product feed requirements guide.

Sources

ChatGPT Shopping Promotions: FAQs

Can promotions be included in a ChatGPT product feed file?

No. OpenAI's integration guide states that promotions data can only be provided via the API. Products can be delivered by file upload, but promotions need the promotions endpoint.

What discount types does ChatGPT Shopping support?

Three benefit types: amount_off, percent_off and free_shipping. Offers such as buy-two-get-one, bundle pricing or tiered spend discounts have no direct type and must be mapped onto these or left out.

What fields does a promotion need?

Four are required: id, title, active_period with start_time and end_time, and benefits. Description, status, applies_to product targets and url are optional.

How do I end a promotion?

Update it, for example by changing its status or active period. The PATCH endpoint upserts promotions matched by id and leaves any promotion not included in the request unchanged, so omitting it does not remove it.

How should discount amounts be formatted?

As a Price object with an integer amount in ISO 4217 minor units and a currency. This differs from the file-upload product format, which writes money as a decimal string followed by a currency code.

Can a promotion apply to specific variants?

Yes. The applies_to list holds ProductTarget objects, each requiring a product_id and optionally listing variant_ids within that product.

Map your real promotion calendar onto what the API can express

Distk maps festive-season and everyday offers onto AI shopping promotion schemas, plans the API work that file feeds cannot cover, and tells you which discounts will not survive the translation.

Start the conversation →