Video Schema Markup: Getting VideoObject Right

video schema markup

Video is one of the few structured data types where the payoff is still obvious. Get video schema markup right and your page becomes eligible for a thumbnail in web results, inclusion in the video tab, key moments that let searchers jump to a timestamp, and appearance in Google’s video-heavy result blocks. Get it wrong and Google may not associate the video with your page at all.

The type is VideoObject. It is more demanding than most schema types because several properties are genuinely required and one of them — a publicly accessible content or embed URL — is where most implementations quietly fail.

The properties Google actually requires

Four properties are non-negotiable for video rich result eligibility:

  • name — the video title. Match the visible title on the page.
  • description — a genuine description of the video content, not the page’s meta description recycled.
  • thumbnailUrl — a publicly crawlable image URL. Google specifies minimum dimensions and supported formats; check current documentation before generating thumbnails at scale.
  • uploadDate — in ISO 8601 format with a timezone offset, for example 2026-03-14T09:00:00+08:00.

Beyond those, you need at least one of contentUrl (a direct link to the raw video file) or embedUrl (the URL of an embeddable player). Google prefers having both when possible, because contentUrl lets it fetch and analyze the file directly.

Two recommended properties carry real weight. duration in ISO 8601 format — PT4M32S for four minutes thirty-two seconds — feeds the duration badge in results. And hasPart or SeekToAction enables key moments, which is the feature most worth the extra effort.

A complete working example

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "VideoObject",
  "name": "How to Replace a Bike Chain",
  "description": "A five-minute walkthrough covering chain measurement, removal, and quick-link installation.",
  "thumbnailUrl": ["https://example.com/img/bike-chain-thumb.jpg"],
  "uploadDate": "2026-03-14T09:00:00+08:00",
  "duration": "PT5M12S",
  "contentUrl": "https://example.com/video/bike-chain.mp4",
  "embedUrl": "https://example.com/embed/bike-chain"
}
</script>

Place it in the <head> or the <body> — Google reads JSON-LD from either — and generate it server-side from the same data that renders the player. Markup that drifts from what is on the page is the root cause of most video structured data problems.

Marking up embedded YouTube videos

This is the question that comes up most, and the answer is more nuanced than yes or no.

If you embed a YouTube video on your page, that video already has structured data on YouTube’s own watch page, and YouTube’s URL is what typically ranks for it. Adding VideoObject markup to your page tells Google the video is also hosted content on your URL, which can make your page eligible for video results rather than only YouTube’s.

Do it correctly or not at all:

  • Set embedUrl to the YouTube embed endpoint for that video, not the watch URL.
  • Do not set contentUrl — you do not host the file and cannot serve it directly.
  • Use the real upload date of the video, not the date you published the page.
  • Only mark up videos that are genuinely the main content of the page. Marking up a tangential embed at the bottom of a blog post is a mismatch between markup and page purpose.

Set expectations here. Even with correct markup, Google frequently favors the YouTube watch page for the video result. Your markup improves eligibility; it does not decide the outcome. Embedding someone else’s video and marking it up as yours is a clear violation and will not help.

Key moments: the feature worth the extra work

Key moments break a video into labeled segments so searchers can jump straight to the part they want. Two implementation paths exist.

The clip approach uses explicit hasPart entries, each a Clip with a name, a start offset in seconds, an end offset, and a URL containing the timestamp fragment. You control exactly which segments appear and what they are called. Use it when the labels matter.

The SeekToAction approach tells Google the URL pattern your player uses for timestamps and lets Google identify the segments itself. Less control, far less markup, and reasonable for a large video library where hand-labeling every chapter is impractical.

Both require that timestamps actually work on your page — clicking the URL with the time fragment must jump the player to that point. If the deep link does nothing, the feature will not be granted.

The mistakes that cost eligibility

Most failures come down to accessibility rather than syntax. Work through this list before blaming the markup:

  1. The thumbnail is not crawlable. Blocked by robots.txt, behind authentication, or on a CDN path that returns 403 to Googlebot. Fetch the thumbnail URL in a private window to confirm.
  2. The video file is blocked. Same problem for contentUrl. Google cannot analyze a file it cannot fetch.
  3. The video is not prominent on the page. Google’s guidance is that the video should be the main content. A player buried below 2,000 words of text may be ignored.
  4. Date format errors. A date without a timezone offset, or in a non-ISO format, is the single most common validation failure for this type.
  5. Duration in the wrong format. It must be ISO 8601 duration notation, not “5:12”.
  6. Markup on pages with no video. Templates that emit VideoObject on every URL regardless of content. That is a structured data mismatch and a spam violation.

Validating and monitoring

Google’s Structured Data Testing Tool was retired — ignore any tutorial that still points there. Test with the Rich Results Test, which renders the page first and therefore catches markup injected by a video player script or tag manager. It reports specifically whether the page is eligible for video rich results and which required properties are missing.

Use the schema.org validator when you need full vocabulary checking, and Search Console’s Enhancements reports to monitor live pages at scale. Videos gets its own report there with valid, warning, and error counts, example URLs, and a Validate Fix flow after deployment.

Also check the Performance report’s Video tab and the search appearance filter to see whether video results are actually driving impressions. Eligibility is not a guarantee — Google decides whether to show a rich result based on query, device, and its own layout choices, so valid markup with no errors can still produce no visible change. Judge the work on trends over several weeks, not on the first day.

Where this fits

Video markup pays off most on pages where video is genuinely the point — tutorials, product demos, reviews, and course content. On a site where video is decoration, the effort is better spent elsewhere.

The layer underneath still decides more than the markup does. A video page that loads slowly, is blocked from crawling, or duplicates three other URLs will not earn a rich result regardless of how clean the JSON-LD is. SEO Rocket’s technical audits cover that ground with quick scans of around 25 pages or deep full-site crawls verified past 900 pages, each issue backed by the real titles, URLs, and H1 text found on your site, alongside PageSpeed and Core Web Vitals with real-user field data. It does not write your VideoObject markup — that is a per-page decision — but it tells you whether the page carrying it is in shape.