Event schema markup: example, required fields and WordPress setup
Event schema describes something that happens at a specific time and place: a concert, a workshop, a conference session, a food festival. Google requires three properties, name, startDate and location, and uses the rest to show dates, venue and ticket information in its event listings. Those listings are only for things people can turn up to: Google's Event documentation rules out virtual experiences that have no real-world component.
Two properties matter more than they look. location must be a Place with a real address, which is the line between an event Google can list and a webinar it won't. eventStatus tells Google whether the event is still on, cancelled, postponed or rescheduled. Getting these right is what keeps a listing accurate when plans change.
JSON-LD example
Copy this into a <script type="application/ld+json"> tag and replace the values with your own.
{
"@context": "https://schema.org",
"@type": "Event",
"name": "Intro to Wheel Throwing: Evening Workshop",
"startDate": "2026-11-04T18:30-05:00",
"endDate": "2026-11-04T21:00-05:00",
"eventStatus": "https://schema.org/EventScheduled",
"eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode",
"location": {
"@type": "Place",
"name": "Kilnworks Studio",
"address": {
"@type": "PostalAddress",
"streetAddress": "88 Foundry Road",
"addressLocality": "Providence",
"addressRegion": "RI",
"postalCode": "02903",
"addressCountry": "US"
}
},
"image": [
"https://example.com/images/wheel-throwing-class.jpg"
],
"description": "A hands-on evening workshop on centering clay and pulling your first cylinder. Clay and firing included.",
"offers": {
"@type": "Offer",
"url": "https://example.com/classes/wheel-throwing",
"price": 65,
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"validFrom": "2026-09-01T09:00-04:00"
},
"organizer": {
"@type": "Organization",
"name": "Kilnworks Studio",
"url": "https://example.com"
}
}
Properties
| Property | Status | What it is |
|---|---|---|
name | Required | The event's title. Not the venue name and not a promotional headline. |
startDate | Required | Start date and time in ISO 8601 with a time zone offset, such as 2026-11-14T19:30-05:00. |
location | Required | A Place with name and a full PostalAddress. Google's event feature only accepts a Place, so a page whose only location is a VirtualLocation gets no listing. |
endDate | Recommended | End date and time, in the same format. |
eventStatus | Recommended | EventScheduled, EventCancelled, EventPostponed or EventRescheduled. schema.org also has EventMovedOnline, which Google does not document. |
eventAttendanceMode | Recommended | OfflineEventAttendanceMode, OnlineEventAttendanceMode or MixedEventAttendanceMode. Valid schema.org, but not part of Google's current Event documentation. |
previousStartDate | Recommended | The original date, used when an event has been rescheduled. |
offers | Recommended | An Offer with url, price, priceCurrency, availability and validFrom. |
organizer | Recommended | The Person or Organization running the event, with name and url. |
performer | Recommended | Who performs or presents. |
image / description | Recommended | An event image and a short description of what happens. |
Venues, hybrid events and changed plans
Google's event experience covers events with a physical location and nothing else. That decides how each format should be marked up:
- In person: a Place with a full PostalAddress. This is the case Google lists.
- Hybrid: the venue as the Place. schema.org lets you add a VirtualLocation for the stream alongside it, but the venue is what makes the page eligible.
- Online only: a webinar can still carry Event markup with a VirtualLocation, and it is valid schema.org, but it will not appear in Google's event listings. For a livestream, VideoObject with a BroadcastEvent is the type Google actually uses, for its LIVE badge.
When plans change, update the markup instead of deleting it:
- Cancelled: set
EventCancelledand keep the original startDate. - Postponed with no new date: set
EventPostponedand keep the original startDate until a new one is known. - Rescheduled: set
EventRescheduled, put the new date in startDate and the old one in previousStartDate. - Moved online: once there is no venue, the event falls outside Google's listings. schema.org's
EventMovedOnlinestill describes the change accurately for other parsers.
Add it in WordPress
By hand. Print JSON-LD from wp_head on each event's page. Event plugins often output their own markup, so check the page source before adding more.
With Hydrogen SEO. Choose Event in the event page's SEO Settings sheet and fill the name, start and end dates, location and offer fields. The plugin renders JSON-LD server-side. Keep dates accurate; expired events still carrying live markup are a common source of Search Console warnings.
One-off markup. The free schema generator in the Hydrogen SEO app at /seo/schema-generator builds Event JSON-LD, including location and ticket offer, from a short form. Its output assumes a scheduled, in-person event, which is the kind Google lists, so edit eventStatus if the date has changed.
Common mistakes
- Marking up things that are not events. Coupons, sales that run for weeks, and business hours are not Events.
- One block for a multi-date series without separate dates. Each occurrence with its own date should be its own Event, ideally with its own page or clearly listed.
- Missing time zone. A startDate without an offset can shift the listed time.
- Venue name as the event name.
nameis the event, the venue goes inlocation. - Deleting markup on cancellation. Set eventStatus instead, so Google can show that it is cancelled.
More: invalid structured data.
Test it
Start offline: the free validator shows which Event fields are missing. After publishing, recheck the real URL in Google's Rich Results Test. Check that the start time in the parsed output is the local time you intended. Search Console's Events report flags errors across all event pages; after an event ends, its markup can come off or stay, but it should never show the wrong status.
Common questions
Can I use Event schema for a webinar?
You can, since the markup is valid, but it will not earn an event listing. Google only supports events that take place in a physical location, so a webinar with no venue is left out.
What should I do when an event is cancelled?
Keep the markup, set eventStatus to EventCancelled and leave the original startDate. Do not change the date to something else.
Do I need offers for a free event?
Offers are recommended, not required. For a free event you can include an Offer with price 0 and your registration URL.
Should recurring classes be one Event or many?
Mark up each dated session as its own Event. A single block cannot describe several start dates.