{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/govtube-us/json-schema/govtube-us-search-response-schema.json",
  "title": "SearchResponse",
  "x-generated": "2026-11-11",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/govtube-us-openapi.json#/components/schemas/SearchResponse",
  "properties": {
    "api_version": {
      "type": "string",
      "title": "Api Version",
      "default": "v1"
    },
    "query": {
      "type": "string",
      "title": "Query"
    },
    "normalized_query": {
      "type": "string",
      "title": "Normalized Query"
    },
    "sort": {
      "type": "string",
      "enum": [
        "newest",
        "most_instances"
      ],
      "title": "Sort",
      "description": "newest: event date, newest first (default); on the same day, timed video sessions before untimed official transcripts, then video id. most_instances: instance count, most first; ties newest first, then video id.",
      "default": "newest"
    },
    "order_exact": {
      "type": "boolean",
      "title": "Order Exact",
      "description": "False when sort=most_instances and counting stopped at the scan budget (counts.exact false): only the newest 300 candidate videos are ranked, by lower-bound counts, and any other videos follow them newest first, unranked. Always true for newest.",
      "default": true
    },
    "counts": {
      "$ref": "#/$defs/Counts"
    },
    "videos": {
      "items": {
        "$ref": "#/$defs/VideoResult"
      },
      "type": "array",
      "title": "Videos"
    },
    "limits": {
      "additionalProperties": {
        "type": "integer"
      },
      "type": "object",
      "title": "Limits"
    },
    "next_cursor": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Next Cursor"
    }
  },
  "type": "object",
  "required": [
    "query",
    "normalized_query",
    "counts",
    "videos",
    "limits"
  ],
  "$defs": {
    "CountPart": {
      "properties": {
        "instances": {
          "type": "integer",
          "title": "Instances"
        },
        "videos": {
          "type": "integer",
          "title": "Videos",
          "description": "Videos and official documents with at least one instance."
        },
        "exact": {
          "type": "boolean",
          "title": "Exact",
          "description": "False when counting stopped at the scan budget; the values are lower bounds."
        }
      },
      "type": "object",
      "required": [
        "instances",
        "videos",
        "exact"
      ],
      "title": "CountPart",
      "description": "One side of the playable / transcript-only split of a search's counts."
    },
    "Counts": {
      "properties": {
        "instances": {
          "type": "integer",
          "title": "Instances",
          "description": "Every instance, timed and document alike (ADR 0004). With playable_only, only instances in playable videos."
        },
        "videos": {
          "type": "integer",
          "title": "Videos",
          "description": "Videos and official documents with at least one instance."
        },
        "exact": {
          "type": "boolean",
          "title": "Exact",
          "description": "False when counting stopped at the scan budget; values are lower bounds."
        },
        "by_timing": {
          "additionalProperties": {
            "type": "integer"
          },
          "type": "object",
          "title": "By Timing",
          "description": "instances split by timing_granularity, e.g. {'word': 12, 'document': 3}. Only granularities with instances appear; the values sum to instances."
        },
        "playable": {
          "$ref": "#/$defs/CountPart",
          "description": "Results with playable video (playable true: a playback asset whose alignment is verified), for this query and filters. While exact is true, the same numbers whether or not playable_only is set. Past the scan budget (exact false) they are lower bounds, and with playable_only the results shown are counted on their own, so they can be a higher lower bound (and exact again). With playable_only they equal instances, videos and exact."
        },
        "transcript_only": {
          "$ref": "#/$defs/CountPart",
          "description": "Results with no playable video (official transcripts and records with timing_granularity 'document', and recordings whose playback is not verified), for this query and filters: the same numbers whether or not playable_only is set. With playable_only they are left out of the results and of instances and videos; without it they are included in them."
        }
      },
      "type": "object",
      "required": [
        "instances",
        "videos",
        "exact",
        "playable",
        "transcript_only"
      ],
      "title": "Counts"
    },
    "DocumentPosition": {
      "properties": {
        "paragraph": {
          "type": "integer",
          "minimum": 1.0,
          "title": "Paragraph",
          "description": "Paragraph of the transcript text, from 1. The document's heading, date line and closing note are not counted."
        },
        "word": {
          "type": "integer",
          "minimum": 1.0,
          "title": "Word",
          "description": "Word within that paragraph, from 1. Words are separated by spaces; the speaker label such as 'The President.' is not counted, a stage note such as '[Applause]' is."
        }
      },
      "type": "object",
      "required": [
        "paragraph",
        "word"
      ],
      "title": "DocumentPosition",
      "description": "Where words sit in an official document's transcript text (ADR 0004), counted from 1 as a reader counts."
    },
    "Excerpt": {
      "properties": {
        "text": {
          "type": "string",
          "title": "Text"
        },
        "match": {
          "items": {
            "$ref": "#/$defs/MatchSpan"
          },
          "type": "array",
          "title": "Match",
          "description": "Each instance's extent, from its first matched word to its last (one span per instance). For unquoted words it includes the words between them; highlight the `highlight` spans instead."
        },
        "highlight": {
          "items": {
            "$ref": "#/$defs/MatchSpan"
          },
          "type": "array",
          "title": "Highlight",
          "description": "The words that matched the query, to highlight: a quoted phrase is one span; unquoted words are one span each, joined only where they are adjacent and in the query's order. Words between them are not included. In text order; every span is inside text."
        },
        "start_ms": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "Start Ms",
          "description": "Null exactly when timing_granularity is document (no made-up times)."
        },
        "end_ms": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "End Ms",
          "description": "Null exactly when timing_granularity is document (no made-up times)."
        },
        "boundary": {
          "type": "string",
          "enum": [
            "sentence",
            "clause",
            "window"
          ],
          "title": "Boundary",
          "description": "sentence: whole sentences; clause: cut at a comma or semicolon; window: cut by word budget."
        },
        "truncated_before": {
          "type": "boolean",
          "title": "Truncated Before",
          "default": false
        },
        "truncated_after": {
          "type": "boolean",
          "title": "Truncated After",
          "default": false
        }
      },
      "type": "object",
      "required": [
        "text",
        "match",
        "start_ms",
        "end_ms",
        "boundary"
      ],
      "title": "Excerpt",
      "description": "The words around a match, cut at natural boundaries inside one speaker turn."
    },
    "Instance": {
      "properties": {
        "id": {
          "type": "string",
          "title": "Id",
          "description": "Durable citation token (gt2. timed, gd2. document: signed by GovTube; gt1./gd1. when the server has no citation key); resolve with /v1/citations/{id}."
        },
        "video_id": {
          "type": "string",
          "title": "Video Id"
        },
        "start_ms": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "Start Ms",
          "description": "Null exactly when timing_granularity is document (no made-up times)."
        },
        "end_ms": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "End Ms",
          "description": "Null exactly when timing_granularity is document (no made-up times)."
        },
        "play_from_ms": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "Play From Ms",
          "description": "Playback start including pre-roll, in playback-asset time. Null exactly when timing_granularity is document (no made-up times)."
        },
        "timing_granularity": {
          "type": "string",
          "enum": [
            "word",
            "segment",
            "sentence",
            "turn",
            "chunk",
            "document"
          ],
          "title": "Timing Granularity",
          "description": "What the timing is attached to (ORTH-177): word = every word has a time (our transcripts); document = no timing at all, the words come from an official document (ADR 0004). Times are null exactly when this is document."
        },
        "resolution_ms": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "Resolution Ms",
          "description": "Longest timed unit in milliseconds, for comparing coarse timings. Null for word (each word is timed) and for document (nothing is timed)."
        },
        "position": {
          "anyOf": [
            {
              "$ref": "#/$defs/DocumentPosition"
            },
            {
              "type": "null"
            }
          ],
          "description": "document only: where the first matched word is in the official text."
        },
        "document_url": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Document Url",
          "description": "document only: the official document, so a reader can check the words in place."
        },
        "document_highlight_url": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Document Highlight Url",
          "description": "document only: the official document opened at these words (a URL text fragment, '#:~:text=...', that browsers scroll to and highlight), when they can be pointed to unambiguously: each directive is the shortest one that matches exactly once on the page. Null otherwise, and always for timed results; document_url stays the plain link for citations."
        },
        "speaker": {
          "$ref": "#/$defs/SpeakerInfo"
        },
        "excerpt": {
          "$ref": "#/$defs/Excerpt"
        },
        "playable": {
          "type": "boolean",
          "title": "Playable",
          "description": "False when the playback asset's alignment is not verified, and always for document results (no timing, nothing to seek)."
        },
        "low_confidence": {
          "type": "boolean",
          "title": "Low Confidence",
          "description": "verification is low_confidence: the quote is on hold until reviewed (ORTH-176).",
          "default": false
        },
        "caption_check": {
          "type": "string",
          "enum": [
            "agrees",
            "differs",
            "not_checked"
          ],
          "title": "Caption Check",
          "description": "How the official live captions compare with the words a quote of this result shows: the excerpt and the whole sentence(s) around the matched words, not just the matched words (ORTH-225; HEURISTIC). differs: the captions have different words somewhere in there, so the machine transcript may have misheard them; check the video before quoting and say the transcript is unverified. agrees: the captions have the same words (captions are live stenography, not a verbatim record, so this is not a check by a person). not_checked: no caption check for this video, the captions skip some of these words, or an official transcript (no captions to compare).",
          "default": "not_checked"
        },
        "verification": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "checked",
                "unverified",
                "low_confidence"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Verification",
          "description": "Whether the words a quote of this result shows (the excerpt and the sentence(s) around the matched words, as caption_check) were checked against a second source (ORTH-176). checked: the official captions have the same words, or a reviewer checked them; no mark is shown. unverified: nothing to check them against, or the captions differ where the speech recognizer was sure of its words (the captioner's spelling or mishearing, more often than not); say 'Transcript unverified'. low_confidence: on hold until reviewed; a caption difference where the recognizer's own word score was under 0.9, or a word scored under 0.5 that the captions can't check (HEURISTIC thresholds, not yet calibrated by listening). Null for official documents (no machine transcript)."
        },
        "verification_source": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "house_captions",
                "senate_captions",
                "dvids_captions",
                "reviewer",
                "asr_word_confidence"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Verification Source",
          "description": "What checked or disputed the words: house_captions, senate_captions, dvids_captions (the official live captions), reviewer (a person, against the video) or asr_word_confidence (the recognizer's own word score; low_confidence only). Null when unverified."
        }
      },
      "type": "object",
      "required": [
        "id",
        "video_id",
        "start_ms",
        "end_ms",
        "play_from_ms",
        "timing_granularity",
        "resolution_ms",
        "speaker",
        "excerpt",
        "playable"
      ],
      "title": "Instance",
      "description": "One occurrence of the query: a spoken moment in a video, or words in an official document (untimed)."
    },
    "MatchSpan": {
      "properties": {
        "start": {
          "type": "integer",
          "title": "Start",
          "description": "Character offset into excerpt.text (inclusive)."
        },
        "end": {
          "type": "integer",
          "title": "End",
          "description": "Character offset into excerpt.text (exclusive)."
        }
      },
      "type": "object",
      "required": [
        "start",
        "end"
      ],
      "title": "MatchSpan"
    },
    "Passage": {
      "properties": {
        "excerpt": {
          "$ref": "#/$defs/Excerpt",
          "description": "The longest member excerpt. excerpt.match has one span per member, in the same order as instances; excerpt.highlight holds every member's matched words; every span is inside excerpt.text."
        },
        "start_ms": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "Start Ms",
          "description": "First member's start_ms (the row's time). Null exactly when timing_granularity is document (no made-up times)."
        },
        "end_ms": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "End Ms",
          "description": "Last member's end_ms. The row's 'to {t}' is instances[-1].start_ms. Null exactly when timing_granularity is document (no made-up times)."
        },
        "play_from_ms": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "Play From Ms",
          "description": "First member's play_from_ms. Null exactly when timing_granularity is document (no made-up times)."
        },
        "timing_granularity": {
          "type": "string",
          "enum": [
            "word",
            "segment",
            "sentence",
            "turn",
            "chunk",
            "document"
          ],
          "title": "Timing Granularity",
          "description": "What the timing is attached to (ORTH-177): word = every word has a time (our transcripts); document = no timing at all, the words come from an official document (ADR 0004). Times are null exactly when this is document."
        },
        "resolution_ms": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "Resolution Ms",
          "description": "Longest timed unit in milliseconds, for comparing coarse timings. Null for word (each word is timed) and for document (nothing is timed)."
        },
        "position": {
          "anyOf": [
            {
              "$ref": "#/$defs/DocumentPosition"
            },
            {
              "type": "null"
            }
          ],
          "description": "document only: first member's position."
        },
        "document_url": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Document Url",
          "description": "document only: the official document."
        },
        "document_highlight_url": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Document Highlight Url",
          "description": "document only: the official document opened at these words (a URL text fragment, '#:~:text=...', that browsers scroll to and highlight), when they can be pointed to unambiguously: each directive is the shortest one that matches exactly once on the page. Null otherwise, and always for timed results; document_url stays the plain link for citations. For a passage: every member that can be pointed to (at most 10)."
        },
        "instances": {
          "items": {
            "$ref": "#/$defs/PassageInstance"
          },
          "type": "array",
          "title": "Instances",
          "description": "Members in text order; at least one."
        }
      },
      "type": "object",
      "required": [
        "excerpt",
        "start_ms",
        "end_ms",
        "play_from_ms",
        "timing_granularity",
        "resolution_ms",
        "instances"
      ],
      "title": "Passage",
      "description": "Instances whose excerpts overlap, shown as one row (handoff §5.1 merging rule)."
    },
    "PassageInstance": {
      "properties": {
        "id": {
          "type": "string",
          "title": "Id",
          "description": "Durable citation token, as Instance.id."
        },
        "start_ms": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "Start Ms",
          "description": "Null exactly when timing_granularity is document (no made-up times)."
        },
        "end_ms": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "End Ms",
          "description": "Null exactly when timing_granularity is document (no made-up times)."
        },
        "play_from_ms": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "Play From Ms",
          "description": "Playback start including pre-roll, in playback-asset time. Null exactly when timing_granularity is document (no made-up times)."
        },
        "timing_granularity": {
          "type": "string",
          "enum": [
            "word",
            "segment",
            "sentence",
            "turn",
            "chunk",
            "document"
          ],
          "title": "Timing Granularity",
          "description": "What the timing is attached to (ORTH-177): word = every word has a time (our transcripts); document = no timing at all, the words come from an official document (ADR 0004). Times are null exactly when this is document."
        },
        "resolution_ms": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "Resolution Ms",
          "description": "Longest timed unit in milliseconds, for comparing coarse timings. Null for word (each word is timed) and for document (nothing is timed)."
        },
        "position": {
          "anyOf": [
            {
              "$ref": "#/$defs/DocumentPosition"
            },
            {
              "type": "null"
            }
          ],
          "description": "As Instance.position."
        },
        "speaker": {
          "$ref": "#/$defs/SpeakerInfo"
        },
        "low_confidence": {
          "type": "boolean",
          "title": "Low Confidence",
          "description": "verification is low_confidence: the quote is on hold until reviewed (ORTH-176).",
          "default": false
        },
        "caption_check": {
          "type": "string",
          "enum": [
            "agrees",
            "differs",
            "not_checked"
          ],
          "title": "Caption Check",
          "description": "How the official live captions compare with the words a quote of this result shows: the excerpt and the whole sentence(s) around the matched words, not just the matched words (ORTH-225; HEURISTIC). differs: the captions have different words somewhere in there, so the machine transcript may have misheard them; check the video before quoting and say the transcript is unverified. agrees: the captions have the same words (captions are live stenography, not a verbatim record, so this is not a check by a person). not_checked: no caption check for this video, the captions skip some of these words, or an official transcript (no captions to compare).",
          "default": "not_checked"
        },
        "verification": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "checked",
                "unverified",
                "low_confidence"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Verification",
          "description": "Whether the words a quote of this result shows (the excerpt and the sentence(s) around the matched words, as caption_check) were checked against a second source (ORTH-176). checked: the official captions have the same words, or a reviewer checked them; no mark is shown. unverified: nothing to check them against, or the captions differ where the speech recognizer was sure of its words (the captioner's spelling or mishearing, more often than not); say 'Transcript unverified'. low_confidence: on hold until reviewed; a caption difference where the recognizer's own word score was under 0.9, or a word scored under 0.5 that the captions can't check (HEURISTIC thresholds, not yet calibrated by listening). Null for official documents (no machine transcript)."
        },
        "verification_source": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "house_captions",
                "senate_captions",
                "dvids_captions",
                "reviewer",
                "asr_word_confidence"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Verification Source",
          "description": "What checked or disputed the words: house_captions, senate_captions, dvids_captions (the official live captions), reviewer (a person, against the video) or asr_word_confidence (the recognizer's own word score; low_confidence only). Null when unverified."
        },
        "playable": {
          "type": "boolean",
          "title": "Playable"
        }
      },
      "type": "object",
      "required": [
        "id",
        "start_ms",
        "end_ms",
        "play_from_ms",
        "timing_granularity",
        "resolution_ms",
        "speaker",
        "playable"
      ],
      "title": "PassageInstance",
      "description": "One instance inside a passage: what the row needs to play, cite and label it."
    },
    "PlaybackAsset": {
      "properties": {
        "kind": {
          "type": "string",
          "enum": [
            "youtube",
            "hls",
            "mp4"
          ],
          "title": "Kind"
        },
        "ref": {
          "type": "string",
          "title": "Ref",
          "description": "YouTube video ID, or an absolute URL for hls/mp4."
        },
        "offset_ms": {
          "type": "integer",
          "title": "Offset Ms",
          "description": "playback_ms = transcript_ms + offset_ms (simple maps only).",
          "default": 0
        },
        "alignment_verified": {
          "type": "boolean",
          "title": "Alignment Verified",
          "default": false
        },
        "made_for_kids": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Made For Kids",
          "description": "YouTube videos only (ORTH-150): YouTube's Made for Kids designation, as GovTube last checked it within the past 30 days. Null when unknown, never checked, or the check is older than 30 days. Embed with tracking off unless this is false."
        }
      },
      "type": "object",
      "required": [
        "kind",
        "ref"
      ],
      "title": "PlaybackAsset",
      "description": "The media a viewer actually plays.\n\n``alignment_verified`` must be true before instances are offered as playable:\nthe transcript clock and this asset's clock are only assumed equal when the\ntranscript was made from this exact asset, or a verified ``TimeMap`` links them."
    },
    "SourceChannel": {
      "properties": {
        "channel_id": {
          "type": "string",
          "title": "Channel Id",
          "description": "YouTube channel ID (UC...), which never changes."
        },
        "name": {
          "type": "string",
          "title": "Name",
          "description": "The channel's name, e.g. 'The White House'."
        },
        "url": {
          "type": "string",
          "title": "Url",
          "description": "The channel's address, by ID."
        }
      },
      "type": "object",
      "required": [
        "channel_id",
        "name",
        "url"
      ],
      "title": "SourceChannel",
      "description": "The official channel a platform video was published on (ADR 0006)."
    },
    "SpeakerInfo": {
      "properties": {
        "cluster": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Cluster",
          "description": "Speaker label, e.g. 'S0'. Null when the words have no speaker label (display_name 'No speaker label'): no voice was found there, or the document names no speaker. GovTube doesn't guess a speaker for them."
        },
        "person_id": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Person Id",
          "description": "Bioguide ID for members of Congress, when named."
        },
        "display_name": {
          "type": "string",
          "title": "Display Name",
          "description": "Official title and name, 'Reporter', 'Unconfirmed speaker', or 'No speaker label'."
        },
        "confirmed": {
          "type": "boolean",
          "title": "Confirmed",
          "description": "A person checked this name. Unchanged by match_status.",
          "default": false
        },
        "match_status": {
          "type": "string",
          "enum": [
            "unconfirmed",
            "matched_unreviewed",
            "confirmed"
          ],
          "title": "Match Status",
          "description": "unconfirmed: no name (display_name is 'Unconfirmed speaker', or a name printed in a document, which is a hint). matched_unreviewed: the name was matched from the on-screen name caption of the official video and no person has reviewed it yet; show it only with the words 'matched from on-screen name, not reviewed'. confirmed: a person checked the name (same as confirmed true). Filters (speaker, confirmed_only) count confirmed names only.",
          "default": "unconfirmed"
        },
        "match_source": {
          "items": {
            "type": "string",
            "enum": [
              "onscreen",
              "congressional_record",
              "reviewer"
            ]
          },
          "type": "array",
          "title": "Match Source",
          "description": "What the name rests on: onscreen = the official video's on-screen name caption; congressional_record = the Congressional Record for that day lists this person as speaking; reviewer = a person checked it. Empty when there is no name."
        }
      },
      "type": "object",
      "required": [
        "cluster",
        "display_name"
      ],
      "title": "SpeakerInfo",
      "description": "How a diarization cluster is shown publicly."
    },
    "VideoLink": {
      "properties": {
        "video_id": {
          "type": "string",
          "title": "Video Id",
          "description": "The linked video (house-YYYYMMDD), its own result in /v1/videos/{video_id}."
        },
        "video_rev": {
          "type": "integer",
          "minimum": 1.0,
          "title": "Video Rev",
          "description": "The video's transcript_rev the match was made against. If the video's transcript_rev is now higher, its words may have moved: treat the link as approximate until it is recomputed."
        },
        "start_ms": {
          "type": "integer",
          "minimum": 0.0,
          "title": "Start Ms",
          "description": "Where the matched words start, in the linked video's transcript time (add its playback.offset_ms for player time; open PREROLL_MS earlier)."
        },
        "end_ms": {
          "type": "integer",
          "minimum": 0.0,
          "title": "End Ms",
          "description": "Where the matched words end, in the linked video's transcript time."
        },
        "coverage": {
          "type": "number",
          "maximum": 1.0,
          "minimum": 0.0,
          "title": "Coverage",
          "description": "Share of the printed words matched to words heard in the video (MEASURED per speech by the aligner)."
        },
        "tier": {
          "type": "string",
          "enum": [
            "high",
            "standard",
            "bracketed"
          ],
          "title": "Tier",
          "description": "high: 100+ printed words and coverage at least 0.8. standard: 40+ printed words, coverage at least 0.5, at least 2 rare 5-word anchors and precision at least 0.6. bracketed: a speech under 40 words placed between two found speeches of the same Record article."
        },
        "method": {
          "type": "string",
          "const": "text_alignment",
          "title": "Method",
          "default": "text_alignment"
        }
      },
      "type": "object",
      "required": [
        "video_id",
        "video_rev",
        "start_ms",
        "end_ms",
        "coverage",
        "tier"
      ],
      "title": "VideoLink",
      "description": "ORTH-271: a Record speech's place in the House floor video, found by text match (a cross-link, not timing)."
    },
    "VideoResult": {
      "properties": {
        "video": {
          "$ref": "#/$defs/VideoSummary"
        },
        "instance_count": {
          "type": "integer",
          "title": "Instance Count",
          "description": "All instances of the query in this video."
        },
        "passage_count": {
          "type": "integer",
          "title": "Passage Count",
          "description": "All passages in this video: instances whose excerpts overlap count once. Computed server-side, so it always agrees with passage paging."
        },
        "instances": {
          "items": {
            "$ref": "#/$defs/Instance"
          },
          "type": "array",
          "title": "Instances",
          "description": "Search: the first instances in time order, up to max_instances_per_video (unchanged for existing clients). Video instance pages: every instance of the passages on this page."
        },
        "passages": {
          "items": {
            "$ref": "#/$defs/Passage"
          },
          "type": "array",
          "title": "Passages",
          "description": "Search: the first passages, up to max_instances_per_video. Video instance pages: the passages from offset, up to limit (offset and limit count passages)."
        },
        "truncated": {
          "type": "boolean",
          "title": "Truncated",
          "description": "Search: instance_count exceeds the instances returned. Video instance pages: more passages follow this page."
        }
      },
      "type": "object",
      "required": [
        "video",
        "instance_count",
        "passage_count",
        "instances",
        "passages",
        "truncated"
      ],
      "title": "VideoResult"
    },
    "VideoSummary": {
      "properties": {
        "video_id": {
          "type": "string",
          "title": "Video Id"
        },
        "title": {
          "type": "string",
          "title": "Title"
        },
        "event_date": {
          "type": "string",
          "format": "date",
          "title": "Event Date"
        },
        "source_id": {
          "type": "string",
          "title": "Source Id"
        },
        "source_url": {
          "type": "string",
          "title": "Source Url"
        },
        "playback": {
          "anyOf": [
            {
              "$ref": "#/$defs/PlaybackAsset"
            },
            {
              "type": "null"
            }
          ]
        },
        "duration_ms": {
          "anyOf": [
            {
              "type": "integer",
              "minimum": 0.0
            },
            {
              "type": "null"
            }
          ],
          "title": "Duration Ms",
          "description": "Length of the source audio in milliseconds, measured at ingest. Null for videos published before this field existed; then use the last word's end_ms as the length."
        },
        "timing_granularity": {
          "type": "string",
          "enum": [
            "word",
            "segment",
            "sentence",
            "turn",
            "chunk",
            "document"
          ],
          "title": "Timing Granularity",
          "description": "What the timing is attached to (ORTH-177): word = every word has a time (our transcripts); document = no timing at all, the words come from an official document (ADR 0004). Times are null exactly when this is document.",
          "default": "word"
        },
        "fidelity": {
          "type": "string",
          "enum": [
            "verbatim",
            "clean",
            "edited"
          ],
          "title": "Fidelity",
          "description": "verbatim: what was said, as said (our transcripts). edited: revised after the fact, e.g. a White House transcript; label it 'Official transcript · edited · no timing' and never certify it as spoken.",
          "default": "verbatim"
        },
        "source_certainty": {
          "type": "string",
          "enum": [
            "official_record",
            "official_channel",
            "unverified"
          ],
          "title": "Source Certainty",
          "description": "How sure GovTube is about the source material (ADR 0006). official_record: the official recording or record of the proceeding (House and Senate video, the Daily Compilation of Presidential Documents). official_channel: published by the office itself, e.g. on its official YouTube channel; it may be edited or excerpted and is not the complete record. unverified: not confirmed as official. Show source_caveats whenever this is not official_record or source_caveats is not empty.",
          "default": "unverified"
        },
        "source_caveats": {
          "items": {
            "type": "string"
          },
          "type": "array",
          "title": "Source Caveats",
          "description": "Plain sentences about what is uncertain in this source material, to show (and pass along) with any quote, e.g. 'Speakers are identified by machine and not reviewed.' Empty when there is nothing to add."
        },
        "source_channel": {
          "anyOf": [
            {
              "$ref": "#/$defs/SourceChannel"
            },
            {
              "type": "null"
            }
          ],
          "description": "The official YouTube channel the video was published on; null for other sources."
        },
        "record_delivery": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "not_spoken",
                "may_include_not_spoken"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Record Delivery",
          "description": "Congressional Record only (ORTH-209). not_spoken: the Record marks the statement as not delivered on the floor (the Senate's bullet); show 'Inserted in the Record · not spoken on the floor'. may_include_not_spoken: the Record can't tell spoken from inserted words here (the House marks inserted words only by typeface, which GovInfo's text doesn't keep, or a Senate speech holds a bulleted passage); show 'May include remarks not spoken on the floor'. Null for every other source, and for a Senate speech with no bullet."
        },
        "video_link": {
          "anyOf": [
            {
              "$ref": "#/$defs/VideoLink"
            },
            {
              "type": "null"
            }
          ],
          "description": "Congressional Record House speeches only (ORTH-271): where this printed speech is in the House floor video, found by matching its text against GovTube's own transcript of the video. The Record result itself stays untimed text (playable false, ADR 0004); this is a cross-link to a separate video result. Show it with the words 'Located in the House floor video by text match'. It never confirms who speaks in the video. Null when the speech wasn't found with enough confidence."
        },
        "video_delivery": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "delivered",
                "not_found"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Video Delivery",
          "description": "Congressional Record House speeches only (ORTH-271), from matching the printed words against GovTube's own transcript of that day's House floor video, and only on days whose video runs to the end of the Record (a video that goes dark early would make delivered speeches look missing). delivered: the speech was found in the video and at least 80% of its printed words were matched to words heard there; show 'Delivered on the floor (matched to video)'. not_found: a speech of 150+ printed words that matched (almost) nothing while the speeches on either side of it in the Record were found in the video; show 'Not found in the floor video (may have been inserted)'. Never read either value as 'not spoken'. Null: no such signal (most speeches, every Senate speech)."
        }
      },
      "type": "object",
      "required": [
        "video_id",
        "title",
        "event_date",
        "source_id",
        "source_url"
      ],
      "title": "VideoSummary"
    }
  }
}