Structured data for AI
How-to

How do you show your shipping costs and return policy to Google and AI shopping assistants?

Short answer

Publish them in three places that agree with each other. First, a plain-text shipping and returns page with real numbers. Second, ShippingService and MerchantReturnPolicy schema markup on that page, which Google can show next to your products. Third, the shipping and returns fields in any product feed you send to Google or ChatGPT.

Cover: Shipping and returns, readable by AI. Structured data for AI how-to.
On this page

    Key facts

    • Google reads two schema types for store-wide policies: ShippingService (via hasShippingService) and MerchantReturnPolicy (via hasMerchantReturnPolicy), both nested under your Organization or OnlineStore markup.
    • One page is enough: Google recommends putting this markup on a single page that describes your policy, not on every page of your site.
    • Settings beat markup: if you set policies in Merchant Center or Search Console, Google uses those and ignores your on-page markup. Product-level markup overrides organization-level markup.
    • ChatGPT has its own fields: OpenAI's product feed spec includes shipping_price, accepts_returns, return_deadline_in_days and return_policy. An empty shipping price means "unknown", not "free".
    • Nothing is guaranteed: Google says features that use structured data may not show up, even when your markup is valid.

    Why shipping and returns matter for AI answers

    When someone asks an assistant to compare two stores, the price is only part of the answer. Delivery cost, delivery time and the return window are the facts that decide whether the cheaper store is really cheaper. If the assistant can't find them, it may leave them out, or guess.

    Most stores make this hard without meaning to. The real numbers sit in a checkout calculator, a pop-up, an image banner ("Free shipping over €50!") or a legal page written in long paragraphs. A person can work it out. A crawler reading the page text may not.

    The fix is not one trick. It's making the same facts available in the three formats that machines actually use:

    Where Who reads it What it does
    Plain-text policy page Any crawler or AI assistant that reads your site The source of truth. Everything else should match it.
    Schema markup (JSON-LD) on that page Google Search; other crawlers can parse it too Turns the policy into labelled data: countries, costs, days, fees
    Product feed fields Google Merchant Center, ChatGPT product feeds Shipping and return data attached to each product

    Step 1: Write a policy page a machine can quote

    Start with the page, because both the markup and the feed should copy what it says. Make it boringly clear:

    • One page, one URL, for example /shipping-returns, linked from your footer and product pages.
    • Numbers in text, not images: "Standard delivery to Portugal: €3.95, free on orders over €50, 1 to 3 business days."
    • A short table per country or zone if your rates differ.
    • Return terms as plain facts: how many days, counted from when, free or paid return, refund or store credit, and which items can't be returned.
    • A visible "last updated" date, so a reader knows the numbers are current.

    A page like this helps every AI system, including the ones that don't read schema at all. It also gives you a single place to update when your carrier raises prices.

    Step 2: Add shipping and return policy markup

    Google's documentation describes two store-wide types. You place them inside your Organization markup (or OnlineStore, a more specific type), ideally on the policy page itself.

    What the return policy needs

    For MerchantReturnPolicy, Google gives you two ways to meet the requirements:

    Option Required properties When to use it
    A: describe the policy applicableCountry and returnPolicyCategory (plus merchantReturnDays if the window is limited) You want Google to know the actual terms
    B: link to it merchantReturnLink You only want to point to your policy page

    Option A is the useful one. Google also recommends returnFees, returnMethod and refundType, and supports separate fees for "changed my mind" returns and for faulty items.

    What the shipping policy needs

    For ShippingService, the one required property is shippingConditions: one block per combination of destination, order value, weight or number of items, each with a shippingRate and a transitTime. If more than one block applies to a product, Google says it uses the cheapest rate, and if rates tie, the fastest delivery. You can also add a handlingTime with an order cutoff time.

    An example for a store shipping to Portugal and Spain

    Here is a simplified example. It describes a 30-day free return by mail with a full refund, and standard delivery to Portugal and Spain with free shipping over €50. Replace every value with your real terms.

    <script type="application/ld+json">
    {
      "@context": "https://schema.org",
      "@type": "OnlineStore",
      "name": "Example Store",
      "url": "https://www.example.com",
      "hasMerchantReturnPolicy": {
        "@type": "MerchantReturnPolicy",
        "applicableCountry": ["PT", "ES"],
        "returnPolicyCountry": "PT",
        "returnPolicyCategory": "https://schema.org/MerchantReturnFiniteReturnWindow",
        "merchantReturnDays": 30,
        "returnMethod": "https://schema.org/ReturnByMail",
        "returnFees": "https://schema.org/FreeReturn",
        "refundType": "https://schema.org/FullRefund"
      },
      "hasShippingService": {
        "@type": "ShippingService",
        "name": "Standard delivery",
        "handlingTime": {
          "@type": "ServicePeriod",
          "cutoffTime": "14:00:00+00:00",
          "duration": { "@type": "QuantitativeValue", "minValue": 0, "maxValue": 1, "unitCode": "DAY" }
        },
        "shippingConditions": [
          {
            "@type": "ShippingConditions",
            "shippingDestination": [
              { "@type": "DefinedRegion", "addressCountry": "PT" },
              { "@type": "DefinedRegion", "addressCountry": "ES" }
            ],
            "orderValue": { "@type": "MonetaryAmount", "minValue": 0, "maxValue": 49.99, "currency": "EUR" },
            "shippingRate": { "@type": "MonetaryAmount", "value": 3.95, "currency": "EUR" },
            "transitTime": {
              "@type": "ServicePeriod",
              "duration": { "@type": "QuantitativeValue", "minValue": 1, "maxValue": 3, "unitCode": "DAY" }
            }
          },
          {
            "@type": "ShippingConditions",
            "shippingDestination": [
              { "@type": "DefinedRegion", "addressCountry": "PT" },
              { "@type": "DefinedRegion", "addressCountry": "ES" }
            ],
            "orderValue": { "@type": "MonetaryAmount", "minValue": 50, "currency": "EUR" },
            "shippingRate": { "@type": "MonetaryAmount", "value": 0, "currency": "EUR" },
            "transitTime": {
              "@type": "ServicePeriod",
              "duration": { "@type": "QuantitativeValue", "minValue": 1, "maxValue": 3, "unitCode": "DAY" }
            }
          }
        ]
      }
    }
    </script>
    

    A few details that are easy to get wrong:

    • Country codes are two-letter ISO codes (PT, ES), and Google allows up to 50 countries in a return policy.
    • Free shipping is a rate with "value": 0, not a missing rate.
    • Don't mix fee types: with FreeReturn, leave out returnShippingFeesAmount. Only add an amount when returnFees is ReturnShippingFees.
    • Products with different terms, like final-sale items or bulky goods, get their own hasMerchantReturnPolicy or shippingDetails inside that product's Offer. Google supports fewer properties at product level.

    Step 3: Check which source Google will actually use

    This is the step most guides skip. Google can get your policies from several places, and it doesn't merge them. Its documentation lists this order, strongest first:

    Priority Source
    1 Content API for Shopping (shipping and return settings)
    2 Settings in Merchant Center or Search Console
    3 Product-level merchant listing markup
    4 Organization-level markup

    So if someone on your team once filled in return settings in Search Console, Google will use those and ignore the markup you just added. Before you add markup, look at what's already set in Merchant Center and Search Console. If the settings are there and correct, you may not need organization-level markup at all. If they're outdated, fix them first, because they win.

    For many small stores, the settings are actually the simpler route. Google suggests them if your policies are complicated or change often. Markup is useful when you don't use Merchant Center, or when you want the policy described on your own site in a form any crawler can parse.

    Step 4: Fill in the shipping and return fields in your feeds

    If you send product feeds, the same facts need to be there too, per product.

    OpenAI's product feed spec for ChatGPT has optional fields for this:

    Field What it means
    shipping_price Shipping charge in the item's currency. Zero means free. Empty means unknown, not free.
    accepts_returns true or false. A policy link alone doesn't set it.
    return_deadline_in_days Return window in whole days. Only with accepts_returns=true.
    return_policy URL of the public policy for this item

    Two notes from the spec are worth knowing. OpenAI says shipping support depends on your feed setup, so confirm it during onboarding. And the standard OpenAI-format upload currently targets the US, so stores selling only in Europe should check what applies to them before building a feed. If you want the bigger picture on feeds, see how shoppers use ChatGPT to find products.

    Step 5: Test it and keep it in sync

    1. Validate the markup. Paste your policy page URL into Google's Rich Results Test or the Schema Markup Validator and fix any errors.
    2. Check the page is reachable. Google reminds you the page must not be blocked by robots.txt, noindex or a login. The same goes for AI crawlers. Our guide on checking which AI crawlers can access your site shows how.
    3. Compare the four versions. Policy page, markup, Merchant Center or Search Console settings, and feeds. They should all say the same thing.
    4. Update them together. When rates or return terms change, change all four the same day. Wrong data is worse than missing data, because an assistant may repeat it to a customer.

    A quick checklist

    Check Pass if
    Policy page exists One URL, numbers in text, linked from product pages
    Return markup applicableCountry, returnPolicyCategory and merchantReturnDays (if limited) are set
    Shipping markup Every destination and price band has a shippingConditions block with rate and transit time
    Precedence checked Merchant Center and Search Console settings are correct or empty
    Feeds match shipping_price and return fields are filled in, not left empty
    Validated Rich Results Test or Schema Markup Validator show no errors
    In sync Last updated date on the page matches the last change in markup and feeds

    Check your own site

    The free Web2Agents AI check tells you whether your homepage has structured data that AI systems can read, with a readiness score out of 30. The €19 AI-Ready Kit gives you paste-ready Organization schema, which you can extend with the shipping and return blocks above. More guides like this one are in our structured data for AI section.

    {"@context":"https://schema.org","@type":"FAQPage","mainEntity":[{"@type":"Question","name":"Do I need shipping and return markup on every product page?","acceptedAnswer":{"@type":"Answer","text":"No. Google recommends putting your standard shipping and return policy markup on a single page that describes the policy, nested under your Organization markup. Add product-level markup only for products with different terms."}},{"@type":"Question","name":"What happens if my Merchant Center settings and my markup disagree?","acceptedAnswer":{"@type":"Answer","text":"Google uses the stronger source. Its order is the Content API for Shopping, then Merchant Center or Search Console settings, then product-level markup, then organization-level markup. Settings in Search Console override your on-page markup."}},{"@type":"Question","name":"Will adding this markup make Google show my return policy?","acceptedAnswer":{"@type":"Answer","text":"Not necessarily. Google says it can use the markup to show return and shipping information alongside your products and in knowledge panels, but it doesn't guarantee that any structured data feature will appear."}},{"@type":"Question","name":"Can I just link to my return policy page instead?","acceptedAnswer":{"@type":"Answer","text":"Yes. Google accepts merchantReturnLink with the URL of your policy page as an alternative to describing the terms. Describing the countries, return window and fees gives Google more to work with."}},{"@type":"Question","name":"Does ChatGPT read my shipping and return policy?","acceptedAnswer":{"@type":"Answer","text":"If you send a product feed, OpenAI's spec has fields for shipping price, whether returns are accepted, the return window and a policy URL. Assistants that browse your site read the page itself, so keep your policy page clear too."}},{"@type":"Question","name":"How do I mark free shipping?","acceptedAnswer":{"@type":"Answer","text":"Use a shipping rate with a value of 0 in your markup, and a shipping price of zero in an OpenAI feed. In the OpenAI feed, an empty shipping price means unknown, not free."}}]}

    FAQ

    Do I need shipping and return markup on every product page?

    No. Google recommends putting your standard shipping and return policy markup on a single page that describes the policy, nested under your Organization markup. Add product-level markup only for products with different terms.

    What happens if my Merchant Center settings and my markup disagree?

    Google uses the stronger source. Its order is the Content API for Shopping, then Merchant Center or Search Console settings, then product-level markup, then organization-level markup. Settings in Search Console override your on-page markup.

    Will adding this markup make Google show my return policy?

    Not necessarily. Google says it can use the markup to show return and shipping information alongside your products and in knowledge panels, but it doesn't guarantee that any structured data feature will appear.

    Can I just link to my return policy page instead?

    Yes. Google accepts merchantReturnLink with the URL of your policy page as an alternative to describing the terms. Describing the countries, return window and fees gives Google more to work with.

    Does ChatGPT read my shipping and return policy?

    If you send a product feed, OpenAI's spec has fields for shipping price, whether returns are accepted, the return window and a policy URL. Assistants that browse your site read the page itself, so keep your policy page clear too.

    How do I mark free shipping?

    Use a shipping rate with a value of 0 in your markup, and a shipping price of zero in an OpenAI feed. In the OpenAI feed, an empty shipping price means unknown, not free.

    Sources

    Newsletter

    New guides on AI visibility, in your inbox.

    Practical, sourced articles on AI crawlers, llms.txt, structured data and AI search. A new one every day.

    Unsubscribe anytime. See our Privacy Policy.