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.
"@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
{
"@type": "Product",
"name": "Pottery Workshop",
"description":
"Join us Sat June 14
at our Brooklyn studio...",
// No startDate
// No location type
// Not indexed as Event
}
{
"@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
- Create event metafield namespace in Shopify Admin:
event.start_date,event.end_date,event.venue_name,event.latitude,event.longitude - Fill event metafields for all workshop/experience products
- Add Liquid conditional in
product.liquidto outputEventJSON-LD whenevent.start_datemetafield is present - Include
startDatewith full ISO 8601 datetime and timezone offset - Set
eventAttendanceModeusing the correct schema.org URI for online vs. in-person - Use
PlacewithPostalAddress+GeoCoordinatesfor in-person events - Use
VirtualLocationwithurlfor online events - Nest an
Offerwithprice,priceCurrency, andavailabilityinside the Event - Set
eventStatustoEventCancelledfor cancelled or past events - Validate with Rich Results Test and confirm Event rich results appear in Google Search Console
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.