Skip to the tool
OnPageKit

Event Schema Generator

Event JSON-LD, with the location the mode requires.

ISO 8601 with offset
Place and PostalAddress
absolute URLs
where tickets are sold
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Event",
  "eventStatus": "https://schema.org/EventScheduled",
  "eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode"
}
</script>
  • No endDate. Without it a listing cannot tell a one-hour talk from a three-day festival.
  • No image declared. Event listings are shown with a picture, and one without loses the space to one with.
  • No offer declared. Free events benefit from a price of 0 and a ticket page just as much as paid ones.
  • No performer named. For a gig, a talk or a match it is the field most people search by.

Everything checked above is syntax and schema.org conformance. The event rich result itself is awarded by Google, so run the published URL through its Rich Results Test before you count on the listing.

Everything runs in your browser. Nothing you type is sent to a server.

Found a bug in this tool? Report it.

Share this tool

Fill in the details, take away the block

This event schema generator produces the Event JSON-LD that puts a date, a venue and a ticket link into search results, calendars and aggregators. Type the facts, watch the block build itself as you go, and copy it into the page. Nothing is sent anywhere; the work happens in the browser tab you are reading this in.

The two fields that govern the rest

Most schema types are a flat list of properties. Event is not: two enumerated fields change what the other fields are allowed to say.

eventAttendanceMode decides which location is legal. An in-person event takes a Place with a PostalAddress. A fully online event takes a VirtualLocation with the URL of the stream. A hybrid takes both, as an array. Marking an online event with a street address sends people to an empty building, and it happens constantly — usually because the venue field was left filled in from last year's page. This tool drops whichever node contradicts the mode you picked, and tells you it did.

eventStatus decides whether previousStartDate is required. Move a date and the markup has to carry both the new time and the one it replaced, or a calendar that already stored the old entry has no way to match them up. Choose Rescheduled here and the field appears, becomes mandatory, and is checked like any other date.

Time zones are not optional

2026-11-14T19:30:00 is not a moment. It is a clock reading, and it means one thing on a server in London and another in a listing shown in New York. Add the offset — +00:00 in winter, +01:00 during British Summer Time — or use Z for UTC.

The one case where a time is genuinely absent is an all-day event, and there the plain date 2026-11-14 is correct. The generator accepts it and flags it, so that a missing time is always a decision rather than an oversight.

Recurring events are many events

There is no repeat rule in this vocabulary. A weekly quiz night is fifty-two events, each with its own URL and its own startDate. One block claiming a range is wrong for every occurrence except the first, and aggregators will show it as a single evening that lasts a year.

Cancelling is a change of status, not a deletion

The instinct when something falls through is to pull the page. Do the opposite: keep the URL, set the status to cancelled, and leave the original startDate in place. That combination is the only signal that tells the systems holding a copy of your event to mark it as off. A deleted page just goes quiet, and the listing lingers.

What this checks, and what only Google can

The output is valid JSON-LD using schema.org properties with the value types they are defined to take. That is conformance, and it is what a generator can be held to. Feature eligibility is a separate judgement made by the search engine against your live page: paste the published URL into Google's Rich Results Test to see it. If the event sits at a venue you also run, the local business schema generator marks up the venue itself, and the breadcrumb schema generator handles the path from the listings page down to this date.

Frequently asked questions

Which fields does Google require for an event rich result?

Three: name, startDate and location. Everything else is optional in the strict sense, but a listing with no image, no offer and no end time competes badly against one that has them, because the panel it appears in has space for all of it. Treat the three as the floor, not the target.

How do I mark up an event that repeats every week?

One block per occurrence, each on its own URL with its own startDate. A single Event node cannot express "every Thursday until March", and squeezing a range into one block produces a listing that is wrong on every date but the first. If you have a series page, keep it as a hub that links out to the individual dates.

My event was cancelled. Should I take the page down?

No — deleting it is the one thing that guarantees nobody finds out. Leave the URL live, set eventStatus to EventCancelled, and keep startDate exactly as it was: that pair is what tells aggregators and calendars to strike it through rather than quietly forget it. The same logic applies to a postponement.

What goes in location when the event is online?

A VirtualLocation with the url people watch on. The attendance mode decides this outright, so the generator drops fields that contradict it: an Offline event ignores the stream url, an Online event ignores the venue, and only Mixed emits both, as an array with the Place first.

Why does the generator reject a start time without a time zone?

Because a bare local time is only meaningful on the machine that wrote it. Write 2026-11-14T19:30:00+00:00, or Z for UTC, and the doors open at the same moment for a reader in Cardiff and a crawler in California. A date with no time at all is accepted, since that is how an all-day event is written.

Related tools

Updated