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 webinar. Google requires three properties, name, startDate and location, and uses the rest to show dates, venue and ticket information in its event listings.

Two properties matter more than they look. eventStatus tells Google whether the event is still on, cancelled, postponed, rescheduled or moved online. eventAttendanceMode says whether people attend in person, online or both. 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.

json
{
  "@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

PropertyStatusWhat it is
nameRequiredThe event's title. Not the venue name and not a promotional headline.
startDateRequiredStart date and time in ISO 8601 with a time zone offset, such as 2026-11-14T19:30-05:00.
locationRequiredA Place with name and PostalAddress, a VirtualLocation with url for online events, or both for mixed events.
endDateRecommendedEnd date and time, in the same format.
eventStatusRecommendedEventScheduled, EventCancelled, EventPostponed, EventRescheduled or EventMovedOnline.
eventAttendanceModeRecommendedOfflineEventAttendanceMode, OnlineEventAttendanceMode or MixedEventAttendanceMode.
previousStartDateRecommendedThe original date, used when an event has been rescheduled.
offersRecommendedAn Offer with url, price, priceCurrency, availability and validFrom.
organizerRecommendedThe Person or Organization running the event, with name and url.
performerRecommendedWho performs or presents.
image / descriptionRecommendedAn event image and a short description of what happens.

In-person, online and mixed events

Match location to eventAttendanceMode:

  • In person: OfflineEventAttendanceMode with a Place that has a full PostalAddress.
  • Online: OnlineEventAttendanceMode with a VirtualLocation whose url is the page where people join or register.
  • Both: MixedEventAttendanceMode with an array containing the Place and the VirtualLocation.

When plans change, update the markup instead of deleting it:

  • Cancelled: set EventCancelled and keep the original startDate.
  • Postponed with no new date: set EventPostponed and 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: set EventMovedOnline and add a VirtualLocation.

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, so edit eventStatus and eventAttendanceMode if yours is online or 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. name is the event, the venue goes in location.
  • 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?

Yes. Use OnlineEventAttendanceMode and a VirtualLocation with the registration or join URL.

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.