Try the new V2 interface (preview): A simplified interface with
send() and stream() patterns is now available, making multi-turn conversations easier. Learn more about the TypeScript V2 previewInstallation
Functions
query()
The primary function for interacting with Claude Code. Creates an async generator that streams messages as they arrive.
Parameters
| Parameter | Type | Description |
|---|---|---|
prompt | string | AsyncIterable<SDKUserMessage> | The input prompt as a string or async iterable for streaming mode |
options | Options | Optional configuration object (see Options type below) |
Returns
Returns aQuery object that extends AsyncGenerator<SDKMessage, void> with additional methods.
tool()
Creates a type-safe MCP tool definition for use with SDK MCP servers.
Parameters
| Parameter | Type | Description |
|---|---|---|
name | string | The name of the tool |
description | string | A description of what the tool does |
inputSchema | Schema extends AnyZodRawShape | Zod schema defining the tool’s input parameters (supports both Zod 3 and Zod 4) |
handler | (args, extra) => Promise<CallToolResult> | Async function that executes the tool logic |
extras | { annotations?: ToolAnnotations } | Optional MCP tool annotations providing behavioral hints to clients |
ToolAnnotations
Re-exported from @modelcontextprotocol/sdk/types.js. All fields are optional hints; clients should not rely on them for security decisions.
| Field | Type | Default | Description |
|---|---|---|---|
title | string | undefined | Human-readable title for the tool |
readOnlyHint | boolean | false | If true, the tool does not modify its environment |
destructiveHint | boolean | true | If true, the tool may perform destructive updates (only meaningful when readOnlyHint is false) |
idempotentHint | boolean | false | If true, repeated calls with the same arguments have no additional effect (only meaningful when readOnlyHint is false) |
openWorldHint | boolean | true | If true, the tool interacts with external entities (for example, web search). If false, the tool’s domain is closed (for example, a memory tool) |
createSdkMcpServer()
Creates an MCP server instance that runs in the same process as your application.
Parameters
| Parameter | Type | Description |
|---|---|---|
options.name | string | The name of the MCP server |
options.version | string | Optional version string |
options.tools | Array<SdkMcpToolDefinition> | Array of tool definitions created with tool() |
listSessions()
Discovers and lists past sessions with light metadata. Filter by project directory or list sessions across all projects.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
options.dir | string | undefined | Directory to list sessions for. When omitted, returns sessions across all projects |
options.limit | number | undefined | Maximum number of sessions to return |
options.includeWorktrees | boolean | true | When dir is inside a git repository, include sessions from all worktree paths |
Return type: SDKSessionInfo
| Property | Type | Description |
|---|---|---|
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 | undefined | Session file size in bytes. Only populated for local JSONL storage |
customTitle | string | undefined | User-set session title (via /rename) |
firstPrompt | string | undefined | First meaningful user prompt in the session |
gitBranch | string | undefined | Git branch at the end of the session |
cwd | string | undefined | Working directory for the session |
tag | string | undefined | User-set session tag (see tagSession()) |
createdAt | number | undefined | Creation time in milliseconds since epoch, from the first entry’s timestamp |
Example
Print the 10 most recent sessions for a project. Results are sorted bylastModified descending, so the first item is the newest. Omit dir to search across all projects.
getSessionMessages()
Reads user and assistant messages from a past session transcript.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
sessionId | string | required | Session UUID to read (see listSessions()) |
options.dir | string | undefined | Project directory to find the session in. When omitted, searches all projects |
options.limit | number | undefined | Maximum number of messages to return |
options.offset | number | undefined | Number of messages to skip from the start |
Return type: SessionMessage
| Property | Type | Description |
|---|---|---|
type | "user" | "assistant" | Message role |
uuid | string | Unique message identifier |
session_id | string | Session this message belongs to |
message | unknown | Raw message payload from the transcript |
parent_tool_use_id | null | Reserved |
Example
getSessionInfo()
Reads metadata for a single session by ID without scanning the full project directory.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
sessionId | string | required | UUID of the session to look up |
options.dir | string | undefined | Project directory path. When omitted, searches all project directories |
SDKSessionInfo, or undefined if the session is not found.
renameSession()
Renames a session by appending a custom-title entry. Repeated calls are safe; the most recent title wins.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
sessionId | string | required | UUID of the session to rename |
title | string | required | New title. Must be non-empty after trimming whitespace |
options.dir | string | undefined | Project directory path. When omitted, searches all project directories |
tagSession()
Tags a session. Pass null to clear the tag. Repeated calls are safe; the most recent tag wins.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
sessionId | string | required | UUID of the session to tag |
tag | string | null | required | Tag string, or null to clear |
options.dir | string | undefined | Project directory path. When omitted, searches all project directories |
Types
Options
Configuration object for the query() function.
| Property | Type | Default | Description |
|---|---|---|---|
abortController | AbortController | new AbortController() | Controller for cancelling operations |
additionalDirectories | string[] | [] | Additional directories Claude can access |
agent | string | undefined | Agent name for the main thread. The agent must be defined in the agents option or in settings |
agents | Record<string, [AgentDefinition](#agent-definition)> | undefined | Programmatically define subagents |
allowDangerouslySkipPermissions | boolean | false | Enable bypassing permissions. Required when using permissionMode: 'bypassPermissions' |
allowedTools | string[] | [] | Tools to auto-approve without prompting. This does not restrict Claude to only these tools; unlisted tools fall through to permissionMode and canUseTool. Use disallowedTools to block tools. See Permissions |
betas | SdkBeta[] | [] | Enable beta features |
canUseTool | CanUseTool | undefined | Custom permission function for tool usage |
continue | boolean | false | Continue the most recent conversation |
cwd | string | process.cwd() | Current working directory |
debug | boolean | false | Enable debug mode for the Claude Code process |
debugFile | string | undefined | Write debug logs to a specific file path. Implicitly enables debug mode |
disallowedTools | string[] | [] | Tools to always deny. Deny rules are checked first and override allowedTools and permissionMode (including bypassPermissions) |
effort | 'low' | 'medium' | 'high' | 'max' | 'high' | Controls how much effort Claude puts into its response. Works with adaptive thinking to guide thinking depth |
enableFileCheckpointing | boolean | false | Enable file change tracking for rewinding. See File checkpointing |
env | Record<string, string | undefined> | process.env | Environment variables. Set CLAUDE_AGENT_SDK_CLIENT_APP to identify your app in the User-Agent header |
executable | 'bun' | 'deno' | 'node' | Auto-detected | JavaScript runtime to use |
executableArgs | string[] | [] | Arguments to pass to the executable |
extraArgs | Record<string, string | null> | {} | Additional arguments |
fallbackModel | string | undefined | Model to use if primary fails |
forkSession | boolean | false | When resuming with resume, fork to a new session ID instead of continuing the original session |
hooks | Partial<Record<HookEvent, HookCallbackMatcher[]>> | {} | Hook callbacks for events |
includePartialMessages | boolean | false | Include partial message events |
maxBudgetUsd | number | undefined | Maximum budget in USD for the query |
maxThinkingTokens | number | undefined | Deprecated: Use thinking instead. Maximum tokens for thinking process |
maxTurns | number | undefined | Maximum agentic turns (tool-use round trips) |
mcpServers | Record<string, [McpServerConfig](#mcp-server-config)> | {} | MCP server configurations |
model | string | Default from CLI | Claude model to use |
outputFormat | { type: 'json_schema', schema: JSONSchema } | undefined | Define output format for agent results. See Structured outputs for details |
pathToClaudeCodeExecutable | string | Uses built-in executable | Path to Claude Code executable |
permissionMode | PermissionMode | 'default' | Permission mode for the session |
permissionPromptToolName | string | undefined | MCP tool name for permission prompts |
persistSession | boolean | true | When false, disables session persistence to disk. Sessions cannot be resumed later |
plugins | SdkPluginConfig[] | [] | Load custom plugins from local paths. See Plugins for details |
promptSuggestions | boolean | false | Enable prompt suggestions. Emits a prompt_suggestion message after each turn with a predicted next user prompt |
resume | string | undefined | Session ID to resume |
resumeSessionAt | string | undefined | Resume session at a specific message UUID |
sandbox | SandboxSettings | undefined | Configure sandbox behavior programmatically. See Sandbox settings for details |
sessionId | string | Auto-generated | Use a specific UUID for the session instead of auto-generating one |
settingSources | SettingSource[] | [] (no settings) | Control which filesystem settings to load. When omitted, no settings are loaded. Note: Must include 'project' to load CLAUDE.md files |
spawnClaudeCodeProcess | (options: SpawnOptions) => SpawnedProcess | undefined | Custom function to spawn the Claude Code process. Use to run Claude Code in VMs, containers, or remote environments |
stderr | (data: string) => void | undefined | Callback for stderr output |
strictMcpConfig | boolean | false | Enforce strict MCP validation |
systemPrompt | string | { type: 'preset'; preset: 'claude_code'; append?: string } | undefined (minimal prompt) | System prompt configuration. Pass a string for custom prompt, or { type: 'preset', preset: 'claude_code' } to use Claude Code’s system prompt. When using the preset object form, add append to extend the system prompt with additional instructions |
thinking | ThinkingConfig | { type: 'adaptive' } for supported models | Controls Claude’s thinking/reasoning behavior. See ThinkingConfig for options |
toolConfig | ToolConfig | undefined | Configuration for built-in tool behavior. See ToolConfig for details |
tools | string[] | { type: 'preset'; preset: 'claude_code' } | undefined | Tool configuration. Pass an array of tool names or use the preset to get Claude Code’s default tools |
Query object
Interface returned by the query() function.
Methods
| Method | Description |
|---|---|
interrupt() | Interrupts the query (only available in streaming input mode) |
rewindFiles(userMessageId, options?) | Restores files to their state at the specified user message. Pass { dryRun: true } to preview changes. Requires enableFileCheckpointing: true. See File checkpointing |
setPermissionMode() | Changes the permission mode (only available in streaming input mode) |
setModel() | Changes the model (only available in streaming input mode) |
setMaxThinkingTokens() | Deprecated: Use the thinking option instead. Changes the maximum thinking tokens |
initializationResult() | Returns the full initialization result including supported commands, models, account info, and output style configuration |
supportedCommands() | Returns available slash commands |
supportedModels() | Returns available models with display info |
supportedAgents() | Returns available subagents as AgentInfo[] |
mcpServerStatus() | Returns status of connected MCP servers |
accountInfo() | Returns account information |
reconnectMcpServer(serverName) | Reconnect an MCP server by name |
toggleMcpServer(serverName, enabled) | Enable or disable an MCP server by name |
setMcpServers(servers) | Dynamically replace the set of MCP servers for this session. Returns info about which servers were added, removed, and any errors |
streamInput(stream) | Stream input messages to the query for multi-turn conversations |
stopTask(taskId) | Stop a running background task by ID |
close() | Close the query and terminate the underlying process. Forcefully ends the query and cleans up all resources |
SDKControlInitializeResponse
Return type of initializationResult(). Contains session initialization data.
AgentDefinition
Configuration for a subagent defined programmatically.
| Field | Required | Description |
|---|---|---|
description | Yes | Natural language description of when to use this agent |
tools | No | Array of allowed tool names. If omitted, inherits all tools from parent |
disallowedTools | No | Array of tool names to explicitly disallow for this agent |
prompt | Yes | The agent’s system prompt |
model | No | Model override for this agent. If omitted or 'inherit', uses the main model |
mcpServers | No | MCP server specifications for this agent |
skills | No | Array of skill names to preload into the agent context |
maxTurns | No | Maximum number of agentic turns (API round-trips) before stopping |
criticalSystemReminder_EXPERIMENTAL | No | Experimental: Critical reminder added to the system prompt |
AgentMcpServerSpec
Specifies MCP servers available to a subagent. Can be a server name (string referencing a server from the parent’s mcpServers config) or an inline server configuration record mapping server names to configs.
McpServerConfigForProcessTransport is McpStdioServerConfig | McpSSEServerConfig | McpHttpServerConfig | McpSdkServerConfig.
SettingSource
Controls which filesystem-based configuration sources the SDK loads settings from.
| Value | Description | Location |
|---|---|---|
'user' | Global user settings | ~/.claude/settings.json |
'project' | Shared project settings (version controlled) | .claude/settings.json |
'local' | Local project settings (gitignored) | .claude/settings.local.json |
Default behavior
WhensettingSources is omitted or undefined, the SDK does not load any filesystem settings. This provides isolation for SDK applications.
Why use settingSources
Load all filesystem settings (legacy behavior):Settings precedence
When multiple sources are loaded, settings are merged with this precedence (highest to lowest):- Local settings (
.claude/settings.local.json) - Project settings (
.claude/settings.json) - User settings (
~/.claude/settings.json)
agents, allowedTools) always override filesystem settings.
PermissionMode
CanUseTool
Custom permission function type for controlling tool usage.
| Option | Type | Description |
|---|---|---|
signal | AbortSignal | Signaled if the operation should be aborted |
suggestions | PermissionUpdate[] | Suggested permission updates so the user is not prompted again for this tool |
blockedPath | string | The file path that triggered the permission request, if applicable |
decisionReason | string | Explains why this permission request was triggered |
toolUseID | string | Unique identifier for this specific tool call within the assistant message |
agentID | string | If running within a sub-agent, the sub-agent’s ID |
PermissionResult
Result of a permission check.
ToolConfig
Configuration for built-in tool behavior.
| Field | Type | Description |
|---|---|---|
askUserQuestion.previewFormat | 'markdown' | 'html' | Opts into the preview field on AskUserQuestion options and sets its content format. When unset, Claude does not emit previews |
McpServerConfig
Configuration for MCP servers.
McpStdioServerConfig
McpSSEServerConfig
McpHttpServerConfig
McpSdkServerConfigWithInstance
McpClaudeAIProxyServerConfig
SdkPluginConfig
Configuration for loading plugins in the SDK.
| Field | Type | Description |
|---|---|---|
type | 'local' | Must be 'local' (only local plugins currently supported) |
path | string | Absolute or relative path to the plugin directory |
Message Types
SDKMessage
Union type of all possible messages returned by the query.
SDKAssistantMessage
Assistant response message.
message field is a BetaMessage from the Anthropic SDK. It includes fields like id, content, model, stop_reason, and usage.
SDKAssistantMessageError is one of: 'authentication_failed', 'billing_error', 'rate_limit', 'invalid_request', 'server_error', 'max_output_tokens', or 'unknown'.
SDKUserMessage
User input message.
SDKUserMessageReplay
Replayed user message with required UUID.
SDKResultMessage
Final result message.
SDKSystemMessage
System initialization message.
SDKPartialAssistantMessage
Streaming partial message (only when includePartialMessages is true).
SDKCompactBoundaryMessage
Message indicating a conversation compaction boundary.
SDKPermissionDenial
Information about a denied tool use.
Hook Types
For a comprehensive guide on using hooks with examples and common patterns, see the Hooks guide.HookEvent
Available hook events.
HookCallback
Hook callback function type.
HookCallbackMatcher
Hook configuration with optional matcher.
HookInput
Union type of all hook input types.
BaseHookInput
Base interface that all hook input types extend.
PreToolUseHookInput
PostToolUseHookInput
PostToolUseFailureHookInput
NotificationHookInput
UserPromptSubmitHookInput
SessionStartHookInput
SessionEndHookInput
StopHookInput
SubagentStartHookInput
SubagentStopHookInput
PreCompactHookInput
PermissionRequestHookInput
SetupHookInput
TeammateIdleHookInput
TaskCompletedHookInput
ConfigChangeHookInput
WorktreeCreateHookInput
WorktreeRemoveHookInput
HookJSONOutput
Hook return value.
AsyncHookJSONOutput
SyncHookJSONOutput
Tool Input Types
Documentation of input schemas for all built-in Claude Code tools. These types are exported from@anthropic-ai/claude-agent-sdk and can be used for type-safe tool interactions.
ToolInputSchemas
Union of all tool input types, exported from @anthropic-ai/claude-agent-sdk.
Agent
Tool name:Agent (previously Task, which is still accepted as an alias)
AskUserQuestion
Tool name:AskUserQuestion
Bash
Tool name:Bash
Monitor
Tool name:Monitor
persistent: true for session-length watches such as log tails. Monitor follows the same permission rules as Bash. See the Monitor tool reference for behavior and provider availability.
TaskOutput
Tool name:TaskOutput
Edit
Tool name:Edit
Read
Tool name:Read
pages for PDF page ranges (for example, "1-5").
Write
Tool name:Write
Glob
Tool name:Glob
Grep
Tool name:Grep
TaskStop
Tool name:TaskStop
NotebookEdit
Tool name:NotebookEdit
WebFetch
Tool name:WebFetch
WebSearch
Tool name:WebSearch
TodoWrite
Tool name:TodoWrite
ExitPlanMode
Tool name:ExitPlanMode
ListMcpResources
Tool name:ListMcpResources
ReadMcpResource
Tool name:ReadMcpResource
Config
Tool name:Config
EnterWorktree
Tool name:EnterWorktree
Tool Output Types
Documentation of output schemas for all built-in Claude Code tools. These types are exported from@anthropic-ai/claude-agent-sdk and represent the actual response data returned by each tool.
ToolOutputSchemas
Union of all tool output types.
Agent
Tool name:Agent (previously Task, which is still accepted as an alias)
status field: "completed" for finished tasks, "async_launched" for background tasks, and "sub_agent_entered" for interactive subagents.
AskUserQuestion
Tool name:AskUserQuestion
Bash
Tool name:Bash
backgroundTaskId.
Monitor
Tool name:Monitor
TaskStop to cancel the watch early.
Edit
Tool name:Edit
Read
Tool name:Read
type field.
Write
Tool name:Write
Glob
Tool name:Glob
Grep
Tool name:Grep
mode: file list, content with matches, or match counts.
TaskStop
Tool name:TaskStop
NotebookEdit
Tool name:NotebookEdit
WebFetch
Tool name:WebFetch
WebSearch
Tool name:WebSearch
TodoWrite
Tool name:TodoWrite
ExitPlanMode
Tool name:ExitPlanMode
ListMcpResources
Tool name:ListMcpResources
ReadMcpResource
Tool name:ReadMcpResource
Config
Tool name:Config
EnterWorktree
Tool name:EnterWorktree
Permission Types
PermissionUpdate
Operations for updating permissions.
PermissionBehavior
PermissionUpdateDestination
PermissionRuleValue
Other Types
ApiKeySource
SdkBeta
Available beta features that can be enabled via the betas option. See Beta headers for more information.
SlashCommand
Information about an available slash command.
ModelInfo
Information about an available model.
AgentInfo
Information about an available subagent that can be invoked via the Agent tool.
| Field | Type | Description |
|---|---|---|
name | string | Agent type identifier (e.g., "Explore", "general-purpose") |
description | string | Description of when to use this agent |
model | string | undefined | Model alias this agent uses. If omitted, inherits the parent’s model |
McpServerStatus
Status of a connected MCP server.
McpServerStatusConfig
The configuration of an MCP server as reported by mcpServerStatus(). This is the union of all MCP server transport types.
McpServerConfig for details on each transport type.
AccountInfo
Account information for the authenticated user.
ModelUsage
Per-model usage statistics returned in result messages.
ConfigScope
NonNullableUsage
A version of Usage with all nullable fields made non-nullable.
Usage
Token usage statistics (from @anthropic-ai/sdk).
CallToolResult
MCP tool result type (from @modelcontextprotocol/sdk/types.js).
ThinkingConfig
Controls Claude’s thinking/reasoning behavior. Takes precedence over the deprecated maxThinkingTokens.
SpawnedProcess
Interface for custom process spawning (used with spawnClaudeCodeProcess option). ChildProcess already satisfies this interface.
SpawnOptions
Options passed to the custom spawn function.
McpSetServersResult
Result of a setMcpServers() operation.
RewindFilesResult
Result of a rewindFiles() operation.
SDKStatusMessage
Status update message (e.g., compacting).
SDKTaskNotificationMessage
Notification when a background task completes, fails, or is stopped. Background tasks include run_in_background Bash commands, Monitor watches, and background subagents.
SDKToolUseSummaryMessage
Summary of tool usage in a conversation.
SDKHookStartedMessage
Emitted when a hook begins executing.
SDKHookProgressMessage
Emitted while a hook is running, with stdout/stderr output.
SDKHookResponseMessage
Emitted when a hook finishes executing.
SDKToolProgressMessage
Emitted periodically while a tool is executing to indicate progress.
SDKAuthStatusMessage
Emitted during authentication flows.
SDKTaskStartedMessage
Emitted when a background task begins. The task_type field is "local_bash" for background Bash commands and Monitor watches, "local_agent" for subagents, or "remote_agent".
SDKTaskProgressMessage
Emitted periodically while a background task is running.
SDKFilesPersistedEvent
Emitted when file checkpoints are persisted to disk.
SDKRateLimitEvent
Emitted when the session encounters a rate limit.
SDKLocalCommandOutputMessage
Output from a local slash command (for example, /voice or /cost). Displayed as assistant-style text in the transcript.
SDKPromptSuggestionMessage
Emitted after each turn when promptSuggestions is enabled. Contains a predicted next user prompt.
AbortError
Custom error class for abort operations.
Sandbox Configuration
SandboxSettings
Configuration for sandbox behavior. Use this to enable command sandboxing and configure network restrictions programmatically.
| Property | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Enable sandbox mode for command execution |
autoAllowBashIfSandboxed | boolean | true | Auto-approve bash commands when sandbox is enabled |
excludedCommands | string[] | [] | Commands that always bypass sandbox restrictions (e.g., ['docker']). These run unsandboxed automatically without model involvement |
allowUnsandboxedCommands | boolean | true | Allow the model to request running commands outside the sandbox. When true, the model can set dangerouslyDisableSandbox in tool input, which falls back to the permissions system |
network | SandboxNetworkConfig | undefined | Network-specific sandbox configuration |
filesystem | SandboxFilesystemConfig | undefined | Filesystem-specific sandbox configuration for read/write restrictions |
ignoreViolations | Record<string, string[]> | undefined | Map of violation categories to patterns to ignore (e.g., { file: ['/tmp/*'], network: ['localhost'] }) |
enableWeakerNestedSandbox | boolean | false | Enable a weaker nested sandbox for compatibility |
ripgrep | { command: string; args?: string[] } | undefined | Custom ripgrep binary configuration for sandbox environments |
Example usage
SandboxNetworkConfig
Network-specific configuration for sandbox mode.
| Property | Type | Default | Description |
|---|---|---|---|
allowedDomains | string[] | [] | Domain names that sandboxed processes can access |
allowManagedDomainsOnly | boolean | false | Restrict network access to only the domains in allowedDomains |
allowLocalBinding | boolean | false | Allow processes to bind to local ports (e.g., for dev servers) |
allowUnixSockets | string[] | [] | Unix socket paths that processes can access (e.g., Docker socket) |
allowAllUnixSockets | boolean | false | Allow access to all Unix sockets |
httpProxyPort | number | undefined | HTTP proxy port for network requests |
socksProxyPort | number | undefined | SOCKS proxy port for network requests |
SandboxFilesystemConfig
Filesystem-specific configuration for sandbox mode.
| Property | Type | Default | Description |
|---|---|---|---|
allowWrite | string[] | [] | File path patterns to allow write access to |
denyWrite | string[] | [] | File path patterns to deny write access to |
denyRead | string[] | [] | File path patterns to deny read access to |
Permissions Fallback for Unsandboxed Commands
WhenallowUnsandboxedCommands is enabled, the model can request to run commands outside the sandbox by setting dangerouslyDisableSandbox: true in the tool input. These requests fall back to the existing permissions system, meaning your canUseTool handler is invoked, allowing you to implement custom authorization logic.
excludedCommands vs allowUnsandboxedCommands:excludedCommands: A static list of commands that always bypass the sandbox automatically (e.g.,['docker']). The model has no control over this.allowUnsandboxedCommands: Lets the model decide at runtime whether to request unsandboxed execution by settingdangerouslyDisableSandbox: truein the tool input.
- Audit model requests: Log when the model requests unsandboxed execution
- Implement allowlists: Only permit specific commands to run unsandboxed
- Add approval workflows: Require explicit authorization for privileged operations
See also
- SDK overview - General SDK concepts
- Python SDK reference - Python SDK documentation
- CLI reference - Command-line interface
- Common workflows - Step-by-step guides