HomeBlog › Availability states for AI agents

Shopify product availability states for AI shopping agents: the complete guide to InStock, PreOrder, BackOrder, LimitedAvailability, and Discontinued

2026-06-06  ·  ~15 min read  ·  availability schema InStock PreOrder BackOrder LimitedAvailability AI shopping

Availability state is the first filter AI shopping agents apply. Before they recommend a product, they verify it can actually be purchased — and 69% of Shopify stores output InStock for products that are out of stock, on backorder, or not yet released.

69%
of Shopify stores output InStock for OOS or backordered products
83%
of pre-order products have no releaseDate in schema — agents can't tell customers when it ships
<2%
of stores with low-inventory SKUs (<5 units) use LimitedAvailability schema

In this guide

  1. Why availability is the first filter, not an afterthought
  2. The 7 schema.org availability values and when to use each
  3. Why Shopify's default JSON-LD outputs the wrong state
  4. The master Liquid snippet for correct availability mapping
  5. Per-state JSON-LD patterns with full examples
  6. Multi-location inventory: when availability varies by store
  7. Availability state and offerCount: why it affects recommendation slots
  8. 5 common availability schema mistakes
  9. FAQ

Why availability is the first filter, not an afterthought

AI shopping agents are recommendation engines that stake their credibility on every citation. Recommending a product that turns out to be unavailable damages the agent's trust with users — and agents don't repeat that mistake. ChatGPT Shopping, Perplexity Commerce, and Google AI Mode all apply availability verification before generating recommendations, which means availability state is an entry gate, not a ranking signal.

The filtering sequence typically works like this:

  1. Crawl: the agent's crawler reads your Product JSON-LD and stores the availability value from each Offer
  2. Filter: when a user query triggers a product lookup, the agent filters to purchasable states: InStock, BackOrder, LimitedAvailability, PreOrder (if the query allows for future delivery)
  3. Rank: within purchasable products, agents rank by relevance, price, trust signals, and review quality
  4. Cite: only products that passed the availability filter appear in recommendations

OutOfStock and Discontinued products are filtered out at step 2. If your in-stock products output InStock but your backordered or pre-order products also output InStock, you're not being excluded — but you're corrupting the signal. When an agent crawls your store and later discovers the "InStock" product wasn't available, that mismatch erodes confidence in your catalog signal quality overall.

The credibility cost: availability state accuracy is a trust signal for your catalog as a whole. Stores that consistently output accurate availability are weighted more reliably in recommendation models. Stores with frequent InStock / actually-unavailable mismatches get deprioritized across all their products, not just the ones with wrong schema.

The 7 schema.org availability values and when to use each

Schema.org value Shopify inventory state Purchasable by AI agent? Use when
InStock policy: deny or continue, qty > 0 Yes Product is available and ready to ship immediately
LimitedAvailability policy: deny or continue, qty > 0, qty < threshold Yes In stock but low quantity — creates urgency signal for AI agents
PreOrder product tagged pre-order, released in future Yes (with future delivery) Product exists, can be ordered now, ships when released
BackOrder policy: continue, qty ≤ 0 Yes (with delay) Temporarily OOS, order button still active, ships when restocked
OutOfStock policy: deny, qty ≤ 0 No OOS and cannot currently be ordered; order button disabled
InStoreOnly POS-only products not sold online No (online) Available for in-store purchase only — BOPIS / POS products
Discontinued archived or permanently OOS No Product is permanently unavailable and will not return

The most consequential distinction is between BackOrder and OutOfStock. BackOrder means "you can buy this now, it will ship when stock returns." OutOfStock means "you cannot buy this right now." AI agents include BackOrder in purchasable recommendations; OutOfStock is excluded. This is why backordered products on Shopify stores that use "continue selling when out of stock" should output BackOrder, not OutOfStock — and definitely not InStock.

Why Shopify's default JSON-LD outputs the wrong state

Shopify's default Product JSON-LD (generated by most themes using Dawn's approach) maps availability using a single condition:

{% if product.available %}
  "availability": "https://schema.org/InStock"
{% else %}
  "availability": "https://schema.org/OutOfStock"
{% endif %}

product.available is a Shopify Liquid boolean that returns true if any variant can be purchased — which covers three distinct scenarios that require different schema.org values:

Scenario product.available Shopify default output Correct schema.org value
In stock, qty > 5 true InStock InStock
In stock, qty 1–4 (low) true InStock LimitedAvailability
Continue selling, qty = 0 true InStock BackOrder
Continue selling, qty < 0 true InStock BackOrder
Pre-order product, tag: pre-order true (if continue) InStock PreOrder
OOS, deny selling, qty = 0 false OutOfStock OutOfStock

The root cause is that product.available conflates three distinct purchase states (ready-to-ship, purchasable-with-delay, pre-order) into a single boolean. Shopify's Liquid API has the granular properties needed to distinguish them — the default theme just doesn't use them.

Warning: Some third-party Shopify themes output a bare string like "availability": "InStock" instead of the full URI "availability": "https://schema.org/InStock". AI agents and validators may accept the short form, but Google's Rich Results Test requires the full URI. If you're using a third-party theme, curl your product page and verify: curl -s https://yourstore.com/products/your-product | grep '"availability"'

The master Liquid snippet for correct availability mapping

This snippet reads Shopify's inventory signals at the variant level (not just product.available) and outputs the correct schema.org availability value. Replace the availability line in your sections/main-product.liquid JSON-LD block:

{% comment %}--- Availability mapping ---{% endcomment %}
{% assign av_variant = product.selected_or_first_available_variant %}
{% assign av_url = 'https://schema.org/OutOfStock' %}

{% if product.tags contains 'pre-order' or product.tags contains 'preorder' %}
  {% assign av_url = 'https://schema.org/PreOrder' %}
{% elsif product.tags contains 'discontinued' or product.tags contains 'archived' %}
  {% assign av_url = 'https://schema.org/Discontinued' %}
{% elsif av_variant != blank %}
  {% if av_variant.inventory_management == blank %}
    {% comment %}No inventory tracking — assume InStock{% endcomment %}
    {% assign av_url = 'https://schema.org/InStock' %}
  {% elsif av_variant.inventory_quantity > 0 %}
    {% if av_variant.inventory_quantity < 5 %}
      {% assign av_url = 'https://schema.org/LimitedAvailability' %}
    {% else %}
      {% assign av_url = 'https://schema.org/InStock' %}
    {% endif %}
  {% elsif av_variant.inventory_policy == 'continue' %}
    {% comment %}Continue selling when OOS = BackOrder{% endcomment %}
    {% assign av_url = 'https://schema.org/BackOrder' %}
  {% else %}
    {% assign av_url = 'https://schema.org/OutOfStock' %}
  {% endif %}
{% endif %}

{% comment %}Use {{ av_url }} in your Offer JSON-LD:{% endcomment %}
{% comment %}"availability": "{{ av_url }}"{% endcomment %}

Key decisions encoded in this snippet:

Per-state JSON-LD patterns with full examples

InStock

Standard in-stock product. No additional availability signals needed — the state alone tells AI agents this product is ready to ship.

{
  "@type": "Offer",
  "url": "https://yourstore.com/products/your-product",
  "priceCurrency": "USD",
  "price": "49.00",
  "availability": "https://schema.org/InStock",
  "itemCondition": "https://schema.org/NewCondition",
  "seller": { "@type": "Organization", "name": "Your Store" }
}
LimitedAvailability

Low-inventory scarcity signal. Combine with inventoryLevel to give AI agents a quantity signal. ChatGPT Shopping and Perplexity may surface a "limited stock" label in their output for products using this state — a direct conversion signal to end users.

{
  "@type": "Offer",
  "url": "https://yourstore.com/products/your-product",
  "priceCurrency": "USD",
  "price": "49.00",
  "availability": "https://schema.org/LimitedAvailability",
  "inventoryLevel": {
    "@type": "QuantitativeValue",
    "value": {{ av_variant.inventory_quantity }},
    "unitCode": "EA"
  },
  "itemCondition": "https://schema.org/NewCondition"
}
PreOrder

Pre-release product available for advance purchase. The critical addition is availabilityStarts (the ship date) — 83% of pre-order products omit this, which means AI agents can't tell users when the product ships. Without a release date, agents are reluctant to recommend pre-orders because they can't answer the follow-up question "when does it arrive?"

{
  "@type": "Offer",
  "url": "https://yourstore.com/products/your-product",
  "priceCurrency": "USD",
  "price": "89.00",
  "availability": "https://schema.org/PreOrder",
  "availabilityStarts": "{{ product.metafields.preorder.ship_date | date: '%Y-%m-%d' }}",
  "additionalProperty": [
    {
      "@type": "PropertyValue",
      "name": "preorderDeposit",
      "value": "{{ product.metafields.preorder.deposit_amount | money_without_currency }}"
    },
    {
      "@type": "PropertyValue",
      "name": "estimatedDelivery",
      "value": "{{ product.metafields.preorder.ship_date | date: '%B %Y' }}"
    }
  ],
  "itemCondition": "https://schema.org/NewCondition"
}

Required metafields: preorder.ship_date (date), preorder.deposit_amount (number — optional, for deposit-based pre-orders).

BackOrder

Temporarily OOS but still purchasable. BackOrder is the correct value for Shopify's "continue selling when out of stock" inventory policy — the product can be purchased and ships when stock is replenished. Add availabilityStarts if you know the restock date; this significantly increases recommendation rate because agents can include a "ships by [date]" qualifier.

{
  "@type": "Offer",
  "url": "https://yourstore.com/products/your-product",
  "priceCurrency": "USD",
  "price": "49.00",
  "availability": "https://schema.org/BackOrder",
  {% if product.metafields.inventory.restock_date != blank %}
  "availabilityStarts": "{{ product.metafields.inventory.restock_date | date: '%Y-%m-%d' }}",
  {% endif %}
  "additionalProperty": {
    "@type": "PropertyValue",
    "name": "backorderNote",
    "value": "Ships when restocked — order secured at current price"
  },
  "itemCondition": "https://schema.org/NewCondition"
}
Discontinued

Permanently unavailable. Products marked Discontinued should also have noindex added to the page meta — keeping them indexable with Discontinued availability signals to AI agents that your store stocks products that can't be bought, which dilutes catalog quality signals. For SEO, use a 301 redirect to a related product or the relevant collection.

<!-- In <head> of the product page -->
<meta name="robots" content="noindex,follow">

{
  "@type": "Offer",
  "url": "https://yourstore.com/products/discontinued-product",
  "availability": "https://schema.org/Discontinued",
  "additionalProperty": {
    "@type": "PropertyValue",
    "name": "discontinuedReason",
    "value": "Product line ended — see current alternatives"
  }
}

Important: don't use Discontinued for seasonal products that will return next season — use OutOfStock with a future availabilityStarts date instead. Discontinued signals permanent end-of-life.

Multi-location inventory: when availability varies by store

Shopify's multi-location inventory is one of the more complex availability scenarios for structured data. When a product is InStock at your Los Angeles warehouse but OutOfStock at your New York warehouse, what does the schema.org availability value say?

The standard approach is to use the aggregate availability: if any location can fulfill the order, the Offer availability is InStock or LimitedAvailability. The location-level detail is expressed through shippingDetails and, for BOPIS (Buy Online Pick Up In Store) scenarios, through availableAtOrFrom pointing to the fulfilling location.

{
  "@type": "Offer",
  "availability": "https://schema.org/InStock",
  "availableAtOrFrom": {
    "@type": "Place",
    "name": "CatalogScan Store — Los Angeles",
    "address": {
      "@type": "PostalAddress",
      "addressLocality": "Los Angeles",
      "addressRegion": "CA",
      "addressCountry": "US"
    }
  },
  "shippingDetails": {
    "@type": "OfferShippingDetails",
    "shippingDestination": {
      "@type": "DefinedRegion",
      "addressCountry": "US"
    },
    "deliveryTime": {
      "@type": "ShippingDeliveryTime",
      "handlingTime": { "@type": "QuantitativeValue", "minValue": 1, "maxValue": 2, "unitCode": "DAY" },
      "transitTime": { "@type": "QuantitativeValue", "minValue": 2, "maxValue": 5, "unitCode": "DAY" }
    }
  }
}

For stores with Shopify POS + online inventory, where some products are in-store only, use InStoreOnly combined with availableAtOrFrom pointing to your physical location. AI shopping agents treat InStoreOnly as a purchasable state for users willing to pick up — Perplexity Commerce and Google AI Mode both surface InStoreOnly products in local product queries.

Availability state and offerCount: why it affects recommendation slots

AI shopping agents don't just read the primary Offer's availability — they assess the offer array's overall quality. A product with a single Offer that's InStock is simpler to recommend than a product with a ProductGroup of 12 variants where 10 are OutOfStock and 2 are InStock. When the ratio of unavailable-to-available offers is high, agents may deprioritize the product in favor of cleaner catalog entries.

The practical implication: for products with high variant counts and mixed availability, include only currently purchasable variants in your primary Offer array. You can structure this in Liquid:

"offers": [
  {% for variant in product.variants %}
    {% unless forloop.first %},{% endunless %}
    {% assign v_av = '' %}
    {% if variant.available %}
      {% if variant.inventory_quantity < 5 and variant.inventory_management != blank %}
        {% assign v_av = 'https://schema.org/LimitedAvailability' %}
      {% else %}
        {% assign v_av = 'https://schema.org/InStock' %}
      {% endif %}
    {% elsif variant.inventory_policy == 'continue' %}
      {% assign v_av = 'https://schema.org/BackOrder' %}
    {% else %}
      {% assign v_av = 'https://schema.org/OutOfStock' %}
    {% endif %}
    {
      "@type": "Offer",
      "sku": "{{ variant.sku }}",
      "name": "{{ variant.title | escape }}",
      "price": "{{ variant.price | money_without_currency }}",
      "priceCurrency": "{{ shop.currency }}",
      "availability": "{{ v_av }}",
      "url": "{{ shop.url }}/products/{{ product.handle }}?variant={{ variant.id }}"
    }
  {% endfor %}
]

This outputs per-variant availability across the entire variant array — giving AI agents a complete picture of which sizes, colors, or configurations are actually available. See the ProductGroup JSON-LD guide for how to wire this into the ProductGroup.hasVariant pattern for maximum variant visibility.

5 common availability schema mistakes

01
Outputting InStock for "continue selling when OOS" products
The most common mistake. Shopify's product.available returns true for products with inventory_policy: continue regardless of quantity. The default theme outputs InStock. The correct value is BackOrder (purchasable, ships when restocked). Fix: add an inventory_policy check to your Liquid snippet — see the master snippet above.
02
Pre-order without availabilityStarts
Using PreOrder without an availabilityStarts date is the schema equivalent of a pre-order page that says "coming soon" with no estimated date. AI agents won't refuse to recommend it, but they'll deprioritize it against pre-orders with dates — because agents that recommend "coming soon, no ETA" get user complaints. Always pair PreOrder with a ship date, even if it's approximate (month and year is enough).
03
Using OutOfStock instead of BackOrder for restockable items
OutOfStock tells AI agents "you cannot buy this product." BackOrder tells them "you can buy this, it ships when restocked." For temporarily OOS products that your store will restock (using Shopify's "continue selling" policy), BackOrder keeps them in AI recommendation consideration. OutOfStock removes them from recommendations entirely until the next crawl. The distinction costs you recommendation slots for every day an item is incorrectly marked OutOfStock.
04
LimitedAvailability on products that are always low-inventory
LimitedAvailability is a scarcity signal — it means "get it before it's gone." Using it on products that perpetually have 1–3 units (because you're a made-to-order or dropship store) trains AI agents to ignore your scarcity signals, and risks triggering Google's "fake scarcity" quality review. Reserve LimitedAvailability for genuinely scarce inventory. For made-to-order products, use PreOrder or custom MTO schema patterns instead.
05
Leaving discontinued products indexed and crawlable
Discontinued products with availability: Discontinued but no noindex tag are still crawled and counted against your catalog quality signals. A store with 300 indexed products where 60 are Discontinued looks like a store where 20% of the catalog is permanently unavailable. Add <meta name="robots" content="noindex"> to discontinued product pages and 301-redirect them to their best available alternatives. This improves your crawlable catalog quality ratio across all AI agent recommendation models.

FAQ

Does availability schema affect my CatalogScan score?

Yes — CatalogScan's Offer signal cluster includes availability state accuracy as a component. Specifically, the system flags stores where product.available is false but the JSON-LD availability value is InStock, which is the most common mismatch we find. Correcting this directly improves your Offer signal score and prevents AI agent exclusion based on availability verification. Run a free scan to see whether your store has availability mismatches in the signal breakdown.

What is the difference between BackOrder and OutOfStock in schema.org?

OutOfStock means the product cannot be ordered at all right now. BackOrder means the product is temporarily unavailable but can still be ordered — it will ship when stock is replenished. In Shopify terms: OutOfStock maps to inventory_policy: deny + quantity: 0 (order button disabled), while BackOrder maps to inventory_policy: continue + quantity: 0 (order button still active). AI shopping agents include BackOrder in purchasable recommendations; OutOfStock is excluded entirely.

Should I use LimitedAvailability for flash sales and limited editions?

LimitedAvailability is correct for products with genuine low inventory — typically fewer than 5–10 units on fast-moving SKUs. For flash sales, combine LimitedAvailability with priceValidUntil on the Offer to signal the time-limited price. For true limited editions (products that will be discontinued once sold through), use LimitedAvailability while units remain and switch to Discontinued when they’re gone. Don’t use LimitedAvailability on products that are always in stock — it’s a trust signal, and overuse dilutes it.

How does Shopify's "continue selling when out of stock" policy map to schema.org?

When a Shopify product’s inventory policy is set to “continue,” product.available returns true even when inventory_quantity is 0 or negative. Shopify’s default JSON-LD outputs InStock whenever product.available is true — so these products incorrectly show InStock. The correct mapping is: continue selling + quantity ≤ 0 = BackOrder. You need a custom Liquid snippet that checks inventory_policy and inventory_quantity separately, not just product.available. The master snippet in this guide handles this case.

Do AI shopping agents actually verify availability against live inventory, or just read the schema?

AI shopping agents like ChatGPT Shopping and Perplexity read availability from your JSON-LD and product feed at crawl time — they do not make live inventory API calls on every recommendation. This means stale availability schema causes real problems: a product crawled as InStock may actually be OOS when a user tries to purchase. Agents that receive complaint signals about unavailable products they recommended will deprioritize your store. Keep your availability schema accurate and, where possible, use Google Merchant Center feed refreshes (which AI agents inherit) to propagate inventory changes between crawls. See the AI agent attribution guide for how to set up tracking that shows you when availability mismatches are affecting conversion.

Is your store outputting the right availability states?

CatalogScan flags InStock mismatches, missing PreOrder dates, and BackOrder vs. OutOfStock errors as part of the Offer signal audit. 90 seconds, no login.

Run a free scan See all 15 signals