Start free

VideoObject schema for web extraction

This is a ready-to-copy extraction schema for the VideoObject data shape. You describe a video page once as a typed JSON schema, send it to Extracto along with a single video URL, and the page runs through a real headless browser before the response comes back validated against your schema. Instead of writing and re-writing CSS selectors that break the moment a watch page ships a new layout, you name the fields you want (title, description, uploadDate, duration, viewCount, channel, thumbnailUrl, contentUrl) and let the extraction map them. Video pages are a hard target for selector-based scraping precisely because so much of the meaningful data lives in lazy-loaded components, collapsed description panels, and JSON-LD blocks rather than in stable, human-readable DOM nodes. Counts get abbreviated ("1.2M views"), upload dates render as relative strings ("3 weeks ago"), and durations show up both as on-thumbnail overlays and as ISO 8601 strings in structured data. Extracto normalizes those into the types your schema declares: viewCount as an integer, uploadDate as an ISO date, duration as a string you can parse deterministically. The single most important guarantee for video data is the null contract. When a field genuinely is not present, a private upload with a hidden view count, or a livestream that has no fixed duration yet, Extracto returns null for that field rather than inventing a plausible-looking number. That distinction matters more for video than for almost any other shape, because a fabricated view count or a guessed upload date silently corrupts trend dashboards, content audits, and creator analytics without ever throwing an error. Every request also runs through a managed anti-bot bypass layer with proxies handled for you, so consent walls, regional gates, and challenge pages on protected video hosts are handled as part of normal rendering with no setup on your end. The result is one URL in, typed JSON out, validated against the exact shape below.


Fields in a VideoObject schema

The fields teams most often extract for a videoobject, what type each one is, and whether it is usually present.

Field Type Required Notes
title string yes The video's title as displayed on the watch page. Returning it as a validated string means you get the clean headline text without surrounding markup, badges, or channel suffixes, so titles slot directly into a catalog or search index without per-page cleanup.
description string optional The full description body, including text hidden behind a 'show more' collapse that selector scraping often misses. Typed as a string, it arrives expanded; when a creator leaves the description empty, you get null instead of an empty-looking placeholder, so you can tell 'no description' apart from 'failed to read'.
uploadDate string optional The publish date in ISO 8601 form (YYYY-MM-DD). Watch pages frequently show relative dates like '3 weeks ago'; receiving a normalized ISO date lets you sort, bucket by recency, and compute age without writing fragile relative-time parsers, and null cleanly signals an unscheduled or hidden date.
duration string optional Runtime expressed as an ISO 8601 duration string (for example PT12M30S) so it parses deterministically into seconds. A live or premiere stream with no fixed length returns null rather than a fabricated 0, which keeps 'we could not determine length' separate from 'this video is zero seconds long'.
viewCount integer optional Total views as a real integer, not the abbreviated '1.2M' string the page renders. Typed numbers go straight into aggregations and charts with no locale or suffix parsing, and a video whose counter is hidden returns null instead of a misleading zero that would skew averages.
channel string optional The uploading channel or author name (the schema.org author/creator concept). Returned as a validated string so you can group videos by creator reliably; for anonymous or removed uploads it returns null rather than guessing a name from unrelated on-page text.
thumbnailUrl string optional An absolute URL to the poster image. Because the browser resolves relative and lazy-loaded image sources, you get a fully qualified link you can fetch or store directly, and pages with no resolvable thumbnail return null instead of a broken or partial path.
contentUrl string optional The canonical URL of the video resource (the playable or embed URL). Typed as a string URL, it gives you a stable handle to reference or re-fetch the asset; when only a player widget exists with no exposed source, you get null rather than a fabricated link that would 404.

The schema

Copy this and send it with any URL.

{
  "type": "object",
  "properties": {
    "title": {
      "type": "string"
    },
    "description": {
      "type": "string"
    },
    "uploadDate": {
      "type": "string"
    },
    "duration": {
      "type": "string"
    },
    "viewCount": {
      "type": "integer"
    },
    "channel": {
      "type": "string"
    },
    "thumbnailUrl": {
      "type": "string"
    },
    "contentUrl": {
      "type": "string"
    }
  },
  "required": [
    "title"
  ]
}

Example output

Validated JSON back, matching the schema.

{
  "title": "How to Brew Pour-Over Coffee",
  "description": "An illustrative example output. A step-by-step guide to brewing a clean, balanced pour-over coffee at home, covering grind size, water temperature, and pour technique. Values shown here are generic examples, not extracted from any real video.",
  "uploadDate": "2024-01-15",
  "duration": "PT10M34S",
  "viewCount": 1200000,
  "channel": "Example Coffee Channel",
  "thumbnailUrl": "https://example-videos.com/thumbnails/demo-clip-maxres.jpg",
  "contentUrl": "https://example-videos.com/watch?v=demo-clip"
}

Try this videoobject schema against a real page in the live demo, or read the docs to use it via the API.

VideoObject schema: FAQ

How is this different from scraping a watch page with CSS selectors?
With selectors you target specific DOM nodes, which break whenever the video host reorders components, renames classes, or moves data into a lazy-loaded panel. Here you describe the fields you want by name and meaning, and Extracto maps them from the fully rendered page, including content behind 'show more' collapses and inside JSON-LD blocks. You maintain a small schema instead of a brittle selector set per layout variant.
What happens when a field like viewCount or duration is not available?
Extracto returns null for that field rather than guessing. A private video with a hidden view count returns null for viewCount, and a live stream with no fixed length returns null for duration. This is deliberate: a fabricated number would silently corrupt analytics and trend dashboards, so a clear null lets you distinguish 'genuinely not present' from 'failed to read' and handle each case explicitly in your code.
Does it work on video hosts that block automated traffic, and what about login-only content?
Every request runs through a managed anti-bot bypass layer with proxies handled for you, so protected video hosts behind providers like Cloudflare, DataDome, or PerimeterX, plus consent and regional gates, are handled as part of normal rendering with no setup. The one exception is content that requires you to be signed in, such as private or members-only videos that need session cookies. That login-gated case is available on the Enterprise plan.
Are the returned values typed, or do I still have to parse strings?
They are typed to the schema you send. viewCount comes back as an integer rather than an abbreviated '1.2M' string, uploadDate is normalized to an ISO 8601 date instead of a relative phrase like '3 weeks ago', and duration is an ISO 8601 duration string such as PT10M34S that parses deterministically into seconds. You get values ready for aggregation, sorting, and storage without writing locale-aware or relative-time parsers yourself.