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.
| Field | Type | Required | What it does in 2026 |
|---|---|---|---|
id | string | Yes | Promotion identifier; upserts are matched by it. |
title | string | Yes | Promotion title. |
description | Description | No | At least one of plain, html or markdown when supplied. |
status | PromotionStatus | No | Known values: draft, scheduled, active, expired, disabled. |
active_period | DateTimeRange | Yes | Required start_time and end_time. |
benefits | PromotionBenefit[] | Yes | One or more of amount off, percent off, free shipping. |
applies_to | ProductTarget[] | No | Products, and optionally specific variants, targeted. |
url | string (uri) | No | Canonical 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 type | Required fields | Example use in 2026 |
|---|---|---|
amount_off | type, amount_off as a Price | A flat discount in currency. |
percent_off | type, percent_off as a number | A percentage discount. |
free_shipping | type only | Shipping 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.
| Response | When it is returned | What to do in 2026 |
|---|---|---|
200 OK on PATCH | Returns id and an accepted boolean | Check accepted, not just the status code. |
400 Bad Request | The promotion payload is invalid | Validate required fields and benefit shapes before sending. |
404 Not Found | The feed is not found | Confirm 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 run | Closest documented benefit | Fit in 2026 |
|---|---|---|
| Flat 200 off on a product | amount_off | Clean fit. |
| 20 percent off sitewide or a category | percent_off with applies_to listing the products | Clean fit if you can enumerate the products. |
| Free delivery above no threshold | free_shipping | Clean fit. |
| Free delivery above a minimum order value | free_shipping | Compromise: the schema has no threshold field. |
| Extra discount for prepaid orders | None | No representation; payment-method conditions are not in the schema. |
| Buy two get one free | None | No representation. |
| Bundle price for a combo | None as a promotion | Consider listing the bundle as its own product with its own price. |
| Coupon code shared on Instagram | None documented | No 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.
- You need API credentials and a feed ID, which come with onboarding as an approved partner.
- You need a promotions source of truth in your own systems, with stable IDs and explicit start and end times.
- You need a process for ending promotions, because omitting one from a PATCH leaves it unchanged.
- You need a money converter for minor units, separate from any file-feed formatter.
- You need to map rich offers onto amount off, percent off or free shipping, or accept leaving them out.
What Are the Common Mistakes With ChatGPT Promotions in 2026?
- Planning promotions into a nightly file feed. OpenAI states promotions can only be provided via the API.
- Treating PATCH as replace. Promotions not included in a request remain unchanged.
- Formatting discounts as strings. Promotion money is an integer in minor units with a currency.
- Expecting buy-X-get-Y support. Benefits are amount off, percent off or free shipping.
- Targeting unstable product IDs.
applies_todepends on the same IDs your feed uses. - Ignoring the
acceptedflag. A 200 response still tells you whether the payload was accepted. - Representing the same discount twice as both a product sale price and a promotion without deciding which is authoritative.
Key Takeaways for 2026
- OpenAI states promotions data can only be provided via the API, not by file upload.
- A promotion needs
id,title,active_periodandbenefits. - Benefits are limited to
amount_off,percent_offandfree_shipping. - Money is an integer in ISO 4217 minor units, not the
amount CURRENCYstring used in file feeds. PATCHupserts by ID and leaves unlisted promotions unchanged, so ending one means updating it.- Product targeting depends on stable product and variant IDs.
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.