diff --git a/docs.json b/docs.json
index e43ba751..77ef7cb2 100644
--- a/docs.json
+++ b/docs.json
@@ -125,6 +125,7 @@
"docs/sandbox/lifecycle-events-webhooks",
"docs/sandbox/persistence",
"docs/sandbox/snapshots",
+ "docs/sandbox/fork",
"docs/sandbox/auto-resume",
"docs/sandbox/filesystem-only-snapshots",
"docs/sandbox/git-integration",
diff --git a/docs/sandbox/fork.mdx b/docs/sandbox/fork.mdx
new file mode 100644
index 00000000..c03dbbe6
--- /dev/null
+++ b/docs/sandbox/fork.mdx
@@ -0,0 +1,168 @@
+---
+title: "Sandbox forking"
+sidebarTitle: Forking
+description: Snapshot a running sandbox and boot new sandboxes from that exact state in a single call.
+---
+
+Forking lets you create running copies of a sandbox in a single call.
+The sandbox is snapshotted in place — paused, captured with its full filesystem and memory state, and resumed — and new sandboxes boot from that snapshot.
+
+Each fork is an independent sandbox with its own ID and timeout. It starts with the exact state the original had at the moment of the fork — files, running processes, loaded variables, and data — and diverges from there. The original sandbox keeps running with its ID and expiration untouched.
+
+## Fork flow
+
+```mermaid actions={false}
+graph LR
+ A[Running Sandbox] -->|fork| B[Snapshotting]
+ B --> A
+ B -->|count = N| C[Fork 1]
+ B --> D[Fork 2]
+ B --> E[Fork N]
+```
+
+The snapshot is captured once regardless of how many forks you request, so forking into many sandboxes costs the same single snapshot of the original.
+
+
+During the fork, the original sandbox is paused and resumed. The pause duration scales with the amount of disk changes since the last snapshot — write-heavy workloads pause longer. The pause also causes all active connections (e.g. WebSocket, PTY, command streams) to be dropped, so make sure your client handles reconnection properly.
+
+
+## Fork a sandbox
+
+You can fork a running sandbox instance. The method returns a list with one entry per requested fork.
+
+
+```js JavaScript & TypeScript
+import { Sandbox } from 'e2b'
+
+const sandbox = await Sandbox.create()
+await sandbox.files.write('/home/user/state.txt', 'shared state')
+
+// Fork the sandbox
+const [fork] = await sandbox.fork()
+if (fork instanceof Sandbox) {
+ // The fork starts with the original's files, processes, and memory
+ await fork.commands.run('cat /home/user/state.txt')
+}
+```
+```python Python
+from e2b import Sandbox
+
+sandbox = Sandbox.create()
+sandbox.files.write('/home/user/state.txt', 'shared state')
+
+# Fork the sandbox
+fork, = sandbox.fork()
+if isinstance(fork, Sandbox):
+ # The fork starts with the original's files, processes, and memory
+ fork.commands.run('cat /home/user/state.txt')
+```
+
+
+You can also fork by sandbox ID using the static method.
+
+
+```js JavaScript & TypeScript
+import { Sandbox } from 'e2b'
+
+// Fork by sandbox ID
+const forks = await Sandbox.fork(sandboxId)
+```
+```python Python
+from e2b import Sandbox
+
+# Fork by sandbox ID
+forks = Sandbox.fork(sandbox_id)
+```
+
+
+## Create multiple forks
+
+Use `count` to boot several sandboxes from the same snapshot in one call. You can request up to 100 forks at once.
+
+
+```js JavaScript & TypeScript highlight={5}
+import { Sandbox } from 'e2b'
+
+const sandbox = await Sandbox.create()
+
+const forks = await sandbox.fork({ count: 3 })
+
+for (const fork of forks) {
+ if (fork instanceof Sandbox) {
+ console.log('Forked sandbox:', fork.sandboxId)
+ }
+}
+```
+```python Python highlight={5}
+from e2b import Sandbox
+
+sandbox = Sandbox.create()
+
+forks = sandbox.fork(count=3)
+
+for fork in forks:
+ if isinstance(fork, Sandbox):
+ print('Forked sandbox:', fork.sandbox_id)
+```
+
+
+## Handle failed forks
+
+Each fork succeeds or fails independently. Instead of throwing on the first failure, the returned list contains a connected sandbox for each fork that started and an error value for each fork that didn't — so a partial failure doesn't throw away the successful forks.
+
+
+```js JavaScript & TypeScript
+import { Sandbox } from 'e2b'
+
+const results = await sandbox.fork({ count: 5 })
+
+const forks = results.filter((r) => r instanceof Sandbox)
+const errors = results.filter((r) => !(r instanceof Sandbox))
+
+for (const error of errors) {
+ console.error('Fork failed:', error.message)
+}
+```
+```python Python
+from e2b import Sandbox
+
+results = sandbox.fork(count=5)
+
+forks = [r for r in results if isinstance(r, Sandbox)]
+errors = [r for r in results if not isinstance(r, Sandbox)]
+
+for error in errors:
+ print('Fork failed:', error)
+```
+
+
+If the request fails as a whole (for example, the sandbox does not exist), the method throws instead of returning error values.
+
+## Fork timeout
+
+The `timeoutMs` (JavaScript) / `timeout` (Python) option sets how long the new forked sandboxes live and defaults to 5 minutes, like `Sandbox.create()`. It applies to the forks only — the original sandbox's expiration is not changed.
+
+
+```js JavaScript & TypeScript
+import { Sandbox } from 'e2b'
+
+const forks = await sandbox.fork({ count: 2, timeoutMs: 60_000 }) // 60 seconds
+```
+```python Python
+from e2b import Sandbox
+
+forks = sandbox.fork(count=2, timeout=60) # 60 seconds
+```
+
+
+## Forking vs. Snapshots
+
+Forking is a one-call shortcut for the common snapshot pattern: capture a running sandbox and immediately boot new sandboxes from the capture.
+
+| | Forking | Snapshots |
+|---|---|---|
+| Result | Running sandboxes, ready to use | A persistent snapshot ID |
+| Reuse | Snapshot is used once, for this call's forks | Snapshot can spawn sandboxes any time later |
+| Steps | One call | `createSnapshot()` / `create_snapshot()`, then `Sandbox.create()` per sandbox |
+
+Use forking when you want running copies right now. Use [snapshots](/docs/sandbox/snapshots) when you want a durable checkpoint to create sandboxes from later.
diff --git a/docs/sandbox/snapshots.mdx b/docs/sandbox/snapshots.mdx
index 8e28303d..06a52364 100644
--- a/docs/sandbox/snapshots.mdx
+++ b/docs/sandbox/snapshots.mdx
@@ -189,6 +189,6 @@ Use snapshots when you need to capture or fork live runtime state that depends o
- **Checkpointing agent work** — an AI agent has loaded data and produced partial results in memory. Snapshot it so you can resume or fork from that point later.
- **Rollback points** — snapshot before a risky or expensive operation (running untrusted code, applying a migration, refactoring a web app). If it fails, rollback - spawn a fresh sandbox from the snapshot before the operation happened.
-- **Forking workflows** — spawn multiple sandboxes from the same snapshot to explore different approaches in parallel.
+- **Forking workflows** — spawn multiple sandboxes from the same snapshot to explore different approaches in parallel. To snapshot and spawn copies in a single call, see [Forking](/docs/sandbox/fork).
- **Cached sandboxes** — avoid repeating expensive setup by snapshotting a sandbox that has already loaded a large dataset or started a long-running process.
- **Sharing state** — one user or agent configures an environment interactively, snapshots it, and others start from that exact state.