How precise are the timestamps in SageTube citations?
· by SageTube Team · grounding, citations, timestamps, product
A SageTube citation deep-links to within a few seconds of the moment it quotes. Each cited passage stores the start time of the timed caption segment its first words fall in, and across the 100 most recently indexed timed transcripts those segments average 2.6 seconds long (26,610 segments measured) — so clicking a citation typically drops you a breath before the sentence you’re verifying. The comparison that matters isn’t seconds versus seconds, though: tools that ingest a video as plain transcript text, NotebookLM among them, cite into the text — there’s no seek position to hand the player at all.
This post walks through where the number comes from, what can degrade it, and how we monitor it in production. It’s a close-up on one part of the grounding model described in Citations, Timestamps, and Trust.
Where does a citation timestamp come from?
Three things line up at indexing time.
First, the transcript keeps its timing. When a video has YouTube captions, SageTube stores the timed segments — [{text, start, duration}, ...] — alongside the transcript text (app/Services/TimedTranscriptBackfiller.php:12). A validation guard checks that fetched segments actually match the stored transcript before they’re accepted, so a stale refetch can’t attach the wrong timing to a video (app/Services/TimedTranscriptBackfiller.php:87).
Second, every indexed passage knows its position in the transcript. The chunker records each passage’s exact character range, and a mapper resolves the passage’s start offset to the start time of the timed segment covering it (app/Services/TranscriptTimestampMapper.php:11). That start and end time are written into the passage’s stored metadata (app/Services/ChunkManager.php:313).
Third, answers carry the number through to the player. When SageTube composes an answer, each citation resolves its passage’s stored start time into a timestampSeconds field (app/Services/ExpertAnswerService.php:607), and the answer view renders it as a YouTube deep link — watch?v=…&t=<seconds>s — that opens the video at that second (resources/views/partials/chat/expert-answer.blade.php:141).
The important property: the timestamp is computed once, at indexing time, from the captions themselves. It is not estimated by a language model at answer time.
How precise is “precise”?
The precision floor is the caption segment. A citation’s timestamp is the start of the segment containing the passage’s first words, so the worst-case gap between the deep link and the exact word is roughly one segment length.
We measured it on our own index rather than assuming: across the 100 most recently indexed transcripts that carry timing, the 26,610 caption segments average 2.6 seconds each. In practice that means the video opens a moment before the cited sentence starts — close enough that verification is “listen for two seconds,” not “scrub around and hunt.”
What can knock a timestamp off target?
Caption text and stored transcript text drift — punctuation gets restored, filler tokens like [Music] appear in one and not the other. The mapper works in normalized text space and searches forward with bounded fallbacks to stay aligned despite that drift (app/Services/TranscriptTimestampMapper.php:27).
One failure mode is worth being candid about because we shipped it: a short fallback match once jumped 6,268 characters ahead on a common phrase, pinning a long stretch of one production video’s passages to a single wrong timestamp. The fix bounds any forward jump to 600 normalized characters — beyond that, the mapper clamps to its current position instead of trusting the match (app/Services/TranscriptTimestampMapper.php:70).
The other honest limit: videos with no captions at all take the audio-transcription path, and those transcripts currently carry no per-segment timing. Their citations name the video and channel but can’t seek the player. As of July 2026, 4,893 transcripts in the index carry timed segments.
How do we know the precision holds in production?
Two scheduled checks run every six hours against the live database.
One measures coverage: among recent video transcripts that have timed segments, the fraction whose passages actually received timestamps — a drop means the mapper regressed or a backfill didn’t run (app/Services/Qa/Tests/Infrastructure/CitationTimestampCoverageTest.php:14). The other catches degenerate output that coverage alone would miss: a passage spanning 1,000+ characters whose start and end timestamps are identical is a collapsed mapping, not a real position, and it gets flagged (app/Services/Qa/Tests/Infrastructure/ChunkTimestampFlatnessTest.php:15).
A citation system that silently degrades is worse than none, because it keeps collecting trust it no longer earns. These checks exist so a mapping regression pages us before it teaches users to stop clicking.
How does NotebookLM handle YouTube timestamps?
Google’s documentation states that for YouTube sources, “only the text transcript of the video is imported” into NotebookLM, and that captions (uploaded or auto-generated) must exist for import to work. NotebookLM’s inline citations then point into that transcript text. That’s genuine grounding — you can read the supporting passage — but the pointer stays in text space: verifying against the actual video means finding the moment yourself.
That’s a reasonable design for a general research notebook that treats a video as one more document. SageTube is built for the video-first case, where the artifact you trust is the person saying the thing on camera — so the citation has to end at the player, seeked to the moment. For more on why passage-level pointers beat document-level ones, see How RAG citations differ from web-search citations, or try a live Expert on sagetube.ai/explore.
Sources
- Add or discover new sources for your notebook — NotebookLM Help (YouTube sources: caption requirement; “only the text transcript of the video is imported”)
Every product claim in this post is tied to the SageTube codebase as of July 2026: timed-segment storage and validation (app/Services/TimedTranscriptBackfiller.php:12, 87), offset-to-time mapping and its bounded-jump guard (app/Services/TranscriptTimestampMapper.php:11, 27, 70), timestamp metadata on passages (app/Services/ChunkManager.php:313), per-citation timestamp resolution (app/Services/ExpertAnswerService.php:607), the player deep link (resources/views/partials/chat/expert-answer.blade.php:141), and the six-hourly production checks (app/Services/Qa/Tests/Infrastructure/CitationTimestampCoverageTest.php:14, ChunkTimestampFlatnessTest.php:15). The 2.6-second average segment length (26,610 segments, 100 most recent timed transcripts) and the 4,893-transcript timing count were queried from the production database on 2026-07-28.
Frequently asked questions
- How accurate are SageTube's citation timestamps?
- A citation's timestamp is the start time of the timed caption segment that contains the cited passage's first words. Across the 100 most recently indexed timed transcripts, those segments average 2.6 seconds long — so the deep link typically lands within a couple of seconds of the exact moment the quoted words are spoken.
- Where do the timestamps come from?
- From YouTube's own timed captions. SageTube stores each transcript's timed segments, records the character range of every indexed passage, and maps the passage's start offset to the covering segment's start time at indexing time. The timestamp is stored with the passage, not guessed at answer time.
- Do all videos get precise timestamps?
- No. Videos with no captions are transcribed from audio, and those transcripts currently don't carry per-segment timing, so their citations name the video without a seek position. As of July 2026, 4,893 transcripts in the SageTube index carry timed segments.
- How is this different from NotebookLM's YouTube citations?
- Per Google's documentation, NotebookLM imports only the text transcript of a YouTube video as a source, and its citations point into that transcript text. SageTube's citations carry a seconds-level seek position and open the YouTube player at that moment.