Back to Blog
Guides5 min read3 August 2026

Event Schema for WordPress: The Complete Guide

Get your events into Google's event carousel and AI answers with a complete Event schema guide: in-person, online, hybrid, recurring, and cancellations.

By AI Schema Gen Team

Event Schema for WordPress: The Complete Guide

Event schema is one of the most visually rewarding types of structured data you can add, and one of the most underused. Done right, it can put your event into Google's eye-catching event carousel at the top of search results, complete with date, location, and a ticket link, and into the "events near me" experience people use to decide what to do. It also makes your events cleanly machine-readable for the AI assistants people increasingly ask "what's happening this weekend."

Whether you run a venue, organize conferences, host webinars, teach classes, or promote local happenings, this guide covers everything you need: the required fields, the recommended ones that unlock richer display, and every real-world variation: in-person, online, hybrid, recurring, ticketed, free, and events that get cancelled or rescheduled. Let's get your events seen.

What Event schema gets you

Event structured data tells search engines that a page is about a specific event, and describes its key facts (what, when, where, and how to attend) in a form they can display and extract.

For a full rundown of which schema types unlock which rich results, see our guide to schema types and rich results in 2026. The headline payoff for Event is Google's event experience. Qualifying events can appear in a scrollable carousel at the top of results for queries like "concerts near me," "tech conferences 2026," or a specific tour's dates, and in Google's dedicated events search. Each card shows the essentials and links straight to your page. These carousels are prime real estate, and they appear for exactly the high-intent searches where someone is deciding whether to attend.

There's a second, growing payoff that applies even when the visual carousel doesn't. Complete Event schema turns your event's title, date, location, performers, and ticket link into structured, machine-readable facts, which means AI assistants can extract and cite your event accurately rather than trying to infer it from your page's prose. As more people ask AI systems what's on, that clean machine-readability becomes its own reason to mark events up properly. We'll come back to this.

One important placement rule up front: Event schema belongs on the individual event's own page, not on a listing page that shows many events. Google's carousel links each card to a specific event URL, so each event needs its own page carrying its own markup. A calendar or listings page is a directory that should link out to those individual event pages.

The required fields (and the ones that actually matter)

Google's Event rich result has just three required fields:

  • name: the event's title
  • startDate: when it starts, in ISO 8601 format with a timezone
  • location: where it happens (a physical place, a virtual URL, or both)

Miss any of those three and you get nothing. But here's the thing worth internalizing: pages with only the three required fields tend to get noticeably less prominence than pages with a fully populated event schema. The three fields make you eligible; the recommended fields make you competitive.

So treat this recommended set as effectively part of the job:

  • endDate: when it ends (same ISO 8601 + timezone format)
  • eventStatus: scheduled, cancelled, postponed, rescheduled, or moved online
  • eventAttendanceMode: in person, online, or hybrid
  • image: a compelling event image
  • description: a clear summary of the event
  • offers: ticket or registration information, including price
  • organizer: who's running it
  • performer: who's appearing (for concerts, talks, shows)

Fill these in and you give Google everything it needs for the richest possible display, and you give AI systems a complete, accurate picture of your event.

A complete in-person event

Here's a full, well-formed Event block for a physical event, showing how the pieces fit together:

{
  "@context": "https://schema.org",
  "@type": "Event",
  "name": "Bright Coffee Roasting Masterclass",
  "startDate": "2026-09-18T18:00:00+01:00",
  "endDate": "2026-09-18T20:30:00+01:00",
  "eventStatus": "https://schema.org/EventScheduled",
  "eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode",
  "location": {
    "@type": "Place",
    "name": "Bright Coffee Roastery",
    "address": {
      "@type": "PostalAddress",
      "streetAddress": "40 Bridge Street",
      "addressLocality": "Manchester",
      "postalCode": "M3 3BT",
      "addressCountry": "GB"
    }
  },
  "image": "https://example.com/events/masterclass.jpg",
  "description": "A hands-on evening masterclass in single-origin coffee roasting, led by our head roaster.",
  "organizer": {
    "@type": "Organization",
    "name": "Bright Coffee Roasters",
    "url": "https://example.com"
  },
  "offers": {
    "@type": "Offer",
    "url": "https://example.com/events/masterclass",
    "price": "45",
    "priceCurrency": "GBP",
    "availability": "https://schema.org/InStock",
    "validFrom": "2026-07-01T09:00:00+01:00"
  }
}

A few things to notice. The dates carry a timezone offset (+01:00), which is required and important, because "6pm" means nothing to a machine without knowing where. The eventStatus and eventAttendanceMode use the full schema.org URL form (https://schema.org/EventScheduled), which is how these enumerated values must be written. And the offers block points at the page where people actually register.

Get this structure right once and every variation below is a small adjustment to it.

Online and virtual events

Webinars, virtual summits, and livestreams became a permanent fixture, and Event schema handles them cleanly. The two changes from an in-person event:

Set the attendance mode to online:

"eventAttendanceMode": "https://schema.org/OnlineEventAttendanceMode"

Use a VirtualLocation instead of a Place, with the URL where people actually join or register:

"location": {
  "@type": "VirtualLocation",
  "url": "https://example.com/webinar/live"
}

That's the core of it. For a webinar you might also choose a more specific subtype like EducationEvent; for a virtual summit, SocialEvent or BusinessEvent. The key rule: match the location type to the attendance mode. Online events use VirtualLocation; in-person events use Place. Mixing them up is a common error that muddles the signal.

Even though some online-only events don't qualify for the visual carousel, marking them up is absolutely still worth it: that structured title, date, and registration link is exactly what an AI assistant needs to answer "are there any good structured-data webinars coming up" with your event.

Hybrid events

For an event people can attend either in person or online, use the mixed attendance mode and provide both locations as an array:

"eventAttendanceMode": "https://schema.org/MixedEventAttendanceMode",
"location": [
  {
    "@type": "Place",
    "name": "DeFabrique",
    "address": {
      "@type": "PostalAddress",
      "addressLocality": "Utrecht",
      "addressCountry": "NL"
    }
  },
  {
    "@type": "VirtualLocation",
    "url": "https://example.com/conference/livestream"
  }
]

This accurately tells search engines and AI systems that both attendance options exist, so it can be presented correctly to people searching either way. Hybrid is where getting the attendance mode explicit matters most, since the event genuinely has two front doors.

Tickets, registration, and free events

The offers block works the same way it does in Product schema: it is how you surface ticket prices and registration, and it's worth getting right because price and a "get tickets" link are exactly what turn a search impression into an attendee.

A few rules that trip people up:

Price must be a plain number. No currency symbols, no thousands separators. Write "price": "45", not "£45" or "1,200". The currency goes separately in priceCurrency as a three-letter ISO code (GBP, USD, EUR).

Free events still need an Offer. This surprises people: even when an event is free, Google expects an offers object if visitors can register. Just set the price to zero:

"offers": {
  "@type": "Offer",
  "url": "https://example.com/events/free-talk",
  "price": "0",
  "priceCurrency": "GBP",
  "availability": "https://schema.org/InStock"
}

Point the offer URL at your registration page, the page where someone actually gets a ticket or signs up, so the path from search to signup is direct.

There's a nice strategic angle here worth knowing. If you sell tickets through a platform like Eventbrite, that platform generates its own Event schema, but only for its page, which sends the click to Eventbrite. By adding Event schema to your own event page, you make your page eligible to appear in Google's event results, directing that valuable click to your site instead. For most organizers, owning that traffic is well worth the small effort of marking up your own page.

Keeping events accurate: cancellations and reschedules

This is the most-neglected part of Event schema and one of the most important, because it's about what happens after you publish, and getting it wrong actively harms the trust you've built.

When something changes, update eventStatus; don't delete the schema. The enumerated values are:

  • https://schema.org/EventScheduled: going ahead as planned (the default)
  • https://schema.org/EventCancelled: cancelled
  • https://schema.org/EventPostponed: postponed, new date not yet set
  • https://schema.org/EventRescheduled: moved to a new date
  • https://schema.org/EventMovedOnline: changed to an online event

Why this matters so much: if you cancel an event but leave the status as scheduled, Google may keep showing it as a live event in the carousel. People click expecting an active event, find it's cancelled, and leave frustrated, which is a bad experience and a signal you don't want to send. So the moment something changes, update the status.

Two specific rules:

Keep the original startDate even when cancelled. Don't strip the date out; Google needs it to match the update to the right event. Change the status, keep the date.

When rescheduling, add previousStartDate alongside the new startDate, so the change is unambiguous:

"eventStatus": "https://schema.org/EventRescheduled",
"previousStartDate": "2026-09-18T18:00:00+01:00",
"startDate": "2026-10-16T18:00:00+01:00"

And if you have a refund or rebooking page, point your offers URL there when you cancel, so people who click land somewhere useful.

This ongoing accuracy is exactly the kind of thing that quietly breaks when markup is hand-maintained: someone updates the event page but forgets the schema, and the two drift apart. Generating your markup from your live event data, rather than maintaining a separate JSON-LD block by hand, is what keeps status and dates honest automatically. It's a good argument for letting a tool handle the markup, which we'll come to.

Recurring events and event series

A weekly class, a monthly meetup, a tour with twelve dates: recurring events are common and frequently marked up wrong. The rule is clear and worth following exactly:

Create a separate Event block for each occurrence, each with its own specific startDate and endDate. Do not use one Event with a vague or open-ended range, and never use aggregated dates like "every Tuesday." Google's carousel surfaces individual, dated occurrence cards, so a class that runs twelve times needs twelve Event objects, ideally each on its own URL.

To tell machines these occurrences belong to a series, connect each one to an EventSeries using the superEvent property:

{
  "@type": "Event",
  "name": "Weekly Coffee Cupping: September 24",
  "startDate": "2026-09-24T18:00:00+01:00",
  "superEvent": {
    "@type": "EventSeries",
    "name": "Weekly Coffee Cupping"
  }
}

Each occurrence stands on its own for the carousel, while superEvent expresses that they're part of one ongoing series: the best of both. This is more work than a single vague block, but it's the difference between showing up as real, dated, clickable events and not showing up at all.

Choosing the right event type

Event is one of 827+ schema types schema.org defines, but it also offers more specific subtypes, and using the precise one helps machines understand exactly what kind of event you're running:

  • MusicEvent: concerts, gigs, festivals
  • BusinessEvent: conferences, summits, trade shows
  • EducationEvent: classes, workshops, courses, webinars with a teaching focus
  • SocialEvent: meetups, parties, community gatherings
  • SportsEvent: matches, races, tournaments
  • TheaterEvent, ScreeningEvent, FoodEvent, ExhibitionEvent, and more

As with schema types generally, the more specific and accurate your choice, the more precisely a machine understands your event. Pick the subtype that genuinely describes it rather than defaulting to the generic Event: a concert marked as MusicEvent is clearer than one marked as a bare Event.

Performers and organizers

Two properties add real richness, especially for events where who's involved is a big part of the appeal.

organizer names who's running the event, usually your organization, connected to your broader identity. If you've built out your Organization entity, this connects your event to it, reinforcing both.

performer names who's appearing: the band, the speaker, the host. For concerts and talks this is central to how people search ("Taylor Swift tour dates"), so modeling performers as named entities genuinely helps:

"performer": {
  "@type": "Person",
  "name": "Maria Santos"
}

Connecting performers and organizers to real, recognized entities also feeds the broader entity picture that helps AI systems understand and surface your content, the same entity thinking that underpins modern AI search visibility.

Common mistakes to avoid

The errors that most often cost people the rich result:

Markup on a listings page instead of individual event pages. The carousel links to individual URLs, so each event needs its own page and its own markup.

Missing or timezone-less dates. startDate is required and must include a timezone offset. A bare "6pm" is incomplete.

Currency symbols or commas in the price. Price must be a plain number; currency goes in priceCurrency.

No Offer on a free event. Google still expects an offers block with price: "0" when people can register.

Deleting schema when an event is cancelled. Update eventStatus instead, and keep the original startDate.

Vague recurring dates. "Every Tuesday" or an open-ended range won't work. Each occurrence needs its own dated Event.

Mismatched location and attendance mode. Online events need VirtualLocation; in-person need Place; hybrid needs both. Mixing them muddles the signal.

Markup that doesn't match the page. As always, your event schema must reflect what's genuinely on the page: real dates, real prices, real details.

Implementing it on WordPress

You've got a few routes, and the right one depends on how many events you run and how often they change.

A dedicated event plugin may already output some Event schema if you use one to manage events. Check what it produces by viewing source on an event page, and confirm it includes the recommended fields, not just the required three. Many event plugins are thin on eventStatus, offers, and attendance mode.

Hand-maintained JSON-LD works for a venue with a handful of events, but it becomes a real burden, and a real risk, as events multiply and change. Every cancellation, reschedule, and new date is a manual edit, and the moment the schema and the page drift apart, you've got inaccurate markup.

Generating from your event content is what scales. Because your event pages already contain the facts (name, date, location, price), the markup can be generated from them and stay in sync as they change. This is where AI Schema Gen fits: it reads your event pages and produces complete, valid Event schema across the recommended fields, and because it generates from your live content, your dates, prices, and status stay accurate automatically rather than requiring you to hand-edit a separate block every time something changes. For anyone running more than a few events, that automatic accuracy is the whole game: a stale or cancelled-but-still-showing event is worse than no markup at all.

Whichever route you choose, the test is the same: does it cover the recommended fields, not just the required three; does it handle your online, hybrid, and recurring events correctly; and does it stay accurate when things change.

It's worth dwelling on the AI angle, because it changes the calculation for events that don't qualify for Google's visual carousel: online-only events, or events in categories Google doesn't surface visually.

Even without the carousel, complete Event schema makes your event's essential facts (title, date, time, location, performers, price, registration link) structured and machine-readable. That means when someone asks an AI assistant "what structured-data workshops are coming up" or "are there any coffee events in Manchester this month," the systems answering have clean, extractable facts about your event rather than having to parse them out of your page's prose and hope they got it right.

As people increasingly turn to AI assistants to discover what's happening, this machine-readability becomes a genuine visibility channel in its own right, and it's the same underlying principle behind getting cited by AI systems generally: the clearer and more structured your information, the more accurately AI can understand and surface it. Marking up your events isn't just chasing a carousel; it's making your events legible to every system people use to decide what to do.

Validating your Event schema

Before and after publishing:

Google's Rich Results Test confirms whether your event is eligible for the rich result and flags errors. Test an individual event page: a simple one, a ticketed one, and a recurring occurrence if you have them.

Search Console has an Events enhancement report showing how Google parsed your event markup across the site after crawling. This is where a template-level issue affecting all your events surfaces, so it's worth watching if you run many.

The Schema Markup Validator at validator.schema.org checks general syntax.

And check your dates render correctly: a timezone mistake or a wrong date is both easy to make and immediately visible to anyone who clicks.

Frequently Asked Questions


Running events on WordPress? AI Schema Gen generates complete Event schema (attendance mode, status, offers, and all) straight from your event pages, and keeps dates and status accurate as things change, across 827+ schema types. Start free at aischemagen.com.

Generate perfect schema in 30 seconds

AI Schema Gen handles everything automatically, free to start.

Get Started Free