Field guide

Claude Transcript Anatomy

How to read Claude JSONL transcript artifacts, hook transcript paths, subagent transcript paths, and stream-json output without mixing them up.

#

Raw artifact

JSONL under ~/.claude/projects

Anthropic documents JSONL transcript files as the default local persistence format for Agent SDK sessions.

#

Subagents

Nested transcript paths

Hook inputs distinguish the main transcript from subagent transcript paths, which matters when aggregating parallel work.

"JSONL files under ~/.claude/projects/"

The Three Records People Confuse

There are three related but different surfaces: the persisted transcript file, the live stream emitted by CLI or SDK output modes, and the JSON payloads passed to hooks or status-line commands. They can describe the same run, but they are not interchangeable.

The persisted transcript is the durable artifact. Stream output is useful for automation, CI, and live processors. Hook and status-line payloads are lifecycle snapshots: they give enough context for a command to decide what to do at that moment.

Reading JSONL Without Overfitting

JSONL means one JSON object per line. That makes transcripts append-friendly and easy to stream, but it also tempts people to write fragile parsers that assume every line has exactly the same shape. A safer parser treats each line as an event-like record, branches by known fields, preserves unknown fields, and emits warnings rather than crashing on new versions.

If you are building a converter, keep the raw line number and source file path in derived output. That one choice makes later audits easier: a reviewer can jump from a friendly Markdown section back to the exact raw record.

  • Parse with a JSONL reader, not split-based string matching.
  • Preserve unknown fields for future Claude Code versions.
  • Keep source filename, line number, session ID, timestamp if present, and parent/subagent relationships.

Model Fields Change, So Read Them

Assistant records usually carry a model string, and that string is the single most useful piece of metadata for interpreting the rest of the turn. As of September 2026 the generally available lineup is Claude Fable 5.1 (claude-fable-5-1), Claude Opus 5 (claude-opus-5), Claude Sonnet 5 (claude-sonnet-5), and Claude Haiku 4.5 (claude-haiku-4-5), alongside legacy Fable 5, Opus 4.x, and Sonnet 4.x identifiers that still appear in older transcripts.

A parser should never hardcode one model. Read the field, keep the raw string, and treat an unrecognized identifier as a new release rather than a corrupt record. A single session can also contain more than one model: Anthropic documents automatic fallbacks when safety classifiers flag a request, so the model that started a run is not guaranteed to be the model that finished it.

  • Store the raw model string per turn, not a normalized label.
  • Flag sessions where the model changes between turns and note why if the transcript explains it.
  • Map cost rows by model identifier, because input, output, and cache-read rates differ across the lineup.

Thinking Blocks Are Not Ordinary Text

Adaptive thinking is on by default across the current lineup, so transcripts can contain thinking content beside normal assistant text. Treat it as a distinct record type. It is useful for understanding a decision path during review, and it is exactly the kind of content that should be redacted before a transcript leaves the organization.

The Fable 5.1 release notes two behaviors worth designing around: earlier models cannot read its thinking blocks, and editing an earlier turn invalidates thinking for that turn. Both mean a transcript replayed or rewritten through a different model is not the same artifact as the original. If a review depends on the reasoning trail, archive the original transcript rather than a reconstructed conversation.

Hook Context Is A Lens, Not The Whole Run

Claude Code hook inputs include lifecycle context such as session ID, current working directory, and transcript path. For subagent events, Anthropic documents a separate subagent transcript path. That is enough to build audit hooks, but a hook payload is still a momentary input to the hook, not the complete transcript.

When a hook writes its own audit entry, include the hook event name and tool identifier, then store a pointer to the transcript rather than copying the entire transcript into every audit row.

Stream Output Has A Different Job

The CLI reference documents --output-format stream-json and related flags for print mode. That surface is ideal for scripts that need to consume messages as they happen. It is also where flags such as including hook events or partial messages become relevant.

Do not assume stream output and persisted transcripts are byte-for-byte mirrors. Treat stream output as an automation interface and the transcript as a persistence artifact. When exact provenance matters, store both the command invocation and the transcript pointer.

Primary sources

Sources behind this page

Anthropic

Hooks reference

Reference for hook lifecycle events, JSON input and output formats, and command, HTTP, prompt, and agent hooks.

Anthropic

CLI reference

Documents stream-json output, hook event inclusion, session persistence controls, naming, and resume flags.

Anthropic

Status line

Documents the JSON session data passed to status-line commands.

Anthropic

Claude models overview

Current model lineup and API identifiers. Used to interpret the model strings recorded in transcripts and telemetry.

Anthropic

Claude Fable 5.1 and Mythos 5.1

Announcement for the September 2026 flagship release, including cheaper cache reads, default effort levels, and thinking-block behavior changes that affect transcript reading.

Cite this page

Claude Logs. "Claude Transcript Anatomy." claudelogs.com, updated 2026-09-20. https://claudelogs.com/transcript-anatomy

FAQ

Should a transcript parser drop fields it does not understand?

No. Preserve unknown fields or at least keep the raw record. Claude Code changes over time, and a lossy converter can erase evidence before a reviewer knows it matters.

Is stream-json enough for an audit archive?

Usually not by itself. It is a useful live interface, but an archive should retain raw transcripts, run metadata, and final repository evidence.

Which model names should I expect in a September 2026 transcript?

Claude Fable 5.1, Claude Opus 5, Claude Sonnet 5, and Claude Haiku 4.5 are the generally available lineup, with legacy Fable 5, Opus 4.x, and Sonnet 4.x identifiers still present in older files. Read the model field rather than assuming one model per session.

Related evidence