What Is VideoObject Schema? The Complete Guide (2026)

Saar Twito11 min read
Saar Twito
Saar TwitoFounder & SEO Engineer

Hi, I'm Saar - a software engineer, SEO specialist, and lecturer who loves building tools and teaching tech.

View author profile →

What Is VideoObject Schema?

VideoObject schema is a type of structured data — based on the Schema.org VideoObject vocabulary — that tells Google a page contains a video and provides the metadata needed to index and display it in search results. When correctly implemented, Google can show your video with a thumbnail directly in search results, eligible for the video carousel, Key Moments timestamps, and a LIVE badge for livestreams.

Without VideoObject schema, Google must discover and interpret video content by crawling the actual video file — a slow, unreliable process. Structured data gives Google explicit, machine-readable facts about each video: its title, thumbnail, upload date, duration, and where to fetch the video itself. Sites using VideoObject schema see significantly higher video indexing rates and richer search appearances.

TL;DR
  • VideoObject schema tells Google what your video is and how to display it — enabling thumbnails in search, Key Moments, and the LIVE badge.
  • Three required fields: name (unique, descriptive), thumbnailUrl (crawlable image, min 60×30px), and uploadDate (ISO 8601 with timezone).
  • Always provide contentUrl (direct video file) or embedUrl (player URL) — preferably both. Without one of these, Greadme deducts 12 points and Google cannot crawl the video.
  • Key Moments use either hasPart (manual Clip objects) or potentialAction (SeekToAction — auto-detection). Never both at once.

Required Properties

PropertyTypeDescription
nameTextThe title of the video. Must be unique per video on your site — do not reuse the same title across different videos. Greadme warns if the value is a generic placeholder like "video" or "untitled".
thumbnailUrlURL or array of URLsURL of the video's thumbnail image. Must be crawlable by Googlebot — not blocked by robots.txt, login walls, or served as a data URL. Minimum size: 60×30 pixels; larger images preferred. At least 80% of pixels must be opaque (not transparent). Provide three aspect ratios as an array: 1×1, 4×3, and 16×9.
uploadDateDateTimeThe date the video was first published, in ISO 8601 format. Always include a timezone offset (e.g., 2026-03-15T10:00:00+00:00). Greadme warns if the timezone is missing — Google will default to Googlebot's timezone, which can cause incorrect date display.

Recommended Properties

PropertyTypeNotes
contentUrlURLDirect URL to the raw video file bytes (e.g., an .mp4file). This is Google's preferred method — it allows Google to actually crawl and index the video content. Greadme deducts 12 points if neither contentUrl nor embedUrl is present.
embedUrlURLURL of the video player (not the page where the player is embedded). Use this when contentUrl is not available. Can be provided alongside contentUrl. Must point to the player itself, not a containing page.
descriptionTextA description of the video. Must be unique per video — Greadme warns if it is identical to name. HTML tags are ignored by Google.
durationDurationVideo length in ISO 8601 duration format: PT#H#M#S. Example: PT1M54S (1 min 54 sec), PT30M (30 min). Videos under 30 seconds are not eligible for Key Moments — Greadme warns for durations shorter than 30 seconds.
expiresDateTimeDate after which the video is no longer available. Omit entirely if the video has no expiration. Greadme warns if the date is already in the past. Must include a timezone offset.
interactionStatisticInteractionCounterView count. Use @type: InteractionCounter with interactionType: WatchAction. See the code example below.
regionsAllowedArray of ISO 3166-1 codesCountries where the video is available. Use ISO 3166-1 two-letter codes (e.g., "US", "GB"). Use either regionsAllowed OR ineligibleRegion — never both. Greadme warns if both are present.

contentUrl vs embedUrl: Which to Use?

Both properties tell Google where to find your video, but they serve different purposes:

PropertyPoints toWhen to use
contentUrlThe raw video file (e.g., https://example.com/video.mp4)Always preferred. Allows Google to crawl and index actual video bytes, improving discoverability.
embedUrlThe video player URL (e.g., https://example.com/embed/123)Use when a direct file URL is not available — e.g., for streaming videos or third-party hosted content.

You can provide both simultaneously. Google prefers contentUrl but uses embedUrl as a fallback.

Key Moments: Clip vs SeekToAction

Key Moments are timestamps shown inside your video result in Google Search — letting users jump directly to specific sections. There are two mutually exclusive ways to implement them. Greadme warns if you use both at the same time.

Option A — Clip (Manual Key Moments)

Use hasPart with an array of Clip objects to manually define each moment. Each Clip requires:

PropertyTypeNotes
nameTextLabel for this section (e.g., "Introduction")
startOffsetNumberStart time in seconds. Must be a number. No two clips on the same video can share the same startOffset — Greadme throws an error for duplicates.
urlURLURL with a timestamp parameter pointing to this moment (e.g., ?t=30). Greadme warns if the URL lacks a timestamp parameter.
endOffsetNumberEnd time in seconds (recommended). Must be greater than startOffset — Greadme errors if not.

Videos must be at least 30 seconds long and support deep-linking (timestamp parameters) to be eligible for the Key Moments feature.

Option B — SeekToAction (Automatic Key Moments)

Use potentialAction with a SeekToAction to tell Google how your URL timestamp scheme works. Google then automatically identifies key moments itself.

"potentialAction": {
  "@type": "SeekToAction",
  "target": "https://example.com/video?t={seek_to_second_number}",
  "startOffset-input": "required name=seek_to_second_number"
}

The target must contain the literal placeholder {seek_to_second_number} — Greadme throws an error if it is missing. The startOffset-input value must be exactly "required name=seek_to_second_number".

LIVE Badge: BroadcastEvent

To display a LIVE badge on your video in Google Search, nest a BroadcastEvent inside the publication field. All three BroadcastEvent fields are required — Greadme errors on any that are missing:

PropertyTypeNotes
isLiveBroadcastBooleanMust be true.
startDateDateTimeWhen the livestream starts/started. ISO 8601 with timezone.
endDateDateTimeWhen the livestream ends/ended. Must be after startDate. ISO 8601 with timezone. The LIVE badge is removed when this date is in the past.

After updating BroadcastEvent markup (e.g., when going live or ending a stream), use the Google Indexing API to notify Google immediately — otherwise it may take hours for the badge to appear or disappear.

Complete Implementation Examples

1. Standard VideoObject

{
  "@context": "https://schema.org",
  "@type": "VideoObject",
  "name": "How to Make Sourdough Bread at Home",
  "description": "Step-by-step guide to baking sourdough from starter to loaf.",
  "thumbnailUrl": [
    "https://example.com/img/sourdough-1x1.jpg",
    "https://example.com/img/sourdough-4x3.jpg",
    "https://example.com/img/sourdough-16x9.jpg"
  ],
  "uploadDate": "2026-03-15T10:00:00+00:00",
  "duration": "PT18M30S",
  "contentUrl": "https://example.com/videos/sourdough.mp4",
  "embedUrl": "https://example.com/embed/sourdough",
  "interactionStatistic": {
    "@type": "InteractionCounter",
    "interactionType": { "@type": "WatchAction" },
    "userInteractionCount": 24800
  }
}

2. VideoObject with Key Moments (Clip)

{
  "@context": "https://schema.org",
  "@type": "VideoObject",
  "name": "Complete JavaScript Tutorial 2026",
  "thumbnailUrl": "https://example.com/img/js-tutorial.jpg",
  "uploadDate": "2026-01-10T08:00:00+00:00",
  "duration": "PT2H15M",
  "contentUrl": "https://example.com/videos/js-tutorial.mp4",
  "hasPart": [
    {
      "@type": "Clip",
      "name": "Variables and Data Types",
      "startOffset": 0,
      "endOffset": 480,
      "url": "https://example.com/js-tutorial?t=0"
    },
    {
      "@type": "Clip",
      "name": "Functions and Scope",
      "startOffset": 480,
      "endOffset": 1200,
      "url": "https://example.com/js-tutorial?t=480"
    }
  ]
}

3. LIVE Broadcast

{
  "@context": "https://schema.org",
  "@type": "VideoObject",
  "name": "Product Launch Livestream 2026",
  "description": "Live announcement and demo of our new product line.",
  "thumbnailUrl": "https://example.com/img/launch-thumb.jpg",
  "uploadDate": "2026-09-01T14:00:00+00:00",
  "contentUrl": "https://example.com/videos/launch-live.mp4",
  "embedUrl": "https://example.com/embed/launch",
  "publication": {
    "@type": "BroadcastEvent",
    "isLiveBroadcast": true,
    "startDate": "2026-09-01T14:00:00+00:00",
    "endDate": "2026-09-01T16:00:00+00:00"
  }
}

6 Common VideoObject Schema Mistakes

1. Blocking the Thumbnail with robots.txt

The thumbnailUrl must be crawlable by Googlebot Images. If the image is blocked by robots.txt or requires authentication, Google cannot fetch it and will not display the video thumbnail in search results — even if the schema is otherwise valid.

2. Using the Page URL as embedUrl

embedUrl should point to the video player, not the page that contains it. The difference: https://example.com/watch/123 (the page) vs https://example.com/embed/123 (the player). Greadme validates the URL format but cannot detect this semantic error — check it manually.

3. Missing Timezone in uploadDate

"uploadDate": "2026-03-15" is valid ISO 8601 but missing the time component and timezone. Greadme warns when the time is present but the timezone offset is absent. Always use the full format with offset: 2026-03-15T10:00:00+00:00.

4. Using Both hasPart and potentialAction

hasPart (manual Clip objects) and potentialAction (SeekToAction auto-detection) are mutually exclusive strategies for Key Moments. Greadme warns when both are present on the same VideoObject — remove one.

5. Duplicate startOffset Values in Clips

No two Clip objects on the same video can share the same startOffset. Greadme throws an error for duplicate start times. Each clip must begin at a distinct point in the video.

6. Setting expires to a Past Date

If expires is in the past, Google may de-index the video. Greadme warns when the expiry date has already passed. Remove the property entirely for videos that do not expire.

VideoObject Schema and AI Search Visibility

AI search platforms increasingly surface video content in their responses. When a user asks a how-to question, Google AI Overviews and Perplexity both consider video content as a high-authority answer format. VideoObject schema ensures your video's title, description, duration, and thumbnail are machine-readable — making them significantly easier for AI systems to identify as relevant, citable content.

For tutorial and educational content in particular, well-structured VideoObject schema with Key Moments timestamps increases the likelihood of being surfaced as a video answer in AI Overviews, since timestamps give AI systems a signal that the video is structured and navigable rather than a single undifferentiated block.

How to Validate Your VideoObject Schema

Paste your page URL into Greadme to validate your VideoObject schema. Greadme checks all three required fields, validates thumbnail URL format, verifies ISO 8601 duration and date formats, detects conflicting Key Moments strategies (Clip vs SeekToAction), validates every field inside Clip and BroadcastEvent objects, and warns about expired videos and missing timezone offsets.