Optimization Guide

Shopify Member-Only and Exclusive Product Schema for AI Shopping Agents

AI shopping agents answering "loyalty member exclusive products," "VIP early access drops," and "Gold tier member discount pricing" need structured membership and eligibility signals — not JavaScript loyalty widgets. Shopify's default JSON-LD has no concept of member pricing, tier gating, or exclusive access, making every loyalty program benefit invisible to AI shopping indexes.

TL;DR Use dual Offer blocks: a public Offer at standard price and a member Offer with eligibleCustomerType or additionalProperty: requiredMembershipTier. For member-only products, add additionalProperty: memberOnlyProduct: true. For early access, combine availabilityStarts with the membership tier requirement on the member Offer. Drive from product tags or metafields with a null-guard.

The Loyalty Program Visibility Gap

Loyalty and membership programs are among the most powerful retention and conversion tools in DTC e-commerce. Exclusive products, early access windows, tiered pricing, and members-only drops create the urgency and reward signals that drive program enrollment and retention. Virtually every major DTC brand operating above $1M ARR has some form of loyalty program — LoyaltyLion, Smile.io, Yotpo Loyalty, Okendo Loyalty, or a custom implementation on Shopify.

All of these programs share a critical structural problem: their benefits are rendered in JavaScript. Tier-unlock messaging, member pricing overlays, early access countdowns — every element that communicates membership value is dynamic JavaScript injected after page load. AI agent crawlers (GPTBot, PerplexityBot, ClaudeBot) do not execute JavaScript. When these crawlers read your product pages, they see only the base Shopify product JSON-LD with no evidence that member pricing or exclusive access exists.

The result: when a user asks ChatGPT Shopping "which brands have loyalty programs with exclusive products," or "what are the best member-only deals right now," stores with sophisticated loyalty programs are not surfaced — because the membership signals are not in structured data.

Member-only query types requiring structured data

Query type Example Required signal AI shopping behavior
Exclusive member products "loyalty member exclusive products from outdoor brands" additionalProperty: memberOnlyProduct: true Surfaces products declared as member-only access
Tier-locked pricing "Gold member pricing on sneakers" additionalProperty: requiredMembershipTier: Gold Returns products with tier-specific offers matching the queried tier
VIP early access "VIP member early access drops this week" availabilityStarts on member Offer + requiredMembershipTier: VIP Surfaces upcoming early access windows for specific member tiers
Member discount rate "brands that give 20% off for members" additionalProperty: memberDiscount: 20 (% value) Filters stores by member discount percentage across their catalog
Subscriber-exclusive deals "subscriber-only deals from clean beauty brands" eligibleCustomerType on Offer + member Offer price Identifies subscriber-only or subscription-holder pricing

Shopify default vs. member-aware JSON-LD

Shopify default (no membership signal)
{
  "@type": "Offer",
  "price": "120.00",
  "availability": "InStock"
  // member price: $96 (20% off)
  // invisible to AI agents
  // injected by LoyaltyLion JS
}
With dual-Offer member pricing
"offers": [
  {
    "@type": "Offer",
    "price": "120.00",
    "availability": "InStock"
  },
  {
    "@type": "Offer",
    "price": "96.00",
    "additionalProperty": [{
      "propertyID":
        "requiredMembershipTier",
      "value": "Member"
    }]
  }
]

Member Pricing and Exclusive Access JSON-LD Patterns

Dual-Offer member pricing — public + member price

The most important pattern: declare both a public price Offer and a member price Offer in a offers array. AI agents that handle multi-offer products will correctly surface the member pricing to users who qualify:

{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "Performance Running Jacket — Windblock",
  "offers": [
    {
      "@type": "Offer",
      "name": "Standard price",
      "price": "148.00",
      "priceCurrency": "USD",
      "availability": "https://schema.org/InStock"
    },
    {
      "@type": "Offer",
      "name": "Member price",
      "price": "118.40",
      "priceCurrency": "USD",
      "availability": "https://schema.org/InStock",
      "additionalProperty": [
        {
          "@type": "PropertyValue",
          "propertyID": "requiredMembershipTier",
          "name": "Required membership tier",
          "value": "Member"
        },
        {
          "@type": "PropertyValue",
          "propertyID": "memberDiscount",
          "name": "Member discount",
          "value": "20"
        }
      ]
    }
  ]
}

Tiered member pricing — multiple loyalty tiers

For stores with multiple loyalty tiers (Silver, Gold, Platinum), declare one Offer per tier alongside the public price. Include the memberDiscount additionalProperty for each tier to enable discount-comparison queries:

{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "Cashmere V-Neck Sweater",
  "offers": [
    {
      "@type": "Offer",
      "name": "Public price",
      "price": "185.00",
      "priceCurrency": "USD",
      "availability": "https://schema.org/InStock"
    },
    {
      "@type": "Offer",
      "name": "Silver member price",
      "price": "166.50",
      "priceCurrency": "USD",
      "availability": "https://schema.org/InStock",
      "additionalProperty": {
        "@type": "PropertyValue",
        "propertyID": "requiredMembershipTier",
        "value": "Silver"
      }
    },
    {
      "@type": "Offer",
      "name": "Gold member price",
      "price": "148.00",
      "priceCurrency": "USD",
      "availability": "https://schema.org/InStock",
      "additionalProperty": {
        "@type": "PropertyValue",
        "propertyID": "requiredMembershipTier",
        "value": "Gold"
      }
    },
    {
      "@type": "Offer",
      "name": "Platinum member price",
      "price": "129.50",
      "priceCurrency": "USD",
      "availability": "https://schema.org/InStock",
      "additionalProperty": {
        "@type": "PropertyValue",
        "propertyID": "requiredMembershipTier",
        "value": "Platinum"
      }
    }
  ]
}

Member-only exclusive product (not publicly purchasable)

For products that are exclusively accessible to members — not available to non-members at any price — declare a single Offer with a memberOnlyProduct signal and set the public availability context clearly:

{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "Founder Series Limited Hoodie — Members Only",
  "description": "Exclusive to all-time members of our loyalty program. Not available for public purchase. Each hoodie has a unique member number embroidered inside.",
  "offers": {
    "@type": "Offer",
    "price": "95.00",
    "priceCurrency": "USD",
    "availability": "https://schema.org/InStock",
    "additionalProperty": [
      {
        "@type": "PropertyValue",
        "propertyID": "memberOnlyProduct",
        "name": "Member-only product",
        "value": "true"
      },
      {
        "@type": "PropertyValue",
        "propertyID": "requiredMembershipTier",
        "name": "Required membership tier",
        "value": "All-Time Member"
      },
      {
        "@type": "PropertyValue",
        "propertyID": "membershipProgramName",
        "name": "Program name",
        "value": "Founders Circle"
      }
    ]
  }
}

VIP early access with availabilityStarts

For products launching publicly in the future but available early to VIP members, create two Offers: an early access Offer for members with availabilityStarts set to the early access date, and a public Offer with availabilityStarts set to the public launch date:

{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "Summer Collection Linen Blazer",
  "offers": [
    {
      "@type": "Offer",
      "name": "VIP member early access",
      "price": "220.00",
      "priceCurrency": "USD",
      "availability": "https://schema.org/PreOrder",
      "availabilityStarts": "2026-06-10T09:00:00-07:00",
      "availabilityEnds": "2026-06-13T08:59:59-07:00",
      "additionalProperty": [
        {
          "@type": "PropertyValue",
          "propertyID": "requiredMembershipTier",
          "value": "VIP"
        },
        {
          "@type": "PropertyValue",
          "propertyID": "earlyAccessWindowHours",
          "value": "72"
        }
      ]
    },
    {
      "@type": "Offer",
      "name": "Public sale",
      "price": "220.00",
      "priceCurrency": "USD",
      "availability": "https://schema.org/PreOrder",
      "availabilityStarts": "2026-06-13T09:00:00-07:00"
    }
  ]
}

Shopify Liquid implementation

Store membership tier and discount data in product metafields. Use product tags as a lightweight gate for member-only products:

{% comment %}Member pricing — driven by product.metafields.loyalty.*{% endcomment %}
{% assign has_member_price = product.metafields.loyalty.member_price | default: '' %}
{% assign member_tier = product.metafields.loyalty.required_tier | default: 'Member' %}
{% assign member_discount = product.metafields.loyalty.discount_pct | default: '' %}
{% assign is_member_only = false %}
{% for tag in product.tags %}
  {% if tag == 'members-only' or tag == 'vip-only' %}
    {% assign is_member_only = true %}
  {% endif %}
{% endfor %}

"offers": [
  {
    "@type": "Offer",
    "name": "Standard price",
    "price": {{ variant.price | money_without_currency | json }},
    "priceCurrency": {{ cart.currency.iso_code | json }},
    "availability": {% if variant.available %}"https://schema.org/InStock"{% else %}"https://schema.org/OutOfStock"{% endif %}
  }{% if has_member_price != '' %},
  {
    "@type": "Offer",
    "name": {{ member_tier | append: ' member price' | json }},
    "price": {{ has_member_price | json }},
    "priceCurrency": {{ cart.currency.iso_code | json }},
    "availability": {% if variant.available %}"https://schema.org/InStock"{% else %}"https://schema.org/OutOfStock"{% endif %},
    "additionalProperty": [
      {
        "@type": "PropertyValue",
        "propertyID": "requiredMembershipTier",
        "value": {{ member_tier | json }}
      }
      {% if member_discount != '' %},
      {
        "@type": "PropertyValue",
        "propertyID": "memberDiscount",
        "value": {{ member_discount | json }}
      }
      {% endif %}
      {% if is_member_only %},
      {
        "@type": "PropertyValue",
        "propertyID": "memberOnlyProduct",
        "value": "true"
      }
      {% endif %}
    ]
  }
  {% endif %}
]

Loyalty tier reference — common Shopify program structures

Program structure Typical tier names Primary signal Secondary signal
Point-based (Smile.io, LoyaltyLion) Bronze / Silver / Gold / Platinum requiredMembershipTier memberDiscount per tier
Spend-threshold (VIP tiers) Member / VIP / Elite / Insider requiredMembershipTier memberOnlyProduct: true for exclusives
Subscription-based Subscriber / Premium / Pro requiredMembershipTier: Subscriber availabilityStarts for early access
App-based loyalty (Yotpo Loyalty) Insider / VIP / Icon requiredMembershipTier membershipProgramName
Co-brand / community membership Community / Pro / Founder memberOnlyProduct: true requiredMembershipTier + program name

Common Mistakes

1. Relying on loyalty app JavaScript for member pricing signals

Every major Shopify loyalty app (LoyaltyLion, Smile.io, Yotpo Loyalty, Okendo) injects member pricing, tier messaging, and discount overlays via JavaScript. These are completely invisible to AI agent crawlers. The loyalty app and your JSON-LD serve different audiences: the app serves logged-in humans; the JSON-LD serves AI agents and search indexers. Both must be maintained independently.

2. Exposing private member prices in public structured data

For programs where the member price is confidential (members-only pricing not disclosed publicly), do not include the actual price in the member Offer JSON-LD. Instead, declare only the requiredMembershipTier additionalProperty and memberOnlyProduct: true — this signals membership exclusivity without revealing pricing. Include the discount percentage (memberDiscount) only if your program already publicizes the discount rate (e.g., "Gold members always get 20% off").

3. Using a single Offer and hiding the member price in description text

Writing "Gold members get 20% off" in the product description is not machine-readable for pricing queries. AI agents reading structured data for price filtering or member-discount queries look at the Offer.price and Offer.additionalProperty — not the Product.description text. A dual-Offer structure is required to make member pricing queryable.

4. Setting memberOnlyProduct without a membership program name

Declaring a product as memberOnlyProduct: true without identifying the program (membershipProgramName additionalProperty) leaves AI agents unable to link the exclusivity claim to a specific loyalty program. A user asking "exclusive products from [brand]'s insider program" needs the program name to be explicit in the structured data, not just a bare true flag.

5. Forgetting to update availabilityStarts after the early access window closes

If you use availabilityStarts on an early access Offer and the window passes without removing the future-dated Offer, AI agents will continue to read the product as not-yet-available to the general public even after the public launch. Use a metafield-driven approach where availabilityStarts is stored as a metafield value you can clear after the window passes, rather than hardcoding dates in the Liquid template.

Implementation Checklist

Frequently Asked Questions

How do I mark up member-only pricing in Shopify product structured data?

Use a dual offers array: a public Offer with standard price and a member Offer with member price. On the member Offer, add additionalProperty: requiredMembershipTier with your tier name, and optionally memberDiscount with the discount percentage. Store member prices in product metafields under a loyalty namespace and inject via Liquid.

Should member-only products that aren't publicly visible be indexed?

Products with a public URL that require login to purchase should have full structured data including the membership requirement signal — this lets AI agents accurately surface member-exclusive products in response to loyalty queries. Products with no public URL (completely hidden behind a password) should not be in your sitemap and will not be crawled by AI agents.

What schema.org type should I use for loyalty program membership?

Use additionalProperty with propertyID: requiredMembershipTier on products that require a specific tier. For the loyalty program entity itself, ProgramMembership describes the program — include programName and a URL to the program sign-up page. Reference the program name in a membershipProgramName additionalProperty on member-exclusive products.

How do I mark up early access products for loyalty members?

Create a member Offer with availabilityStarts set to the early access date (ISO 8601 with timezone) and additionalProperty: requiredMembershipTier for the tier that gets early access. Create a separate public Offer with availabilityStarts set to the public launch date. Drive both dates from metafields so they can be updated without template edits.

Does Shopify include loyalty or member pricing in its default product JSON-LD?

No. Shopify outputs a single Offer with base price only. All loyalty app pricing (LoyaltyLion, Smile.io, Yotpo Loyalty) is injected via JavaScript — invisible to AI agent crawlers. You must manually add dual-Offer structures and membership additionalProperty signals in product.liquid.

Related Resources