Skip to main content
Claude Code persists every conversation as a session — a JSONL transcript stored on disk under ~/.claude/projects/. The session API lets you programmatically create multi-turn conversations, read transcripts, rename or tag sessions, and fork sessions into independent branches.
The unstable_v2_* functions are alpha APIs. Their signatures may change in minor or patch releases. Pin to an exact version when using them in production.

unstable_v2_createSession()

Creates a new persistent session for multi-turn conversations.
function unstable_v2_createSession(options: SDKSessionOptions): SDKSession
options
SDKSessionOptions
required
Session configuration.
Returns an SDKSession object with a prompt() method for sending turns and a sessionId property.

unstable_v2_resumeSession()

Resumes an existing session by its UUID, continuing the conversation from where it left off.
function unstable_v2_resumeSession(
  sessionId: string,
  options: SDKSessionOptions,
): SDKSession
sessionId
string
required
UUID of the session to resume. Obtain session IDs from listSessions() or from the session_id field in a previous result message.
options
SDKSessionOptions
required
Session configuration. See unstable_v2_createSession() for field details.

unstable_v2_prompt()

One-shot convenience function — creates a session, sends a single prompt, awaits the result, and returns the SDKResultMessage.
async function unstable_v2_prompt(
  message: string,
  options: SDKSessionOptions,
): Promise<SDKResultMessage>
message
string
required
The user prompt to send.
options
SDKSessionOptions
required
Session configuration.
Returns: Promise<SDKResultMessage> — the terminal result message from the agent loop.
const result = await unstable_v2_prompt('What files are here?', {
  model: 'claude-sonnet-4-6',
  cwd: '/path/to/project',
})
console.log(result.result) // final text response

listSessions()

Lists sessions with metadata. Returns sessions sorted by lastModified descending.
async function listSessions(
  options?: ListSessionsOptions,
): Promise<SDKSessionInfo[]>
options
ListSessionsOptions
Filtering and pagination options.
Returns: Promise<SDKSessionInfo[]>
sessionId
string
Unique session identifier (UUID).
summary
string
Display title: custom title, auto-generated summary, or first prompt.
lastModified
number
Last modified time in milliseconds since epoch.
fileSize
number
File size in bytes (only populated for local JSONL storage).
customTitle
string
User-set session title (set via /rename).
firstPrompt
string
First meaningful user prompt in the session.
gitBranch
string
Git branch at the end of the session.
cwd
string
Working directory for the session.
tag
string
User-set session tag.
createdAt
number
Creation time in milliseconds since epoch.

getSessionInfo()

Reads metadata for a single session without scanning all project sessions. Returns undefined if the session is not found, is a sidechain session, or has no extractable summary.
async function getSessionInfo(
  sessionId: string,
  options?: GetSessionInfoOptions,
): Promise<SDKSessionInfo | undefined>
sessionId
string
required
UUID of the session.
options
GetSessionInfoOptions

getSessionMessages()

Reads the conversation messages from a session’s JSONL transcript file. Parses the transcript, builds the conversation chain via parentUuid links, and returns user/assistant messages in chronological order.
async function getSessionMessages(
  sessionId: string,
  options?: GetSessionMessagesOptions,
): Promise<SessionMessage[]>
sessionId
string
required
UUID of the session to read.
options
GetSessionMessagesOptions
Returns: Promise<SessionMessage[]> — array of messages, or an empty array if the session is not found.

renameSession()

Appends a custom title entry to the session’s JSONL file.
async function renameSession(
  sessionId: string,
  title: string,
  options?: SessionMutationOptions,
): Promise<void>
sessionId
string
required
UUID of the session.
title
string
required
New title for the session.
options
SessionMutationOptions

tagSession()

Sets or clears a tag on a session. Pass null to clear an existing tag.
async function tagSession(
  sessionId: string,
  tag: string | null,
  options?: SessionMutationOptions,
): Promise<void>
sessionId
string
required
UUID of the session.
tag
string | null
required
Tag string to set, or null to clear the tag.
options
SessionMutationOptions
See renameSession() for field details.

forkSession()

Forks a session into a new branch with fresh UUIDs. Copies transcript messages from the source session, remapping every message UUID while preserving the parentUuid chain. Supports branching from a specific point in the conversation.
Forked sessions start without undo history — file-history snapshots from the source are not copied.
async function forkSession(
  sessionId: string,
  options?: ForkSessionOptions,
): Promise<ForkSessionResult>
sessionId
string
required
UUID of the source session to fork.
options
ForkSessionOptions
Returns: Promise<ForkSessionResult>
sessionId
string
UUID of the newly created forked session.

Complete example

import {
  unstable_v2_createSession,
  listSessions,
  getSessionMessages,
  renameSession,
  tagSession,
  forkSession,
} from '@anthropic-ai/claude-code'

async function sessionLifecycleDemo() {
  // 1. Create a persistent session
  const session = unstable_v2_createSession({
    model: 'claude-opus-4-5',
    cwd: '/path/to/project',
    maxTurns: 10,
    allowedTools: ['Bash', 'Read'],
  })

  console.log('Session ID:', session.sessionId)

  // 2. Send a first turn
  const stream1 = session.prompt('List the top-level files in this directory.')
  for await (const message of stream1) {
    if (message.type === 'assistant') {
      for (const block of message.message.content) {
        if (block.type === 'text') process.stdout.write(block.text)
      }
    }
  }

  // 3. Send a second turn (conversation continues)
  const stream2 = session.prompt('Now count how many TypeScript files there are.')
  for await (const message of stream2) {
    if (message.type === 'result') {
      console.log('\nResult:', message.result)
    }
  }

  // 4. Rename and tag the session
  await renameSession(session.sessionId, 'TS file audit')
  await tagSession(session.sessionId, 'audit')

  // 5. List sessions for this project
  const sessions = await listSessions({ dir: '/path/to/project', limit: 10 })
  console.log('Recent sessions:', sessions.map(s => s.summary))

  // 6. Read the conversation transcript
  const messages = await getSessionMessages(session.sessionId)
  console.log(`Loaded ${messages.length} messages`)

  // 7. Fork from the first turn to explore a different path
  const firstTurnMessages = await getSessionMessages(session.sessionId)
  const firstAssistantMessage = firstTurnMessages.find(m => m.type === 'assistant')

  if (firstAssistantMessage) {
    const fork = await forkSession(session.sessionId, {
      upToMessageId: firstAssistantMessage.uuid,
      title: 'Alternative analysis',
    })
    console.log('Forked session ID:', fork.sessionId)
  }
}

sessionLifecycleDemo().catch(console.error)