Skip to main content
Each of your video pages can carry the metadata AI and search engines read: JSON-LD with chapters, a visible transcript, and links agents follow. Your page template makes one request per page, with the id your platform already has for the video. Your CDN keeps the answer. The page block is the crawl-time view of the ARV record. It is one JSON file with ready HTML for the page head and the page body.

The request

string
required
Your account slug, for example your-brand.
string
required
Your own video id, URL-encoded, for example catalog%3Avideo%3A1234. Up to 200 printable characters, no leading or trailing space. The catalog import stores this id.
string
default:"json"
  • json: the whole block as JSON. See the Quickstart for the shape.
  • head: text/html for the page head. The JSON-LD script, the discovery link tags and, when on, the WebMCP tags.
  • body: text/html for the page body. Chapter summaries and the transcript. Empty when the rights allow neither.
Any other value returns 404.
string
Only for an unlisted account: Bearer <account API key>. See Listed and unlisted accounts.
The block never contains a stream URL.

Render it server side

Fetch the block in your server, edge function or build step, and write it into the HTML you send. Do not load it with a script in the browser. Many crawlers and AI fetchers read the HTML as sent and never run scripts, so metadata added in the browser stays invisible to them.
Fetch at build time if you build pages ahead. Each build then gets the newest block, for example after AgentTV improves a transcript.

One VideoObject per page

A page should describe its video once. If your page already renders a VideoObject, merge the block into it. Do not add a second one.
  • You render no VideoObject. Put head_html (or the format=head response) in your page head as it is.
  • You already render a VideoObject. Use format=json. Take the fields you lack from json_ld["@graph"][0], most of all hasPart (the chapters as Clip items), and add them to your own object. Keep your own @id, url, embedUrl, contentUrl and player fields. Then render each of discovery.links as a <link> tag in your head.
Each Clip in hasPart has a url at the chapter’s start second. For a listed account it points to the AgentTV watch page. Search engines show key moments best when each Clip url is your own page, opened at that second. When you merge, rewrite each url to your page with your player’s start parameter, and keep startOffset as it is:
For an unlisted account the block already does this, with the start rule we set for your player. See Start at the moment.

WebMCP tags when you merge

When WebMCP site tools are on for your account and your site is verified, head_html ends with two more tags. They are not in the JSON fields. If you merge the JSON, copy them from the format=head response into your head:
They let an AI agent in the visitor’s browser search your catalog and play a moment on the page. See Crawl time and inference time. Copy them as served: the version and the ids can change.

Chapters and the transcript

  • Chapters come as Clip items in the JSON-LD, with a name, a description, and start and end offsets in seconds.
  • The transcript comes as transcript.cues, each with start_seconds and text. It is never inside the JSON-LD.
  • body_html is ready HTML with the chapter summaries and the transcript, with plain timestamps and no links. Put it in your page body, or build your own section from transcript.cues.
Keep the transcript as text in the HTML you send, not in a script or a data attribute. A toggle that collapses it is fine.

Parts

A long video often has its own structure: each match of an event, each talk of a conference, each segment of a show. AgentTV finds it from the chapters and serves it as parts. Each part is a run of the video’s chapters in a row, with its own title, description and thumbnail. Use it to lay out a long video by its structure, for example a rail of matches.
  • parts is [] when the video has none.
  • Times are in milliseconds from the start of the video.
  • A thumbnail_url is null when your rights do not allow showing the picture.
  • On a read with your account key, each thumbnail_url is a signed frame URL that is valid for about an hour. Fetch the block again for fresh URLs. Do not store them as permanent links.
In the JSON-LD, each part is a Clip in hasPart, with its chapters as nested Clip items. A video with no parts keeps its chapters as flat Clip items.

Language

The block states the video’s spoken language and subtitle languages as language_primary, language_source, language_confidence, subtitle_tracks and caption_languages. The JSON-LD carries them as inLanguage, subtitleLanguage and caption, and body_html sets a lang attribute on the video’s words. See Languages. The transcript is present only when your rights allow quotes and the grant is not gated or limited to a territory. Chapter summaries show only when your rights allow summaries. See Rights and access.

Caching and traffic

A listed account’s 200 comes with these headers:
  • Your CDN may keep a block for 5 minutes and serve it stale for 5 more while it refreshes. A rights change reaches your pages within 10 minutes.
  • Send the ETag back as If-None-Match. An unchanged block returns 304 with no body. Each format has its own ETag.
  • There is no purge call. To refresh at once, listen for the video.updated webhook and fetch again.
  • Every 404 is Cache-Control: private, no-store. A newly published video shows on the next request.
  • An unlisted account’s key read is always private, no-store. Cache it in your own server, keyed by video id, and refresh on the webhook.
  • A key read also has an ETag and answers a matching If-None-Match with 304. Its ETag changes every hour, with the signed frame URLs, so a 304 means your cached URLs are still valid. To tell a real content change from the hourly re-signing, compare the x-agentcdn-content-version header. It changes only when the content changes.
With a CDN in front, AgentTV sees about one request per video per CDN cache every 5 minutes, whatever your page traffic.

When there is no block

The route returns 404 with {"error": "owned_web_artifact_unavailable"}, never an empty 200, when:
  • the id is unknown, or belongs to another account,
  • the video is not published, or not public on a listed account,
  • the video’s rights block citation,
  • the format value is not one of the three above.
Render the page without the block. Do not cache an empty block.