Optimization Guide

Shopify Event Ticket and Workshop Product Schema for AI Shopping Agents

Shopify is widely used to sell workshops, cooking classes, pottery sessions, and experience gift vouchers — but Shopify's default Product JSON-LD is the wrong schema type. AI shopping agents use Event schema to answer date, location, and activity queries. Without it, your classes are invisible to every AI event discovery tool.

TL;DR Replace "@type": "Product" with "@type": "Event" in your workshop product JSON-LD. Add startDate, endDate, location (Place with PostalAddress for in-person; VirtualLocation for online), organizer, and eventAttendanceMode. Nest ticket pricing inside an Offer with price and availability. Store event metafields (event.start_date, event.venue_name, event.capacity) and inject via Liquid conditionally for event-type products.

Why Product Schema Fails for Events

Shopify generates Product JSON-LD for every product by default. For physical goods, this is correct. For workshops and experiences, it is the wrong schema type — and the mismatch has direct ranking consequences.

AI shopping agents have separate event discovery indexes powered by Event schema. When a user asks ChatGPT "cooking classes in Austin this weekend" or Perplexity "pottery workshop gift ideas", these agents query the event index by startDate range, addressLocality, and @type: Event. A product page with @type: Product and date information buried in the description will never appear — it is not indexed as an event.

Event query types that require Event schema

Query type Example Required Event property AI behavior
Activity near me "pottery workshop near Chicago" location.geo (GeoCoordinates) Proximity-based event discovery using lat/lng
This weekend "cooking class this Saturday" startDate (ISO 8601 datetime) Filters events by date range from today forward
Online class "virtual wine tasting class" eventAttendanceMode: OnlineEventAttendanceMode Filters events by attendance format
Price-filtered activity "art classes under $50" offers.price inside Event Filters events by ticket price
Capacity / availability "pottery class with spots available" offers.availability: InStock or LimitedAvailability Surfaces events with open registration

Product schema vs. Event schema for workshops

Product schema (wrong — no event discovery)
{
  "@type": "Product",
  "name": "Pottery Workshop",
  "description":
    "Join us Sat June 14
    at our Brooklyn studio...",
  // No startDate
  // No location type
  // Not indexed as Event
}
Event schema (correct — AI agent discoverable)
{
  "@type": "Event",
  "name": "Pottery Workshop",
  "startDate":
    "2026-06-14T10:00:00-05:00",
  "endDate":
    "2026-06-14T13:00:00-05:00",
  "location": {
    "@type": "Place",
    "name": "Brooklyn Clay"
  },
  "eventStatus":
    "EventScheduled"
}

Event JSON-LD Patterns

Minimum viable in-person workshop

The smallest Event block that achieves AI event-index inclusion. All five properties are required for date + location discovery:

{
  "@context": "https://schema.org",
  "@type": "Event",
  "name": "Beginner Pottery Wheel Workshop",
  "startDate": "2026-07-12T10:00:00-05:00",
  "endDate": "2026-07-12T13:00:00-05:00",
  "eventStatus": "https://schema.org/EventScheduled",
  "eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode",
  "location": {
    "@type": "Place",
    "name": "Brooklyn Clay Studio",
    "address": {
      "@type": "PostalAddress",
      "streetAddress": "190 Bowery Street",
      "addressLocality": "New York",
      "addressRegion": "NY",
      "postalCode": "10012",
      "addressCountry": "US"
    }
  },
  "organizer": {
    "@type": "Organization",
    "name": "Brooklyn Clay",
    "url": "https://yourstore.com"
  },
  "offers": {
    "@type": "Offer",
    "price": "85.00",
    "priceCurrency": "USD",
    "availability": "https://schema.org/InStock",
    "url": "https://yourstore.com/products/pottery-workshop"
  }
}

Full event with geo coordinates, capacity, and performer

Adding geo coordinates enables proximity queries; maximumAttendeeCapacity and remainingAttendeeCapacity enable availability filtering:

{
  "@context": "https://schema.org",
  "@type": "Event",
  "name": "Farm-to-Table Cooking Class with Chef Maria Santos",
  "description": "A 3-hour hands-on cooking class featuring seasonal ingredients from local farms. Learn knife skills, sauce fundamentals, and plating technique. Small group of 8 maximum.",
  "startDate": "2026-07-19T18:00:00-05:00",
  "endDate": "2026-07-19T21:00:00-05:00",
  "eventStatus": "https://schema.org/EventScheduled",
  "eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode",
  "location": {
    "@type": "Place",
    "name": "The Larder Kitchen Studio",
    "address": {
      "@type": "PostalAddress",
      "streetAddress": "415 West 13th Street",
      "addressLocality": "New York",
      "addressRegion": "NY",
      "postalCode": "10014",
      "addressCountry": "US"
    },
    "geo": {
      "@type": "GeoCoordinates",
      "latitude": 40.7413,
      "longitude": -74.0067
    }
  },
  "organizer": {
    "@type": "Organization",
    "name": "The Larder Kitchen Studio",
    "url": "https://yourstore.com"
  },
  "performer": {
    "@type": "Person",
    "name": "Chef Maria Santos"
  },
  "maximumAttendeeCapacity": 8,
  "remainingAttendeeCapacity": 3,
  "image": "https://yourstore.com/products/cooking-class-hero.jpg",
  "offers": {
    "@type": "Offer",
    "price": "195.00",
    "priceCurrency": "USD",
    "availability": "https://schema.org/LimitedAvailability",
    "validFrom": "2026-06-01T00:00:00Z",
    "url": "https://yourstore.com/products/farm-to-table-cooking-class"
  }
}

Online / virtual workshop

For online classes, replace Place with VirtualLocation and set OnlineEventAttendanceMode:

{
  "@context": "https://schema.org",
  "@type": "Event",
  "name": "Watercolor Florals — Live Online Workshop",
  "startDate": "2026-07-26T14:00:00Z",
  "endDate": "2026-07-26T16:00:00Z",
  "eventStatus": "https://schema.org/EventScheduled",
  "eventAttendanceMode": "https://schema.org/OnlineEventAttendanceMode",
  "location": {
    "@type": "VirtualLocation",
    "url": "https://zoom.us/j/your-meeting-link"
  },
  "organizer": {
    "@type": "Organization",
    "name": "Palette Studio",
    "url": "https://yourstore.com"
  },
  "offers": {
    "@type": "Offer",
    "price": "55.00",
    "priceCurrency": "USD",
    "availability": "https://schema.org/InStock",
    "url": "https://yourstore.com/products/watercolor-workshop"
  }
}

Shopify Liquid Implementation

Create event metafields in Shopify Admin → Settings → Custom data → Products. Use a tag or product type to identify event products, then conditionally output Event JSON-LD instead of the default Product JSON-LD:

Metafield key Type Example value Maps to
event.start_date Date and time 2026-07-12T10:00:00-05:00 Event.startDate
event.end_date Date and time 2026-07-12T13:00:00-05:00 Event.endDate
event.venue_name Single-line text Brooklyn Clay Studio location.Place.name
event.venue_address Single-line text 190 Bowery St, New York, NY 10012 location.Place.address
event.latitude Decimal 40.7209 location.geo.latitude
event.longitude Decimal -73.9929 location.geo.longitude
event.capacity Integer 8 maximumAttendeeCapacity
event.is_online Boolean false Toggles VirtualLocation vs. Place
{% if product.metafields.event.start_date %}
  {% assign is_online = product.metafields.event.is_online %}
  {% assign spots = product.metafields.event.capacity %}
  
{% else %}
  {% comment %} Regular product JSON-LD for non-event products {% endcomment %}
{% endif %}

EventStatus Reference

Status URI When to use AI agent behavior
EventScheduled https://schema.org/EventScheduled Event is on as planned Surfaces in upcoming event queries
EventPostponed https://schema.org/EventPostponed Event delayed, new date TBD Deprioritized in date-specific queries
EventRescheduled https://schema.org/EventRescheduled Event moved — add previousStartDate Shows at new date; suppresses old date
EventCancelled https://schema.org/EventCancelled Event will not happen Excluded from event discovery results

Common Mistakes

Mistake Impact Fix
Using Product schema for workshops Event is not indexed in AI event discovery; never appears in date/location queries Use Event schema type for any product with a specific date, start time, and venue
Missing startDate ISO 8601 format with timezone AI agents cannot reliably filter by date without timezone; "this weekend" queries fail Always include timezone offset in startDate: e.g., 2026-07-12T10:00:00-05:00
No geo coordinates for in-person event Event excluded from proximity queries ("near me", "in [city]") Add GeoCoordinates with latitude and longitude to the Place location block
Past events remaining as EventScheduled AI agents may surface past events as upcoming; damages trust signals Update startDate to future dates or set eventStatus to EventCancelled for passed events
Ticket price omitted from Event Offer AI agents cannot surface event in price-filtered queries like "art classes under $75" Always nest an Offer with price, priceCurrency, and availability inside the Event

Implementation Checklist

Frequently Asked Questions

Should I use Product or Event schema for workshop tickets on Shopify?

Use Event schema, not Product. AI shopping agents and search engines have separate event discovery indexes powered by Event schema. Event includes startDate, endDate, location, and eventAttendanceMode properties that enable date-range and proximity filtering. Product schema lacks temporal and location properties — workshop products using only Product schema will never appear in date or location-based event queries.

How do I declare the event location for an in-person workshop?

Use a Place type as the location property on the Event. Include name (venue name), address as a PostalAddress (with streetAddress, addressLocality, addressRegion, postalCode, addressCountry), and geo as GeoCoordinates (latitude and longitude) for proximity-based AI queries. For online events, use VirtualLocation with a url instead.

How do I handle recurring weekly classes in Shopify?

For recurring events, declare each upcoming date as a separate Event with its own JSON-LD block. In Shopify, recurring classes are often set up as products with date-selection variants — use Liquid to iterate over upcoming date metafields and generate an Event JSON-LD block per future date. Only include dates that haven't passed. Alternatively, use an EventSeries as the parent type and link individual Event instances as subEvent entries.

What eventAttendanceMode values should I use?

Schema.org defines three values: https://schema.org/OfflineEventAttendanceMode (in-person only), https://schema.org/OnlineEventAttendanceMode (virtual only), and https://schema.org/MixedEventAttendanceMode (hybrid). Always use the full URI format, not just the short name. AI agents use this property to filter events when users specify "online" or "in-person" in their queries.

How do I handle cancelled or postponed event structured data?

Use the eventStatus property: EventScheduled (on as planned), EventPostponed (delayed, date TBD), EventRescheduled (moved — add previousStartDate with original date), or EventCancelled. Update promptly — AI agents that surface "events this weekend" queries exclude EventCancelled events and deprioritize EventPostponed ones.

Related Resources