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
Persist sessions to external storage
Documents default JSONL transcript storage under ~/.claude/projects/ and the SessionStore mirroring interface.
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
Telemetry
Observability
A practical map of Claude Code and Agent SDK telemetry: traces, metrics, logs, identity attributes, and event analysis.
Controls
Hook Audits
How Claude Code hooks create reliable capture points for prompts, tool calls, stop events, subagents, and policy decisions.
Governance
Storage
How to design Claude transcript storage, SessionStore mirroring, retention windows, and deletion workflows without losing useful evidence.
Free tool
Log Viewer
Drop a Claude Code JSONL transcript and turn it into a readable local timeline of messages, tool calls, tool results, and token fields.
Free tool
Token Analyzer
Estimate Claude Code transcript token usage and cost by turn with a dated model pricing table and CSV export.
Free tool
Audit Checklist
Run an interactive agent-session audit checklist and export a concise Markdown note for PRs, incidents, and handoffs.