Free Video Object Schema Generator

Fill in the facts visible on your page, copy the Video Object JSON-LD, and validate it before you publish. The guide, examples, and FAQs are below the tool. Generate this schema with AI

Type to filter 121 supported schema types.

Schema workflow

Use only facts a visitor can verify on the page, then validate the JSON-LD before publishing.

Required. A stable URL Googlebot can fetch, at least 60x30px.

Required. Google recommends a time and timezone; edit the JSON to add one, such as T08:00:00-04:00.

Google needs a name, a start time in seconds, and a URL that starts the video at that time for each clip.

Required

  • Visible Video Object content
  • Canonical page URL
  • Clear page owner/publisher
  • Fields that match the visible page

Recommended

  • A representative image when the schema supports it
  • SameAs or related links when visible
  • Validation before publishing

Avoid

  • Adding properties that are not visible
  • Copying example URLs into production
  • Skipping Google and Schema.org validation

Schema stacks

Use Video Object schema in a stack

Complete JSON-LD bundles that combine Video Object with the other types a real page needs. Browse all stacks

  • Media Schema Stack

    Video and Podcast pages with breadcrumb and FAQs. Great for media hubs that publish both audio and video versions.

  • Virtual Tour Stack

    Virtual tour pages with TouristTrip + VideoObject context, FAQs, and breadcrumb navigation.

  • Podcast + Video Stack

    PodcastEpisode or PodcastSeries pages with video, FAQs, and breadcrumb context for shows that publish both audio and video.

  • Video + Article Stack

    Article pages with embedded video, FAQs, and breadcrumb context. Great for tutorials or feature content with video.

  • Webinar / Replay Stack

    Webinar registration and replay pages with Event + VideoObject context, FAQs, and breadcrumbs.

  • Gaming / eSports Stack

    Team or tournament pages with SportsOrganization, events, highlight video, FAQs, and breadcrumb context.

Next step

Validate, repair, and publish clean structured data.

Check the generated JSON-LD against the visible page, then run both SwiftSchema and external validators before publishing.

Video Schema Markup — VideoObject JSON-LD for Google

VideoObject tells Google the title, thumbnail, date, and file of the video on a watch page. Google requires three properties and supports key moments and the LIVE badge.

Generate VideoObject JSON-LD

Why video markup doesn't show up

  • The markup is on a page that isn’t indexed, or that isn’t a watch page for the video. Google needs the watch page indexed first.
  • embedUrl or contentUrl points at the page the video is on, not the player or the file.
  • The thumbnail URL expires or is blocked by robots.txt, so Google can’t fetch it.
  • Key moment clips have no url that starts the video at that time.
  • SeekToAction uses query-input, but Google requires startOffset-input.

How SwiftSchema helps

The generator covers Google’s three required properties plus description, duration, contentUrl, embedUrl, and the creator.

It builds key moments as Clip items (name, start time, and clip URL) or as a SeekToAction with the startOffset-input Google requires, and adds a BroadcastEvent for livestreams.

What is VideoObject structured data?

VideoObject is the schema.org type for a video file. On the page where people watch a video, it gives Google the video's title, thumbnail, upload date, length, and the URL of the file or player.

Google says it tries to understand videos automatically, but markup lets you "influence the information that's shown in video results, such as the description, thumbnail URL, upload date, and duration." Videos can appear in the main search results, Video mode, Google Images, and Google Discover.

Required properties

PropertyWhat Google requires
nameThe video's title, unique for each video on your site.
thumbnailUrlOne or more URLs of the video's thumbnail image. See the thumbnail rules below.
uploadDateWhen the video was first published, in ISO 8601. Google recommends a timezone, such as 2026-10-14T08:00:00-04:00.

Recommended properties

PropertyNotes
descriptionUnique for each video. Google ignores HTML tags in it.
contentUrlThe URL of the video file itself, in a supported format such as MP4, WebM, or M3U8. Google says this is the most effective way for it to fetch your video.
embedUrlThe URL of the player, usually the src of the iframe or embed element. Use it when contentUrl isn't available. Never the page the video is on.
durationISO 8601, such as PT3M12S.
creator (or author)A Person or Organization with name and a url that identifies them.
expiresWhen the video stops being available. Leave it out if it doesn't expire.
hasPartClip items for key moments (below).
interactionStatisticAn InteractionCounter with interactionType (WatchAction, LikeAction, CommentAction, or ShareAction) and userInteractionCount.
publicationA BroadcastEvent for the LIVE badge (below).
regionsAllowed or ineligibleRegionCountry codes where the video is or isn't available. Add whichever fits.

publisher is a valid schema.org property on VideoObject, but Google's video documentation reads creator or author for who made the video.

Before markup: can Google index the video?

Google's video best practices list what a video needs before structured data can help:

  • The watch page is indexed, and "performing well in Search." An indexed page doesn't guarantee an indexed video.
  • The video is embedded on the watch page, not hidden behind other elements, and doesn't need the user to swipe, click, or type to load.
  • A valid thumbnail at a stable URL: BMP, GIF, JPEG, PNG, WebP, SVG, or AVIF, at least 60x30 pixels, not blocked by robots.txt or a login.
  • A supported file type, such as MP4, MOV, WebM, or M3U8. Data URLs don't work.
  • Behind a paywall? Add paywalled content markup so Google can still find the video.

Key moments: Clip or SeekToAction

Key moments let people jump to parts of a video from Search. Google may find them automatically. To set them yourself, use one of two methods:

  • Clip (in hasPart): you list each segment with a name, a startOffset in seconds, and a url that starts the video at that point, plus an optional endOffset. No two clips on the same video may share a start time. Works in every language Google Search supports.
  • SeekToAction (in potentialAction): you give a target URL with {seek_to_second_number} where the timestamp goes, and "startOffset-input": "required name=seek_to_second_number". Google then finds the moments itself. Supported in 12 languages, including English and Spanish.

Google says to use Clip instead of SeekToAction if you prefer to mark key moments yourself. Both need a video of at least 30 seconds that can be deep-linked to a point other than the start, on a page where people can watch it. For a YouTube video, put timestamps in the YouTube description instead. To opt out of key moments entirely, use the nosnippet meta tag.

Livestreams and the LIVE badge

Add publication with a BroadcastEvent: isLiveBroadcast set to true, a startDate, and an endDate. If you don't know when the stream will end, give an estimate. Once it's over, the endDate must show when it actually ended.

Google asks you to call the Indexing API when the stream goes live, when it stops and the markup has the endDate, and whenever the markup changes. The Indexing API only supports livestream videos.

How to build it here

  1. 01

    Enter the video title, a description, and a thumbnail URL that won’t expire.

  2. 02

    Set the upload date and, if you know it, the duration in ISO 8601 (PT3M12S).

  3. 03

    Add the video file URL as Content URL, the player URL as Embed URL, or both.

  4. 04

    Add who made the video under Creator.

  5. 05

    For key moments, add clips with a name, start time, and clip URL, or a SeekToAction template.

  6. 06

    For a livestream, tick Live Broadcast and set the start and end times.

  7. 07

    Copy the JSON-LD into the watch page, then test it in Google’s Rich Results Test.

Ready to build the markup?

One VideoObject per video, on its watch page.

Generate VideoObject JSON-LD

The generator emits name, description, thumbnailUrl, uploadDate, duration, contentUrl, embedUrl, creator, hasPart clips, a SeekToAction potentialAction, and a BroadcastEvent publication. Empty fields are left out. The upload date and the live times have no timezone; add one such as -04:00 before you publish.

Common mistakes

  • embedUrl set to the page URL. It must be the player's URL. contentUrl must be the file.
  • An expiring thumbnail URL from a CDN. Google needs one stable thumbnail URL per video, the same in your sitemap and markup.
  • No dedicated watch page. Google's video features need a page whose main purpose is that one video.
  • Clips without a url, or two clips with the same start time.
  • query-input in SeekToAction. Google requires startOffset-input.
  • A description copied across every video. Google asks for unique text in name and description.

Required properties

  • name
  • thumbnailUrl
  • uploadDate

Recommended properties

  • description
  • contentUrl
  • embedUrl (if no contentUrl)
  • duration
  • creator (or author)
  • expires
  • hasPart (Clip, for key moments)
  • potentialAction (SeekToAction, for key moments)
  • publication (BroadcastEvent, for the LIVE badge)
  • interactionStatistic
  • regionsAllowed or ineligibleRegion
Watch page video with the recommended properties
Validate
{
  "@context": "https://schema.org",
  "@type": "VideoObject",
  "name": "How to Add Product Structured Data in 3 Minutes",
  "description": "A walkthrough of adding Product JSON-LD to a store page and testing it in Google's Rich Results Test.",
  "thumbnailUrl": [
    "https://www.example.com/thumbs/product-jsonld-1x1.jpg",
    "https://www.example.com/thumbs/product-jsonld-4x3.jpg",
    "https://www.example.com/thumbs/product-jsonld-16x9.jpg"
  ],
  "uploadDate": "2026-10-14T08:00:00-04:00",
  "duration": "PT3M12S",
  "contentUrl": "https://media.example.com/video/product-jsonld.mp4",
  "embedUrl": "https://www.example.com/embed/product-jsonld",
  "creator": {
    "@type": "Organization",
    "name": "Northstar Analytics",
    "url": "https://www.example.com"
  },
  "interactionStatistic": {
    "@type": "InteractionCounter",
    "interactionType": {
      "@type": "WatchAction"
    },
    "userInteractionCount": 4821
  }
}
Key moments with Clip
Validate
{
  "@context": "https://schema.org",
  "@type": "VideoObject",
  "name": "How to Add Product Structured Data in 3 Minutes",
  "thumbnailUrl": "https://www.example.com/thumbs/product-jsonld-16x9.jpg",
  "uploadDate": "2026-10-14T08:00:00-04:00",
  "contentUrl": "https://media.example.com/video/product-jsonld.mp4",
  "hasPart": [
    {
      "@type": "Clip",
      "name": "Write the Product JSON-LD",
      "startOffset": 15,
      "endOffset": 95,
      "url": "https://www.example.com/videos/product-jsonld?t=15"
    },
    {
      "@type": "Clip",
      "name": "Test it in the Rich Results Test",
      "startOffset": 95,
      "endOffset": 192,
      "url": "https://www.example.com/videos/product-jsonld?t=95"
    }
  ]
}
Key moments with SeekToAction
Validate
{
  "@context": "https://schema.org",
  "@type": "VideoObject",
  "name": "How to Add Product Structured Data in 3 Minutes",
  "thumbnailUrl": "https://www.example.com/thumbs/product-jsonld-16x9.jpg",
  "uploadDate": "2026-10-14T08:00:00-04:00",
  "contentUrl": "https://media.example.com/video/product-jsonld.mp4",
  "potentialAction": {
    "@type": "SeekToAction",
    "target": "https://www.example.com/videos/product-jsonld?t={seek_to_second_number}",
    "startOffset-input": "required name=seek_to_second_number"
  }
}
Livestream with the LIVE badge (BroadcastEvent)
Validate
{
  "@context": "https://schema.org",
  "@type": "VideoObject",
  "name": "Structured Data Office Hours, Live",
  "description": "Live Q&A on schema markup and Google rich results.",
  "thumbnailUrl": "https://www.example.com/thumbs/office-hours-16x9.jpg",
  "uploadDate": "2026-10-20T12:00:00-04:00",
  "embedUrl": "https://www.example.com/embed/office-hours",
  "publication": {
    "@type": "BroadcastEvent",
    "isLiveBroadcast": true,
    "startDate": "2026-10-20T12:00:00-04:00",
    "endDate": "2026-10-20T13:00:00-04:00"
  }
}

FAQs

Which VideoObject properties does Google require?Show

Three: name, thumbnailUrl, and uploadDate. Google recommends description, contentUrl or embedUrl, duration, creator, and the others listed on this page. Without the required properties, Google says it may not be able to extract any information about the video.

What's the difference between contentUrl and embedUrl?Show

contentUrl is the URL of the video file itself, such as an MP4. embedUrl is the URL of the video player, usually the src of the iframe or embed element. Neither should be the page the video is on. Google says contentUrl is the most effective way for it to fetch your video, and embedUrl is the alternative.

How do I get key moments for my video?Show

Either list each segment yourself with Clip (name, startOffset in seconds, and a url that starts the video at that point), or use SeekToAction to tell Google how your timestamp URLs work so it can find key moments itself. The video must be at least 30 seconds long and support deep links to a point in the video. For YouTube videos, timestamps in the YouTube description work instead.

How do I get the LIVE badge?Show

Add publication with a BroadcastEvent that has isLiveBroadcast true, startDate, and endDate (an estimate is fine before the stream ends). Google asks you to call the Indexing API when the stream starts, when it ends, and when the markup changes.

Does VideoObject markup guarantee a video result?Show

No. The watch page must be indexed and performing well in Search before its video is considered, the video must be embedded on that page and not hidden, and it needs a valid thumbnail at a stable URL. Google also doesn't guarantee any feature that uses structured data.

What format does uploadDate need?Show

ISO 8601, such as 2026-10-14 or 2026-10-14T08:00:00-04:00. Google recommends including a timezone; without one, it uses Googlebot's timezone.

Related types

Browse all schema types

References