# Session Management > Understanding how the Claude Agent SDK handles sessions and session resumption ## Session Management The Claude Agent SDK provides session management capabilities for handling conversation state and resumption. Sessions allow you to continue conversations across multiple interactions while maintaining full context. ## How Sessions Work When you start a new query, the SDK automatically creates a session and returns a session ID in the initial system message. You can capture this ID to resume the session later. ### Getting the Session ID options: { options: { model: "claude-sonnet-4-5" } }) for await (const message of response) { // The first message is a system init message with the session ID ```python if (message.type === 'system' && message.subtype === 'init') { if (message.type === 'system' && message.subtype === 'init') { sessionId = message.session_id console.log(`Session started with ID: ${sessionId}`) // You can save this ID for later resumption } ``` // Process other messages... // Process other messages... console.log(message) } // Later, you can use the saved sessionId to resume if (sessionId) { const resumedResponse = query({ ```python prompt: "Continue where we left off", options: { resume: sessionId } }) } ``` ```python Python theme={null} from claude_agent_sdk import query, ClaudeAgentOptions session_id = None async for message in query( prompt="Help me build a web application", ``` ```python options=ClaudeAgentOptions( options=ClaudeAgentOptions( model="claude-sonnet-4-5" ) ): ## The first message is a system init message with the session ID ``` ```python if hasattr(message, 'subtype') and message.subtype == 'init': if hasattr(message, 'subtype') and message.subtype == 'init': session_id = message.data.get('session_id') print(f"Session started with ID: {session_id}") # You can save this ID for later resumption ``` ## Process other messages... # Process other messages print(message) ## Later, you can use the saved session_id to resume if session_id: async for message in query( ```python prompt="Continue where we left off", prompt="Continue where we left off", options=ClaudeAgentOptions( resume=session_id ) ): print(message) ``` ## Resuming Sessions The SDK supports resuming sessions from previous conversation states, enabling continuous development workflows. Use the `resume` option with a session ID to continue a previous conversation. options: { options: { resume: "session-xyz", // Session ID from previous conversation model: "claude-sonnet-4-5", allowedTools: ["Read", "Edit", "Write", "Glob", "Grep", "Bash"] } }) // The conversation continues with full context from the previous session for await (const message of response) { console.log(message) } ``` ```python Python theme={null} from claude_agent_sdk import query, ClaudeAgentOptions ## Resume a previous session using its ID async for message in query( prompt="Continue implementing the authentication system from where we left off", ``` ```python options=ClaudeAgentOptions( options=ClaudeAgentOptions( resume="session-xyz", # Session ID from previous conversation model="claude-sonnet-4-5", allowed_tools=["Read", "Edit", "Write", "Glob", "Grep", "Bash"] ) ): print(message) ## The conversation continues with full context from the previous session ``` The SDK automatically handles loading the conversation history and context when you resume a session, allowing Claude to continue exactly where it left off. ## Forking Sessions When resuming a session, you can choose to either continue the original session or fork it into a new branch. By default, resuming continues the original session. Use the `forkSession` option (TypeScript) or `fork_session` option (Python) to create a new session ID that starts from the resumed state. ### When to Fork a Session Forking is useful when you want to: * Explore different approaches from the same starting point * Create multiple conversation branches without modifying the original * Test changes without affecting the original session history * Maintain separate conversation paths for different experiments ### Forking vs Continuing | Behavior | `forkSession: false` (default) | `forkSession: true` | | -------------------- | ------------------------------ | ------------------------------------ | | **Session ID** | Same as original | New session ID generated | | **History** | Appends to original session | Creates new branch from resume point | | **Original Session** | Modified | Preserved unchanged | | **Use Case** | Continue linear conversation | Branch to explore alternatives | ### Example: Forking a Session options: { model: "claude-sonnet-4-5" } options: { model: "claude-sonnet-4-5" } }) for await (const message of response) { if (message.type === 'system' && message.subtype === 'init') { ```python sessionId = message.session_id sessionId = message.session_id console.log(`Original session: ${sessionId}`) } // Fork the session to try a different approach const forkedResponse = query({ prompt: "Now let's redesign this as a GraphQL API instead", ```python options: { options: { resume: sessionId, forkSession: true, // Creates a new session ID model: "claude-sonnet-4-5" } }) for await (const message of forkedResponse) { if (message.type === 'system' && message.subtype === 'init') { ```python console.log(`Forked session: ${message.session_id}`) console.log(`Forked session: ${message.session_id}`) // This will be a different session ID } // The original session remains unchanged and can still be resumed const originalContinued = query({ prompt: "Add authentication to the REST API", ```python options: { options: { resume: sessionId, forkSession: false, // Continue original session (default) model: "claude-sonnet-4-5" } }) ``` ```python Python theme={null} from claude_agent_sdk import query, ClaudeAgentOptions ## First, capture the session ID session_id = None async for message in query( prompt="Help me design a REST API", ```python options=ClaudeAgentOptions(model="claude-sonnet-4-5") options=ClaudeAgentOptions(model="claude-sonnet-4-5") ): if hasattr(message, 'subtype') and message.subtype == 'init': ```python session_id = message.data.get('session_id') session_id = message.data.get('session_id') print(f"Original session: {session_id}") ## Fork the session to try a different approach async for message in query( prompt="Now let's redesign this as a GraphQL API instead", ```python options=ClaudeAgentOptions( options=ClaudeAgentOptions( resume=session_id, fork_session=True, # Creates a new session ID model="claude-sonnet-4-5" ) ): if hasattr(message, 'subtype') and message.subtype == 'init': ```python forked_id = message.data.get('session_id') forked_id = message.data.get('session_id') print(f"Forked session: {forked_id}") ## This will be a different session ID ## The original session remains unchanged and can still be resumed async for message in query( prompt="Add authentication to the REST API", ```python options=ClaudeAgentOptions( options=ClaudeAgentOptions( resume=session_id, fork_session=False, # Continue original session (default) model="claude-sonnet-4-5" ) ): print(message) ```