Optimization Guide
Ecommerce Bundle Discount Schema for AI Shopping Agents
Bundle discounts, BOGO deals, and multi-buy pricing are invisible to AI shopping agents unless you encode them in JSON-LD structured data. Shopify automatic discounts apply at checkout — but AI agents never see checkout. Here's how to fix that.
Offer blocks with eligibleQuantity to expose bundle pricing to AI agents. One base Offer at full unit price (minValue: 1) and one bundle Offer at the effective discounted price (minValue: 2 or your threshold). Add an additionalProperty block with propertyID: "promotionType" for explicit promotion classification. Shopify automatic discounts never surface in structured data — you must encode the discounted price directly in your template.
Why Bundle Discounts Are Invisible to AI Agents
Shopify's discount system works entirely at checkout time. When a customer qualifies for "Buy 2 Get 10% Off", the discount applies in the cart on a checkout.shopify.com URL that AI agents cannot crawl. From an AI agent's perspective, your product has exactly one price: whatever appears in your product page JSON-LD.
| Discount type | Shopify mechanism | AI agent visibility |
|---|---|---|
| Automatic discount (buy X, save Y%) | Shopify Scripts / Discount Functions | Invisible — checkout only |
| Discount code (BUNDLE20) | Checkout coupon field | Invisible — requires code entry |
| Compare-at price on individual variant | Shopify Admin compare-at field | Visible if reflected in JSON-LD |
| Bundle price in product JSON-LD | Custom Liquid / theme edit | Visible — fully machine-readable |
| Bundle price in product description | Product admin description | Partial — NLP fallback only |
The implication: if you run any bundle deals that aren't reflected in JSON-LD, competing stores with cleaner markup will appear to offer better per-unit pricing — even if your effective price is lower. AI agents recommend based on what they can confirm, not what they have to guess.
Core Pattern: Dual Offer Blocks with eligibleQuantity
The schema.org standard for quantity-conditional pricing is the eligibleQuantity property on an Offer. Publish one Offer per pricing tier, each with its own quantity constraint using QuantitativeValue.
Buy 2, save 10% — full example
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Daily Vitamin C Serum 30ml",
"offers": [
{
"@type": "Offer",
"name": "Single bottle",
"price": "38.00",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"eligibleQuantity": {
"@type": "QuantitativeValue",
"minValue": 1,
"maxValue": 1,
"unitCode": "C62"
}
},
{
"@type": "Offer",
"name": "2-pack — save 10%",
"price": "34.20",
"highPrice": "38.00",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"eligibleQuantity": {
"@type": "QuantitativeValue",
"minValue": 2,
"unitCode": "C62"
},
"additionalProperty": [
{
"@type": "PropertyValue",
"propertyID": "promotionType",
"name": "Promotion Type",
"value": "MultiBuyDiscount"
},
{
"@type": "PropertyValue",
"propertyID": "discountPercent",
"name": "Discount",
"value": "10%"
}
]
}
]
}
Three-tier bundle (1 / 3 / 6)
"offers": [
{
"@type": "Offer", "name": "Single unit",
"price": "24.00", "priceCurrency": "USD",
"eligibleQuantity": { "@type": "QuantitativeValue", "minValue": 1, "maxValue": 2, "unitCode": "C62" }
},
{
"@type": "Offer", "name": "3-pack — save 15%",
"price": "20.40", "highPrice": "24.00", "priceCurrency": "USD",
"eligibleQuantity": { "@type": "QuantitativeValue", "minValue": 3, "maxValue": 5, "unitCode": "C62" },
"additionalProperty": { "@type": "PropertyValue", "propertyID": "discountPercent", "value": "15%" }
},
{
"@type": "Offer", "name": "6-pack — save 25%",
"price": "18.00", "highPrice": "24.00", "priceCurrency": "USD",
"eligibleQuantity": { "@type": "QuantitativeValue", "minValue": 6, "unitCode": "C62" },
"additionalProperty": { "@type": "PropertyValue", "propertyID": "discountPercent", "value": "25%" }
}
]
BOGO Schema Pattern
Buy One Get One deals have an effective per-unit price of half the single-unit price for BOGO Free, or proportionally less for BOGO discounts. Encode this with maxValue: 2 and the correct effective price:
{
"@type": "Offer",
"name": "BOGO Free — buy 2, pay for 1",
"price": "22.50",
"highPrice": "45.00",
"priceCurrency": "USD",
"eligibleQuantity": {
"@type": "QuantitativeValue",
"minValue": 2,
"maxValue": 2,
"unitCode": "C62"
},
"additionalProperty": [
{
"@type": "PropertyValue",
"propertyID": "promotionType",
"value": "BOGO"
},
{
"@type": "PropertyValue",
"propertyID": "promotionDescription",
"value": "Buy one, get one free — add two to cart to apply"
}
]
}
Shopify Liquid Implementation
Store bundle pricing in a product metafield namespace (bundle.discount_pct, bundle.min_qty) and read it in your Liquid template. This approach lets marketing update discounts through Shopify Admin without touching theme code:
{% comment %} In product.liquid, inside the offers array {% endcomment %}
{% if product.metafields.bundle.discount_pct %}
{% assign bundle_qty = product.metafields.bundle.min_qty | default: 2 %}
{% assign discount = product.metafields.bundle.discount_pct | times: 1.0 %}
{% assign bundle_price = product.price | times: 1.0 | divided_by: 100 %}
{% assign bundle_price = bundle_price | times: 100 | minus: discount | divided_by: 100 %}
,{
"@type": "Offer",
"name": {{ bundle_qty | append: "-pack bundle — save " | append: product.metafields.bundle.discount_pct | append: "%" | json }},
"price": {{ bundle_price | money_without_currency | json }},
"highPrice": {{ product.price | money_without_currency | json }},
"priceCurrency": {{ cart.currency.iso_code | json }},
"availability": "https://schema.org/InStock",
"eligibleQuantity": {
"@type": "QuantitativeValue",
"minValue": {{ bundle_qty }},
"unitCode": "C62"
},
"additionalProperty": {
"@type": "PropertyValue",
"propertyID": "discountPercent",
"value": {{ product.metafields.bundle.discount_pct | append: "%" | json }}
}
}
{% endif %}
Setting bundle metafields in Shopify Admin
Define two metafields in your Shopify Admin → Settings → Custom data → Products:
| Namespace.key | Type | Example value |
|---|---|---|
bundle.discount_pct | Integer (number) | 10, 15, 25 |
bundle.min_qty | Integer (number) | 2, 3, 6 |
Bundle Discount Description Supplement
Add bundle pricing explicitly to your product description for NLP fallback coverage. AI agents parse description text when structured data is missing or ambiguous:
| Pattern | Example phrase |
|---|---|
| Quantity + savings statement | "Buy 2 and save 10% — automatically applied at checkout." |
| Per-unit effective price | "As low as $20.40 per bottle when you buy 2 or more." |
| BOGO explicit statement | "Buy one, get one free — add any two to your cart." |
| Tiered savings table in description | "Buy 3: save 15% | Buy 6: save 25% | Buy 12: save 30%" |
promotionType Values for AI Agent Classification
Using consistent promotionType values in your additionalProperty helps AI agents classify and filter promotions accurately:
| promotionType value | Use case | Example |
|---|---|---|
MultiBuyDiscount | Buy N, save X% | Buy 2 get 10% off |
BOGO | Buy one get one free / half price | BOGO free, BOGO 50% off |
BundleSavings | Fixed amount off a bundle | $10 off when you buy 3 |
VolumeDiscount | Tiered pricing by volume | 3-pack: 15%, 6-pack: 25% |
FreeShippingBundle | Free shipping triggered by quantity | Free shipping when you buy 2+ |
Bundle Discount Schema Checklist
- Store bundle discount parameters in product metafields (
bundle.discount_pct,bundle.min_qty) rather than hard-coding values - Add a second
Offerblock to your product JSON-LD witheligibleQuantity.minValueequal to the bundle threshold - Set
pricein the bundle Offer to the effective per-unit discounted price (not the total bundle price) - Set
highPriceto the full unit price so AI agents can calculate the savings percentage - Add
additionalPropertywithpromotionTypeanddiscountPercentfor explicit classification - Add bundle pricing language to your product description for NLP fallback coverage
- For time-limited bundle deals, add
priceValidUntilwith an ISO 8601 date string - Validate the updated JSON-LD using Google's Rich Results Test to catch syntax errors
- Ping IndexNow with updated product URLs after publishing bundle markup
Related Resources
- Shopify Product Bundle Structured Data — JSON-LD patterns for gift sets and product bundles using ItemList.
- Shopify Subscription Pricing Structured Data — UnitPriceSpecification for recurring billing models.
- Shopify Schema Markup Guide — full Product, Offer, and additionalProperty implementation guide.
- AI Shopping Agent Product Ranking Factors — the full 18-signal model where pricing clarity fits in.
Frequently Asked Questions
How do I mark up a buy-two-get-one-free deal in JSON-LD?
Use Offer.eligibleQuantity with QuantitativeValue (minValue 2, maxValue 2) and set price to the effective per-unit cost (half of the single unit price for BOGO free). Add an additionalProperty with promotionType: "BOGO" and a promotionDescription explaining the mechanic. Include priceValidUntil if time-limited.
Can AI shopping agents read Shopify automatic discount codes?
No. Shopify automatic discounts and codes apply at checkout on checkout.shopify.com — a URL AI agents cannot crawl. To expose bundle pricing, you must encode it in product-page JSON-LD. Use Liquid metafields to keep the values manageable without hard-coding per product.
What is the difference between a bundle discount and a sale price in schema.org?
A sale price (Offer.price lower than highPrice) applies to every unit regardless of quantity. A bundle discount applies only at a minimum quantity threshold — encoded via eligibleQuantity. Use separate Offer blocks: one at full price with minValue: 1, and one at the bundle price with minValue equal to your bundle threshold.
How should I encode a percentage-off bundle vs. a fixed savings amount?
For percentage-off, set Offer.price to the discounted price and highPrice to the original. Add additionalProperty with propertyID: "discountPercent". For fixed savings ($10 off when you buy 3), set the effective per-unit price and add additionalProperty with propertyID: "bundleSavings" and value "$10.00".
Check Your Bundle Pricing Visibility
CatalogScan scans your product catalog for missing bundle pricing signals, malformed eligibleQuantity blocks, and promotion markup gaps — then ranks them by impact on AI agent citation rates for deal-intent queries.
Scan your store free