# Claude Code Schema

**Source**: [anthropics/claude-code](https://github.com/anthropics/claude-code)

**Note**: The Claude Code repository is primarily documentation and plugins. No official public schema definitions are available. This schema is derived from observed session files and live session analysis.

**File Location**: `~/.claude/projects/{path-encoded-dir}/{session-id}.jsonl`

**Format**: JSONL (one JSON object per line)

**Path Encoding**: `/Users/bob/project` becomes `-Users-bob-project`

## Line Types

Each line has a `type` field indicating the message type:

| Type | Category | Description |
|------|----------|-------------|
| `user` | Conversation | User input or tool results |
| `assistant` | Conversation | Assistant response with tool calls |
| `result` | Conversation | Tool result (separate from user message) |
| `progress` | Observability | Hook/tool execution progress |
| `system` | Observability | System events (turn duration, hook summaries) |
| `queue-operation` | Observability | Background task notifications |
| `file-history-snapshot` | Observability | Git file snapshots |
| `summary` | Observability | Session summary |

## Common Fields

All lines share these base fields:

```typescript
interface BaseLine {
  type: string;
  timestamp: string;               // ISO timestamp
  uuid: string;                    // Unique message ID
  parentUuid: string | null;       // Parent message ID (threading)
  sessionId: string;
  cwd: string;                     // Working directory
  version: string;                 // CLI version, e.g., "2.1.31"
  gitBranch?: string;
  slug?: string;                   // Session slug (human-readable)
  isSidechain?: boolean;
  userType?: string;               // e.g., "external"
}
```

## User Message

```typescript
interface UserLine extends BaseLine {
  type: 'user';
  message: {
    role: 'user';
    content: string | ContentBlock[];
  };
  thinkingMetadata?: {
    maxThinkingTokens: number;
    level?: string;
    disabled?: boolean;
  };
  toolUseResult?: {               // Present when message contains tool result
    stdout: string;
    stderr: string;
    interrupted: boolean;
    durationMs: number;
    structuredPatch?: unknown;
  };
  todos?: unknown[];
  permissionMode?: string;         // e.g., "acceptEdits"
  imagePasteIds?: string[];
}

// Content can be string or array of blocks (for tool results)
type ContentBlock =
  | { type: 'text'; text: string }
  | { type: 'tool_result'; tool_use_id: string; content: string | ContentPart[] };

type ContentPart = { type: 'text'; text: string };
```

## Assistant Message

```typescript
interface AssistantLine extends BaseLine {
  type: 'assistant';
  requestId: string;
  message: {
    role: 'assistant';
    model: string;                 // e.g., "claude-sonnet-4-5-20250929"
    id: string;                    // Message ID (e.g., "msg_01QbK2yT...")
    type: 'message';
    content: AssistantContentBlock[];
    usage: Usage;
    stop_reason: string | null;    // e.g., "end_turn", "tool_use"
    stop_sequence: string | null;
  };
}

type AssistantContentBlock =
  | { type: 'text'; text: string }
  | { type: 'thinking'; thinking: string; signature: string }
  | { type: 'tool_use'; id: string; name: string; input: Record<string, unknown> };

interface Usage {
  input_tokens: number;
  output_tokens: number;
  cache_read_input_tokens: number;
  cache_creation_input_tokens: number;
  cache_creation?: {
    ephemeral_5m_input_tokens: number;
    ephemeral_1h_input_tokens: number;
  };
  service_tier?: string;
  server_tool_use?: {
    web_search_requests: number;
    web_fetch_requests: number;
  };
}
```

## Result Message

Tool results that arrive separately from user messages:

```typescript
interface ResultLine extends BaseLine {
  type: 'result';
  message: {
    role: 'user';
    content: ToolResultBlock[];
  };
}

interface ToolResultBlock {
  type: 'tool_result';
  tool_use_id: string;
  content: string;
  is_error?: boolean;
}
```

## Progress Message

Hook and tool execution progress:

```typescript
interface ProgressLine extends BaseLine {
  type: 'progress';
  data: ProgressData;
  parentToolUseID?: string;
  toolUseID?: string;
}

type ProgressData =
  | {
      type: 'hook_progress';
      hookEvent: string;           // e.g., "PostToolUse"
      hookName: string;            // e.g., "PostToolUse:Write"
      command: string;
    }
  | {
      type: 'bash_progress';
      stdout: string;
      stderr: string;
    };
```

## System Message

System events and metadata:

```typescript
interface SystemLine extends BaseLine {
  type: 'system';
  subtype: string;
  toolUseID?: string;
  isMeta?: boolean;
}

// Subtypes:
// - 'turn_duration': Turn timing info
interface TurnDurationSystem extends SystemLine {
  subtype: 'turn_duration';
  durationMs: number;
}

// - 'stop_hook_summary': Hook execution summary
interface StopHookSummarySystem extends SystemLine {
  subtype: 'stop_hook_summary';
  hookCount: number;
  hookInfos: Array<{ command: string }>;
  hookErrors: string[];
  preventedContinuation: boolean;
  stopReason: string;
  hasOutput: boolean;
  level: string;                   // e.g., "suggestion"
}

// - 'local_command': Local command execution
interface LocalCommandSystem extends SystemLine {
  subtype: 'local_command';
  command: string;
  output: string;
}
```

## Queue Operation

Background task notifications:

```typescript
interface QueueOperationLine {
  type: 'queue-operation';
  timestamp: string;
  sessionId: string;
  operation: string;               // e.g., "enqueue"
  content: string;                 // XML-like task notification
}

// Content format (XML in string):
// <task-notification>
//   <task-id>abc123</task-id>
//   <output-file>/tmp/tasks/abc123.output</output-file>
//   <status>running|failed|completed</status>
//   <summary>Task description</summary>
// </task-notification>
```

## File History Snapshot

Git file snapshots:

```typescript
interface FileHistorySnapshotLine extends BaseLine {
  type: 'file-history-snapshot';
  files?: Array<{
    path: string;
    content: string;
    hash: string;
  }>;
}
```

## Summary

Session summary:

```typescript
interface SummaryLine extends BaseLine {
  type: 'summary';
  summary: string;
  leafUuid: string;                // Last message UUID
  isMeta: boolean;
}
```

## Thinking Content

Claude Code supports extended thinking with signatures for verification:

```typescript
interface ThinkingBlock {
  type: 'thinking';
  thinking: string;                // Plaintext reasoning
  signature: string;               // Cryptographic signature (base64)
}
```

The `signature` field validates the thinking content's authenticity.

## Example Session

```jsonl
{"type": "user", "message": {"role": "user", "content": "Build a blog app"}, "timestamp": "2026-02-04T10:00:00.000Z", "uuid": "user-001", "parentUuid": null, "sessionId": "abc123", "cwd": "/project", "version": "2.1.31", "thinkingMetadata": {"maxThinkingTokens": 31999}}
{"type": "assistant", "message": {"role": "assistant", "model": "claude-sonnet-4-5-20250929", "id": "msg_001", "type": "message", "content": [{"type": "thinking", "thinking": "Planning the app structure...", "signature": "EtAC..."}, {"type": "text", "text": "I'll create a Flask blog app."}, {"type": "tool_use", "id": "tool-001", "name": "Write", "input": {"file_path": "app.py", "content": "..."}}], "usage": {"input_tokens": 1500, "output_tokens": 200, "cache_read_input_tokens": 1000}, "stop_reason": "tool_use"}, "timestamp": "2026-02-04T10:00:05.000Z", "uuid": "asst-001", "parentUuid": "user-001", "sessionId": "abc123", "requestId": "req_001"}
{"type": "progress", "data": {"type": "hook_progress", "hookEvent": "PostToolUse", "hookName": "PostToolUse:Write", "command": "callback"}, "timestamp": "2026-02-04T10:00:06.000Z", "uuid": "prog-001", "toolUseID": "tool-001", "sessionId": "abc123"}
{"type": "user", "message": {"role": "user", "content": [{"type": "tool_result", "tool_use_id": "tool-001", "content": "File written successfully"}]}, "timestamp": "2026-02-04T10:00:07.000Z", "uuid": "user-002", "parentUuid": "asst-001", "sessionId": "abc123"}
{"type": "system", "subtype": "turn_duration", "durationMs": 7000, "timestamp": "2026-02-04T10:00:07.000Z", "uuid": "sys-001", "sessionId": "abc123"}
{"type": "summary", "summary": "Created Flask blog app with app.py", "leafUuid": "user-002", "isMeta": true, "timestamp": "2026-02-04T10:00:08.000Z", "uuid": "sum-001", "sessionId": "abc123"}
```

## Schema Comparison: Observed vs QC Trace Implementation

### Covered Types (Our v1 Implementation)

| Observed Type | Our Implementation | Status |
|---------------|-------------------|--------|
| `user` | `ClaudeUserMessage` | Covered |
| `assistant` | `ClaudeAssistantMessage` | Covered |
| `result` | Transformed to `tool_result` | Covered |
| `progress` | `ProgressData` in unified | Covered |
| `system` | `SystemEventData` in unified | Covered |
| `queue-operation` | `QueueOperationData` in unified | Covered |
| `file-history-snapshot` | Captured as `file_snapshot` | Covered |
| `summary` | Captured as `summary` | Covered |

### Content Block Types

| Block Type | Status |
|------------|--------|
| `text` | Covered |
| `thinking` | Covered (with signature) |
| `tool_use` | Covered |
| `tool_result` | Covered |

### Usage Fields

| Field | Status |
|-------|--------|
| `input_tokens` | Covered |
| `output_tokens` | Covered |
| `cache_read_input_tokens` | Covered |
| `cache_creation_input_tokens` | Covered |
| `cache_creation` (nested) | Not captured |
| `service_tier` | Not captured |
| `server_tool_use` | Not captured |

### System Subtypes

| Subtype | Status |
|---------|--------|
| `turn_duration` | Captured |
| `stop_hook_summary` | Captured |
| `local_command` | Captured |

## Schema Version

- **Version**: v1 (frozen 2026-02-04)
- **CLI Version**: 2.1.31+
- **Source**: Session file analysis (no official schema available)

## Notes

- Path-encoded directory: `/Users/bob/project` becomes `-Users-bob-project`
- Session ID is a UUID, used as the filename
- Tool results can appear in `user` messages (inline) or `result` messages (separate)
- Thinking content includes a signature for verification
- Progress events track hook executions in real-time
- System events provide observability data (timing, hooks, commands)
- No official public schema - derived from live session analysis
