You have a video on your site and you want search engines to understand it: its title, length, thumbnail and where the file or player lives. Video schema markup says all of that in a machine-readable form. It is a block of JSON-LD using the schema.org VideoObject type, which Google reads to learn about videos on your pages.
This guide is for site owners and developers who publish their own videos, self-hosted or embedded. You will leave with a working VideoObject example, the fields Google treats as required, the rules for thumbnails and files, a test routine, and a way to see in Search Console why a video was or was not indexed. One point first: markup alone does not get a video indexed. The page it sits on has to qualify.
Short answer: Video schema markup is a JSON-LD VideoObject block on the page that shows the video. Google lists name, thumbnailUrl and uploadDate as required, and recommends contentUrl or embedUrl. The markup must match what visitors see, and valid markup does not guarantee a video result in search.
Before you begin
- Pages: know which URL shows each video. The markup belongs on that page, not in a site-wide template.
- Facts: gather the title, description, upload date, duration and thumbnail URL, plus the video file URL or the player URL.
- Access: you need to edit the page template, and ideally have Google Search Console access for the property.
- Time and risk: about thirty minutes per video. Markup that describes things a visitor cannot see can lead to a manual action, so keep it honest. Test on a staging copy if you have one.
What does video schema markup do, and what does it not do?
Google says structured data helps it understand a page and may enable richer presentation when the page is eligible. It does not guarantee that such features appear, so a page can carry valid markup and still show nothing special.
Video markup gives Google the metadata in a predictable shape, lets you name the thumbnail, and unlocks optional features such as key moments, a LIVE badge and country restrictions. It does not make a video load faster, and it cannot rescue a page that is not indexed. Google accepts JSON-LD, Microdata and RDFa and recommends JSON-LD; JSON-LD vs Microdata explains the difference.
Does the page need to be a watch page?
Yes, this is the first thing to check. Google's video guidance says a video is eligible for video features only when the watch page is indexed and the video is embedded on it, is not hidden behind other elements, and has a valid thumbnail at a stable URL. Google describes a watch page as a page whose main purpose is to show a single video, such as a video landing page, a TV episode player page or a sports highlight page.
Google's examples of pages that are not watch pages include a blog post reviewing an embedded video, a product page with a video, and a category page listing several videos with equal prominence. They can still appear as ordinary results, but they are not treated as watch pages.
So if a video is central to a topic, give it its own page with a unique title and description. If it is supporting material inside an article, do not expect it to be indexed as its own result. Google's Search Console help says it indexes only one video per page.
Which properties does a VideoObject need?
The table lists the properties Google documents for video rich results. "Required" means a missing value makes the page ineligible for that feature.
| Property | Status in Google's documentation | What to put there |
|---|---|---|
name |
Required | A title that is unique to this video |
thumbnailUrl |
Required | One or more URLs of the thumbnail image |
uploadDate |
Required | When the video was first published, in ISO 8601, ideally with a time zone |
contentUrl |
Recommended | The URL of the video file itself, not the page it is on |
embedUrl |
Recommended | The URL of the player, usually the src of the embed |
description |
Recommended | Unique text for this video; HTML tags are ignored |
duration |
Recommended | ISO 8601 duration, for example PT3M20S |
expires |
Recommended | Only if the video really stops being available |
regionsAllowed or ineligibleRegion |
Recommended | Country codes; use one of the two, not both |
interactionStatistic |
Recommended | View, like, comment or share counts, as numbers |
Google recommends contentUrl as the most effective way for it to fetch the video, and asks for embedUrl when no file URL is available. The two are different things. contentUrl points at the bytes of the video. embedUrl points at a player. Neither is the address of your watch page.
Step-by-step instructions
Step 1: Confirm the page qualifies and the video is visible
Open the page in a normal browser. The player should be visible without a click on a poster image, a swipe or typing; Google's guidance says not to rely on user actions to load the video. If a script injects the player, check that it appears in the rendered HTML, as shown in JavaScript SEO and rendering.
You have succeeded when the page has one clear video with its own title and description.
Step 2: Collect the values
Write down the title, description, upload date with time zone, duration, thumbnail URL and the file or player URL. Use the day the video was first published, not today's date. Leave expires out unless the video really stops being available; Google notes that a video with an expiration date in the past does not appear in video results.
You have succeeded when every value is copied from your own records, not guessed.
Step 3: Write the JSON-LD
Here is a complete example using the placeholder domain example.com. Swap in your own values and URLs.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "VideoObject",
"name": "How to Descale a Kettle in Five Minutes",
"description": "A short walkthrough of descaling a kettle with citric acid, including rinsing and safety notes.",
"thumbnailUrl": [
"https://example.com/media/descale-kettle-16x9.jpg",
"https://example.com/media/descale-kettle-4x3.jpg",
"https://example.com/media/descale-kettle-1x1.jpg"
],
"uploadDate": "2026-09-14T08:00:00+00:00",
"duration": "PT5M12S",
"contentUrl": "https://example.com/media/descale-kettle.mp4",
"embedUrl": "https://example.com/player/descale-kettle",
"interactionStatistic": {
"@type": "InteractionCounter",
"interactionType": { "@type": "WatchAction" },
"userInteractionCount": 1840
}
}
</script>
Delete interactionStatistic unless you have a real, current count.
You have succeeded when the JSON parses without errors.
Step 4: Make the thumbnail and the video fetchable
Google's thumbnail rules: at least 60 by 30 pixels (larger is preferred), in BMP, GIF, JPEG, PNG, WebP, SVG or AVIF, and reachable by Googlebot and Googlebot Images, so no robots.txt block and no login. A mostly transparent thumbnail is rejected: at least 80 percent of pixels need an alpha value above 250. Use one stable URL per video, and the same URL everywhere you describe it: the poster attribute, structured data and any sitemap.
The video file also needs a stable URL that robots.txt and noindex do not block, because Google fetches the bytes for previews and key moments. Supported types include MP4, WebM, MOV and M3U8; data URLs are not supported. If you are unsure what your rules block, see the robots.txt guide.
You have succeeded when both URLs open in a private window without logging in.
Step 5: Add the block to the watch page
Put the script in the head or body of the watch page; Google allows either. Generate it from the same data that prints the visible title and description so the two cannot drift apart. The WordPress route is covered in Add Schema Markup to WordPress.
You have succeeded when "view source" on the live page shows the block with this video's values.
Step 6: Test the markup
Paste the URL into the Rich Results Test and fix every critical error; missing recommended fields are optional. Then use the URL Inspection tool on the live page. Our walkthroughs How to Use the Rich Results Test and JSON-LD Validation cover both, and Rich Results Test Errors helps decode messages.
You have succeeded when the test detects a video item with no critical errors.
Crawvix's structured data check reads the JSON-LD blocks in the pages it samples, reports JSON that does not parse and, for VideoObject, flags a missing name, thumbnailUrl or uploadDate. It does not read Microdata or RDFa and cannot tell you whether Google will index a video, so use it as a first pass and confirm in Search Console.
Step 7: Tell Google about the page and watch the reports
List the watch page in your sitemap. A video sitemap can add the player, file and thumbnail locations; see Image, Video and News Sitemaps. Google says recrawling and reindexing can take several days. Search Console's Video indexing report then shows how many indexed watch pages contain an indexed video, with reasons for the rest.
You have succeeded when the page appears in the Video indexing report with a status you understand.
Optional extras: key moments, LIVE badge and regions
These are separate features with their own rules, so add them only when they fit.
- Key moments with
Clip. Each clip needs aname, astartOffsetin seconds and aurlthat deep-links to that time. The video must be at least 30 seconds long and support deep links, and no two clips on a page may share a start time.SeekToActionlets Google find moments itself. - LIVE badge with
BroadcastEvent. Nest it underpublicationwithisLiveBroadcast,startDateandendDate; Google's rules also describe using the Indexing API for stream start and end. - Country limits. Use
regionsAllowedorineligibleRegion, never both, with ISO 3166-1 codes. - Opting out of key moments. Google says the
nosnippetmeta tag does that.
What do the Video indexing report reasons mean?
Google's help page for the report lists reasons a page has no indexed video. A selection, in plain words:
| Reason shown | What to check |
|---|---|
| Video isn't on a watch page | The video is supporting content. Give it its own page if it should be indexed |
| Cannot determine video position and size | The player is not on the page at load, for example hidden behind a click |
| No thumbnail URL provided | Add thumbnailUrl or a poster attribute |
| Unsupported thumbnail format or invalid size | Use a supported type of at least 60 by 30 pixels |
| Thumbnail could not be reached | The URL requires a login or no longer exists |
| Video not found on host service | The video was deleted or is private at its host |
Fix the cause, then request a recrawl of the page. That does not force indexing; Google decides.
Final verification checklist
- The video sits on a page whose main purpose is that video, and that page is indexed.
- The page carries one
VideoObjectblock withname,thumbnailUrlanduploadDate. -
contentUrlorembedUrlis present and points to the file or player, not the watch page. - The values in the markup match the visible title, description and date.
- The thumbnail is a supported format, not blocked, and at a stable URL.
- The Rich Results Test shows a video item with no critical errors.
- The watch page is in your sitemap and appears in the Video indexing report.
- Your video schema markup matches the page, and nobody expects it to produce a video result on its own.
Common mistakes to avoid
- Putting the watch page address in
contentUrl. It must be the video file. Use the file or player URL. - Marking up a video that is not on the page. Markup has to describe content visitors can see. Remove it or add the video.
- Leaving out the time zone in
uploadDate. Google falls back to the time zone used by Googlebot, which may not match yours. - A thumbnail behind a login or a robots.txt rule. The report names this directly as a reason for no indexed video.
- Setting
expiresfor a video that stays online. A past expiry date removes it from video results.
Frequently asked questions
Do I need video schema markup if I embed a YouTube video?
Not always. Markup is one of several ways to give Google metadata; the video guidance also mentions video sitemaps and Open Graph. The bigger question is whether your page is a watch page. For an embedded video inside an article, the video is supporting content.
Will video schema markup get my video into a rich result?
Possibly, but Google does not guarantee it. Eligibility depends on the markup, the guidelines and the page; valid markup can still produce no special display.
Should I use contentUrl or embedUrl?
Provide contentUrl if you can, because Google recommends it. If you only have a player, provide embedUrl. Many pages can supply both.
Can one page have more than one video?
You can mark up several, but Search Console help says Google indexes only one video per page. Give important videos their own watch pages.
Related guides
- Image, Video and News Sitemaps: When They Help and How to Build Them
- JSON-LD Validation: Test and Debug Structured Data Step by Step
- Rich Results Test Errors: Fix the Most Common Problems and Warnings
- Lazy Load Iframes and Video Embeds Without Hurting the Page
- Add Schema Markup to WordPress
Official references
- https://developers.google.com/search/docs/appearance/structured-data/video
- https://developers.google.com/search/docs/appearance/video
- https://developers.google.com/search/docs/appearance/structured-data/sd-policies
- https://support.google.com/webmasters/answer/9495631?hl=en
- https://schema.org/VideoObject
Next step: Try the free website sample to see how your own site does on a few of these checks. This guide provides technical information, not a guarantee of rankings, traffic or index inclusion.