diff --git a/docs/blueprints/blueprint-api.md b/docs/blueprints/blueprint-api.md
new file mode 100644
index 00000000..f3d96e00
--- /dev/null
+++ b/docs/blueprints/blueprint-api.md
@@ -0,0 +1,286 @@
+---
+sidebar_position: 4
+title: Blueprints API (V2 & V3)
+hide_title: true
+---
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+# Blueprints API
+
+A developer's guide to installing and synchronizing Blueprints programmatically. The full
+endpoint reference lives in the [Blueprint Manifest API docs](/api/blueprint-manifest); this
+page is the narrative on top of it — when to use each engine, how the calls fit together,
+and copy‑pasteable examples.
+
+:::info
+Blueprints are currently in closed **BETA**, available to selected customers.
+:::
+
+## Two engines: V2 and V3
+
+epilot is migrating Blueprint installs from the original Terraform-based engine (**V2**) to a
+new direct-API engine (**V3**). Both are live; they use **different endpoints**.
+
+| | **V2 (Terraform)** | **V3 (direct API)** |
+| --- | --- | --- |
+| Install path | `POST /v2/blueprint-manifest/blueprints/{id}:install` | `POST /v3/blueprint-manifest/blueprint:install` |
+| How it applies | Generates Terraform, runs `plan`/`apply` | Calls resource APIs directly in dependency order |
+| Resource matching | Name-based (`processExistingResources`) | Lineage registry (stable cross-org identity) |
+| Many orgs at once | Patches (mass rollout) | **Bulk install** (`POST .../bulk-installs`) |
+| Resume on failure | Limited | Checkpoint-based resume |
+| Status | Stable, default in the portal today | Rolling out |
+
+**Which should I use?**
+
+- Building a **new programmatic integration** (e.g. installing one Blueprint into many
+ customer orgs from CI)? Use **V3**, and prefer **bulk install**.
+- Working with the **existing portal flows / Patches**? That's **V2**.
+
+:::tip Jobs are shared
+Both engines produce a **job**. Jobs — V2 *and* V3 — are polled, resumed, and cancelled
+through the same `/v2/blueprint-manifest/jobs/*` endpoints. Tell them apart with the job's
+`sync_engine` field (`"terraform"` | `"v3"`). There is no separate `/v3/.../jobs` surface —
+that cross-version step is intentional.
+:::
+
+## V3 endpoint map
+
+| Purpose | Method & path |
+| --- | --- |
+| Install into one org | `POST /v3/blueprint-manifest/blueprint:install` |
+| Install into many orgs | `POST /v3/blueprint-manifest/bulk-installs` |
+| Get a bulk install | `GET /v3/blueprint-manifest/bulk-installs/{bulk_job_id}` |
+| List bulk targets | `GET /v3/blueprint-manifest/bulk-installs/{bulk_job_id}/targets` |
+| Retry one target | `POST /v3/blueprint-manifest/bulk-installs/{bulk_job_id}/targets/{destination_org_id}:retry` |
+| Inspect lineage | `GET /v3/blueprint-manifest/blueprints/{blueprint_id}/lineage` |
+| Restore a deployment | `POST /v3/blueprint-manifest/blueprints/{blueprint_id}/deployments/{job_id}:restore` |
+| **Poll any job** | `GET /v2/blueprint-manifest/jobs/{job_id}` *(shared)* |
+| **Resume a paused install** | `POST /v2/blueprint-manifest/jobs/{job_id}:continue` *(shared)* |
+| **Cancel a job** | `POST /v2/blueprint-manifest/jobs/{job_id}:cancel` *(shared)* |
+
+## Authentication
+
+All calls take a bearer token in the `authorization` header. For **cross-org** installs the
+two tokens have distinct roles:
+
+- The **caller token** (source org) authorizes reads of the source Blueprint.
+- The **destination token** (`destination_auth_token`) authorizes writes into the target org.
+
+`destination_auth_token` is **write-only** — passed in the request, used only for that org's
+writes, and never stored or returned.
+
+## Single install (V3)
+
+Install one Blueprint into one destination org.
+
+
+
+
+```bash
+curl -X POST https://blueprint-manifest.sls.epilot.io/v3/blueprint-manifest/blueprint:install \
+ -H "authorization: Bearer $SOURCE_TOKEN" \
+ -H "content-type: application/json" \
+ -d '{
+ "source_org_id": "source-org-id",
+ "source_blueprint_id": "11111111-1111-1111-1111-111111111111",
+ "destination_org_id": "dest-org-id",
+ "destination_auth_token": "DEST_TOKEN",
+ "auto_apply": true
+ }'
+# => 202 { "job_id": "...", "destination_blueprint_id": "..." }
+```
+
+
+
+
+```bash
+epilot blueprint-manifest installBlueprintV3 -d '{
+ "source_org_id": "source-org-id",
+ "source_blueprint_id": "11111111-1111-1111-1111-111111111111",
+ "destination_org_id": "dest-org-id",
+ "destination_auth_token": "DEST_TOKEN",
+ "auto_apply": true
+}'
+```
+
+
+
+
+```ts
+import { epilot } from '@epilot/sdk'
+
+epilot.authorize(() => SOURCE_TOKEN)
+
+const { data } = await epilot.blueprintManifest.installBlueprintV3(null, {
+ source_org_id: 'source-org-id',
+ source_blueprint_id: '11111111-1111-1111-1111-111111111111',
+ destination_org_id: 'dest-org-id',
+ destination_auth_token: 'DEST_TOKEN',
+ auto_apply: true,
+})
+```
+
+
+
+
+### `auto_apply`: apply automatically vs review the plan first
+
+- **`auto_apply: true`** — plans, snapshots, then applies in one shot. No manual step.
+- **`auto_apply: false`** (default) — the job stops at `status: "WAITING_USER_ACTION"` after
+ planning so you can review what would change, then you resume it:
+
+```bash
+curl -X POST https://blueprint-manifest.sls.epilot.io/v2/blueprint-manifest/jobs/$JOB_ID:continue \
+ -H "authorization: Bearer $DEST_TOKEN"
+```
+
+### Poll the job
+
+```bash
+curl https://blueprint-manifest.sls.epilot.io/v2/blueprint-manifest/jobs/$JOB_ID \
+ -H "authorization: Bearer $DEST_TOKEN"
+# => {
+# "sync_engine": "v3",
+# "status": "IN_PROGRESS" | "WAITING_USER_ACTION" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED",
+# "resource_progress": [ { "type": "...", "status": "..." } ]
+# }
+```
+
+## Bulk install (V3) — one Blueprint into many orgs
+
+Instead of scripting N single installs, hand the server a list of targets. It caps active
+installs, isolates per-target failures, and tracks aggregate status. Every child install
+runs with `auto_apply: true`.
+
+**v1 limits:** 1–100 targets · `max_concurrency` 1–5 (default 2).
+
+### 1. Create
+
+
+
+
+```bash
+curl -X POST https://blueprint-manifest.sls.epilot.io/v3/blueprint-manifest/bulk-installs \
+ -H "authorization: Bearer $SOURCE_TOKEN" \
+ -H "content-type: application/json" \
+ -d '{
+ "source_blueprint_id": "11111111-1111-1111-1111-111111111111",
+ "max_concurrency": 2,
+ "options": { "resources_to_ignore": [] },
+ "targets": [
+ { "destination_org_id": "org-a", "destination_auth_token": "TOKEN_A" },
+ { "destination_org_id": "org-b", "destination_auth_token": "TOKEN_B" }
+ ]
+ }'
+# source_org_id is optional and defaults to the caller org; if set it must equal it.
+# => 202 {
+# "bulk_job_id": "...", "status": "QUEUED",
+# "target_count": 2, "max_concurrency": 2,
+# "counts": { "queued": 2, "in_progress": 0, "success": 0, "partial_success": 0, "failed": 0 }
+# }
+```
+
+
+
+
+```bash
+epilot blueprint-manifest createBulkInstallV3 -d '{
+ "source_blueprint_id": "11111111-1111-1111-1111-111111111111",
+ "max_concurrency": 2,
+ "targets": [
+ { "destination_org_id": "org-a", "destination_auth_token": "TOKEN_A" },
+ { "destination_org_id": "org-b", "destination_auth_token": "TOKEN_B" }
+ ]
+}'
+```
+
+> Available once the V3 spec is synced to the CLI — see [CLI exposure](#cli-exposure) below.
+
+
+
+
+### 2. Poll the parent
+
+```bash
+curl https://blueprint-manifest.sls.epilot.io/v3/blueprint-manifest/bulk-installs/$BULK_JOB_ID \
+ -H "authorization: Bearer $SOURCE_TOKEN"
+# => { "status": "IN_PROGRESS", "counts": { "queued": 0, "in_progress": 2, "success": 0, ... } }
+```
+
+### 3. List targets (with per-target progress)
+
+Each target row hydrates its latest child job, including `events[]` and `resource_progress[]`.
+
+```bash
+curl "https://blueprint-manifest.sls.epilot.io/v3/blueprint-manifest/bulk-installs/$BULK_JOB_ID/targets?limit=10" \
+ -H "authorization: Bearer $SOURCE_TOKEN"
+# => {
+# "results": [
+# {
+# "destination_org_id": "org-b",
+# "destination_blueprint_id": "...",
+# "status": "FAILED",
+# "job_ids": ["job-1"],
+# "job": { "id": "job-1", "status": "FAILED", "events": [...], "resource_progress": [...] }
+# }
+# ],
+# "next_cursor": "..."
+# }
+```
+
+Paginate by passing the returned `next_cursor` back as `?cursor=...` (max `limit` 25).
+
+### 4. Retry a failed target
+
+Allowed only for `FAILED` or `PARTIAL_SUCCESS` targets. Supply a fresh destination token;
+the source/destination identifiers are immutable. A new child job is appended to `job_ids`.
+
+```bash
+curl -X POST "https://blueprint-manifest.sls.epilot.io/v3/blueprint-manifest/bulk-installs/$BULK_JOB_ID/targets/org-b:retry" \
+ -H "authorization: Bearer $SOURCE_TOKEN" \
+ -H "content-type: application/json" \
+ -d '{ "destination_auth_token": "FRESH_TOKEN_B" }'
+```
+
+### Status model
+
+| Target status | Meaning |
+| --- | --- |
+| `QUEUED` | persisted, not started |
+| `IN_PROGRESS` | child install running |
+| `SUCCESS` / `PARTIAL_SUCCESS` / `FAILED` | mirrors the child job's terminal status |
+
+The **parent** aggregates its targets:
+
+| Parent status | Condition |
+| --- | --- |
+| `QUEUED` | no target started |
+| `IN_PROGRESS` | at least one target queued/running, not all terminal |
+| `SUCCESS` | every target succeeded |
+| `PARTIAL_SUCCESS` | all terminal, mix incl. ≥1 success/partial |
+| `FAILED` | all terminal, none succeeded or partially succeeded |
+
+## Lineage & restore (V3)
+
+- **Lineage** — `GET /v3/blueprint-manifest/blueprints/{blueprint_id}/lineage` returns the
+ source→target id mapping for a Blueprint's resources in the current org. This is how V3
+ re-identifies resources across syncs instead of matching by name.
+- **Restore** — `POST /v3/blueprint-manifest/blueprints/{blueprint_id}/deployments/{job_id}:restore`
+ rolls a deployment back to its pre-install snapshot. Preview the effect first with
+ `GET .../deployments/{job_id}/restore-preview`.
+
+## CLI exposure {#cli-exposure}
+
+The epilot CLI is **spec-driven**: `epilot blueprint-manifest ` dispatches
+against a bundled OpenAPI definition. Exposing a new endpoint is a spec sync, not a CLI code
+change — making the CLI a good fit for dockerized CI jobs (no raw `curl`).
+
+- **Callable today:** `installBlueprintV3`, `getBlueprintLineageV3`.
+- **Available after the next V3 spec sync to `sdk-js`:** `createBulkInstallV3`,
+ `getBulkInstallV3`, `listBulkInstallTargetsV3`, `retryBulkInstallTargetV3`,
+ `restoreBlueprintDeploymentV3`, `getRestorePreview`.
+
+See the [CLI overview](/docs/cli/overview) and the
+[generated command reference](/docs/cli/commands/blueprint-manifest).