Why You Are Here
FAQ lost its in 2026. HowTo lost its in 2023. Event did not. Correctly marked-up events can appear in Google's event carousel, a scrollable row at the top of results showing the date, venue, and a ticket link for each event.
That carousel surfaces for queries like concerts near me, conferences 2026, and artist or venue names. For anything date-bound, it is one of the highest-return markup types available.
The first situation is a venue, promoter, or organiser whose event pages carry no structured data, leaving the carousel out of reach entirely.
The second is diagnosing why events are not appearing. Usually the cause is one of the specific issues covered below: markup on the listing page rather than individual event pages, a missing timezone, or a recurring event described as one open-ended range.
The third is a site with an events calendar generating pages from a template, where the markup needs to be right once so it is right across hundreds of pages.
What This Tool Does
The Event Schema Generator builds valid Event JSON-LD from a simple form.
Choose your event type, enter the name, start and end dates with timezone, venue address, organiser, and ticket details, and the tool assembles correctly structured JSON-LD with Place, PostalAddress, and Offer nested properly, with the script tag included. Copy it and paste it into your page.
Only Three Properties Are Required
Event has one of the simplest requirement sets of any rich result type.
| Property | Status |
|
name |
REQUIRED |
|
startDate |
REQUIRED |
|
location |
REQUIRED |
The Virtual Event Question
This deserves a straight answer because the guidance around it is muddled.
That is the position for the event rich result.
At the same time, Schema.org fully supports VirtualLocation, the eventAttendanceMode property exists precisely to distinguish online from offline, and AI search systems parse virtual event markup without difficulty.
| Your Event | Carousel Eligible | Worth Marking Up |
|
Physical venue |
Yes |
Yes |
|
Hybrid, physical and online |
Yes, via the physical component |
Yes |
|
Online only, no physical component |
NO |
YES, for AI and other engines |
Mark up your webinar. It will not earn a Google event carousel slot, but AI assistants answering event questions increasingly draw on structured data, and other search engines have their own rules. What you should not do is expect the carousel and then wonder why it never appears.
Property Reference
| Property | Status | Notes |
|
name |
REQUIRED |
The event title |
|
startDate |
REQUIRED |
ISO 8601 with timezone offset |
|
location |
REQUIRED |
Place, VirtualLocation, or an array |
|
endDate |
Recommended |
Same format as startDate |
|
eventStatus |
Recommended |
Scheduled, cancelled, postponed, rescheduled |
|
eventAttendanceMode |
Recommended |
Offline, online, or mixed |
|
image |
Recommended |
Multiple aspect ratios preferred |
|
description |
Recommended |
What the event is |
|
offers |
Recommended |
Ticket price, currency, availability, URL |
|
offers.price |
Recommended |
Number only, no symbol |
|
offers.priceCurrency |
Recommended |
ISO 4217 code |
|
offers.availability |
Recommended |
Schema.org URL value |
|
offers.validFrom |
Recommended |
When tickets go on sale |
|
performer |
Recommended |
Person or PerformingGroup |
|
organizer |
Recommended |
Organization or Person |
|
previousStartDate |
Conditional |
Required when rescheduled |
|
isAccessibleForFree |
Optional |
True or false |
|
maximumAttendeeCapacity |
Optional |
Venue or ticket capacity |
Write 2026-09-15T09:00:00+05:00, not 2026-09-15T09:00:00. Without an offset, Google falls back to the timezone of the location you supplied, which is usually right but not always, and is guesswork you can simply remove.
Use a date alone rather than inventing a time. 2026-09-15 is valid for both startDate and endDate.
Event Subtypes
A specific subtype carries more meaning than the generic Event.
| Event | subType |
|
Concert or gig |
MusicEvent |
|
Conference or summit |
BusinessEvent |
|
Theatre, dance, comedy |
TheaterEvent |
|
Sports fixture |
SportsEvent |
|
Exhibition or show |
ExhibitionEvent |
|
Festival |
Festival |
|
Course or class |
EducationEvent |
|
Screening |
ScreeningEvent |
|
Charity or fundraiser |
SocialEvent |
|
Sale or promotion |
SaleEvent |
Example schema
{
"@context": "https://schema.org",
"@type": "MusicEvent",
"name": "Autumn Sessions: Live at the Bridgewater",
"startDate": "2026-10-14T19:30:00+01:00",
"endDate": "2026-10-14T22:30:00+01:00",
"eventStatus": "https://schema.org/EventScheduled",
"eventAttendanceMode":
"https://schema.org/OfflineEventAttendanceMode",
"location": {
"@type": "Place",
"name": "Bridgewater Hall",
"address": {
"@type": "PostalAddress",
"streetAddress": "Lower Mosley Street",
"addressLocality": "Manchester",
"postalCode": "M2 3WS",
"addressCountry": "GB"
}
},
"image": [
"https://example.com/images/event-1x1.jpg",
"https://example.com/images/event-16x9.jpg"
],
"description": "An evening of contemporary chamber music.",
"performer": {
"@type": "PerformingGroup",
"name": "The Northern Quartet"
},
"organizer": {
"@type": "Organization",
"name": "Example Concerts",
"url": "https://example.com"
},
"offers": {
"@type": "Offer",
"url": "https://example.com/tickets/autumn-sessions",
"price": "24.00",
"priceCurrency": "GBP",
"availability": "https://schema.org/InStock",
"validFrom": "2026-07-01T09:00:00+01:00"
}
}
Recurring Events
This is where a lot of event markup goes wrong.
A weekly class running every Tuesday for twelve weeks is twelve Event objects, not one block spanning three months. Google's carousel surfaces individual occurrence cards, each linking to its own URL. One block describing a vague range gives it nothing specific to show.
• A single block with a start date in January and an end date in December
• Descriptions such as every Tuesday in place of actual dates
• One block reused for a whole season of events
• One Event object per occurrence, each with exact startDate and endDate
• Its own page per occurrence where practical
• Past occurrences removed or updated rather than left indefinitely
Cancelled, Postponed, and Rescheduled Events
The instinct when an event is cancelled is to remove the date or delete the markup. Both are wrong.
startDate remains required regardless of status. Blanking it breaks the markup.
| Situation | eventStatus | Also do |
|
Going ahead |
EventScheduled |
— |
|
Cancelled |
EventCancelled |
Keep the original startDate; point offers.url at a refund page |
|
Postponed, new date unknown |
EventPostponed |
Keep the original startDate |
|
Rescheduled |
EventRescheduled |
New date in startDate, old date in previousStartDate |
|
Moved online |
EventMovedOnline |
Update eventAttendanceMode and location |
Common Mistakes to Avoid
Each card in Google's event carousel links to its own event URL, so the structured data has to live on the individual event page. Marking up a page that lists twenty upcoming events gives Google no distinct destination per event. Give each event its own page with its own Event block, and let the listing page simply link to them.
A startDate such as 2026-09-15T09:00:00 with no offset leaves the time ambiguous. Google will fall back to the timezone of your location, which is usually correct but is an inference rather than a fact, and it fails outright if the location is imprecise. Always write the offset, and remember it shifts with daylight saving.
Removing or emptying startDate on a cancelled event breaks the markup, because startDate is required regardless of status. The correct approach is to keep the original date and set eventStatus to EventCancelled, which tells Google exactly what happened and lets it update the display accordingly.
Quick Reference
| Item | Detail |
|
Type |
Event or a specific subtype |
|
Rich result |
Event carousel, fully supported |
|
Required |
name, startDate, location |
|
Dates |
ISO 8601 with timezone offset |
|
No known start hour |
Use a date alone |
|
Online-only |
No carousel, still worth marking up |
|
Hybrid |
location array, Place plus VirtualLocation |
|
Recurring |
One block per occurrence |
|
Cancelled |
Keep startDate, set eventStatus |
|
Rescheduled |
Add previousStartDate |
|
Placement |
Individual event pages, not listings |
|
Price |
Number only, currency separate |
