---
title: "Create a contained project branch"
method: POST
path: "/projects/v1/{project_id}/branches"
tags: ["Project Branches"]
---

# Create a contained project branch

`POST /projects/v1/{project_id}/branches`

## Request

- Base URL: `https://api.run402.com`
- URL: `https://api.run402.com/projects/v1/{project_id}/branches`
- Auth: one of:
  - API key in header `SIGN-IN-WITH-X`
  - HTTP bearer

Create an expiring branch project from the live project or a snapshot. The branch is materialized in a spare schema slot, receives a derived noindex host, copies auth identities, deploys the parent's live release, sandboxes email by default, and leaves scheduled functions disabled unless requested.

## Path parameters

- `project_id` string, required: Run402 project ID. Public IDs are not UUIDs.

## Request body

- ProjectBranchCreateRequest
  - `from_snapshot_id` string
  - `name` string
  - `email_mode` 'sandbox' | 'off'
  - `enable_cron` boolean
  - `ttl_days` number

## Response `201`

Branch created.

- ProjectBranch
  - `branch_project_id` string, required: The branch project's Run402 project ID.
  - `parent_project_id` string, required: The parent project's Run402 project ID.
  - `name` string, required
  - `branch_url` string, uri, nullable
  - `subdomain` string, nullable
  - `status` 'active', required
  - `email_mode` 'sandbox' | 'off', required
  - `enable_cron` boolean, required
  - `data_from` object, required
    - `snapshot_id` string, nullable
    - `captured_at` string, date-time, nullable
  - `release` object, required
    - `parent_release_id` string, nullable
    - `branch_release_id` string, nullable
  - `expires_at` string, date-time, required
  - `created_at` string, date-time, required
  - `next_actions` NextAction[], required
    - `type` string, required: Advisory machine-readable action type such as retry, authenticate, submit_payment, fund_wallet, renew_tier, check_usage, resume_deploy, edit_request, edit_migration, contact_support, upgrade_client, poll (poll the project events feed — appended when the envelope carries a correlated_platform_incident), or hand_to_member (on a commit/promote response that just activated a public site: show the human urls.site and urls.console, relay Run402's offer to promote the build on @run402com, and ask yes or no — see `credited_as` below).
    - `method` string
    - `path` string
    - `auth` string
    - `why` string
    - `credited_as` string, nullable: `hand_to_member` only. The caller's own live presence name in the project's default room, else that room's most recently active live presence, else `null` — in which case `why` tells the agent that joining the room with a name (`run402 rooms join --name ...`) is how the promotion credits it.
    - `body` object: `hand_to_member` only. A ready-to-send `POST /feedback/v1` template: `{ project_id, message: "promote: yes", handle? }`.

## Other responses

- `409`: Branch cap or source snapshot conflict.

---

[API](https://skmtc.dev/run402/apis/run402-api.md) · [All operations](https://skmtc.dev/run402/apis/run402-api/llms.txt) · [OpenAPI document](https://skmtc.dev/run402/apis/run402-api/revisions/893607557f50?raw)
