Environments
Preview An environment is a first-class child of a
site — its own database and files, its own preview URL, and its
own observability. Every site has a production environment; staging and preview
environments are clones of production, mapped to branches by your
branch routes. Most application-layer operations
(deploys, components, cache, secrets) are env-scoped, because a plugin can be active on
staging but not production.
The environment object
Section titled “The environment object”| Field | Type | Description |
|---|---|---|
id |
string | Stable identifier, e.g. env_01J8.... |
site_id |
string | The owning site. |
kind |
string | production, staging, or preview. |
branch |
string | The git branch mapped to this environment. |
status |
string | active, provisioning, suspended. |
preview_url |
string | Live URL for the environment. |
created_at |
string | RFC 3339 timestamp — also the observability hard-cut floor. |
Create & list environments
Section titled “Create & list environments”POST /v1/sites/{id}/environments
Section titled “POST /v1/sites/{id}/environments”environments:write Create an environment, cloned from
production. Provisioning is non-instant, so this returns a 202 Accepted with an
async job.
| Parameter | Type | Required | Description |
|---|---|---|---|
kind |
string | yes | staging or preview. |
branch |
string | yes | Git branch to map to this environment. |
ephemeral |
boolean | no | If true, the environment is reaped when idle unless renewed. |
curl -X POST https://api.managed.dev/v1/sites/site_01J7.../environments \ -H "Authorization: Bearer mfk_live_..." \ -H "Idempotency-Key: 7d2a...b9" \ -H "Content-Type: application/json" \ -d '{ "kind": "preview", "branch": "feature/checkout", "ephemeral": true }'job, err := client.Environments.Create(ctx, "site_01J7...", &forge.EnvCreateParams{ Kind: forge.EnvKind("preview"), Branch: forge.String("feature/checkout"), Ephemeral: forge.Bool(true),}, forge.WithIdempotencyKey("7d2a...b9"))const job = await client.environments.create( "site_01J7...", { kind: "preview", branch: "feature/checkout", ephemeral: true }, { idempotencyKey: "7d2a...b9" },);{ "data": { "id": "job_01J9...", "type": "environment.create", "status": "queued", "created_at": "2026-06-24T14:20:41Z", "resource": { "type": "environment", "id": "env_01J8...", "site_id": "site_01J7..." }, "links": { "self": "/v1/jobs/job_01J9...", "stream": "/v1/jobs/job_01J9.../stream" } }, "request_id": "req_01J9..."}GET /v1/sites/{id}/environments · GET · DELETE /v1/sites/{id}/environments/{envID}
Section titled “GET /v1/sites/{id}/environments · GET · DELETE /v1/sites/{id}/environments/{envID}”- List (environments:read) every environment on a site, cursor-paginated.
- Retrieve (environments:read) one environment.
- Delete (environments:write) an environment; returns
a
202job. Production cannot be deleted.
Lifecycle actions
Section titled “Lifecycle actions”Each action returns a 202 Accepted with a job. See
environment lifecycle for what each one does.
| Endpoint | Scope | Effect |
|---|---|---|
POST …/{envID}/suspend |
environments:write | Pause the environment; stops serving and frees resources. |
POST …/{envID}/resume |
environments:write | Bring a suspended environment back online. |
POST …/{envID}/refresh |
environments:write | Reseed database and files from production. |
POST …/{envID}/reset |
environments:write | Return the environment to a clean baseline. |
POST …/{envID}/renew |
environments:write | Extend an ephemeral environment’s lifetime. |
curl -X POST https://api.managed.dev/v1/sites/site_01J7.../environments/env_01J8.../refresh \ -H "Authorization: Bearer mfk_live_..." \ -H "Idempotency-Key: c41e...30"Clone content
Section titled “Clone content”POST /v1/sites/{id}/environments/{envID}/clone-content
Section titled “POST /v1/sites/{id}/environments/{envID}/clone-content”environments:write Copy database and/or files from a source environment into this one — directional and selectable, with a dry-run. This is Pantheon-parity content cloning, decoupled from code deploys.
| Parameter | Type | Required | Description |
|---|---|---|---|
from_env |
string | yes | Source environment id or kind, e.g. production. |
selectors |
string[] | yes | Any of db, files. |
dry_run |
boolean | no | If true, report what would change without applying it. |
curl -X POST https://api.managed.dev/v1/sites/site_01J7.../environments/env_01J8.../clone-content \ -H "Authorization: Bearer mfk_live_..." \ -H "Idempotency-Key: 88af...12" \ -H "Content-Type: application/json" \ -d '{ "from_env": "production", "selectors": ["db", "files"], "dry_run": true }'mf env clone-content --site acme-store --env staging \ --from production --select db,files --dry-runDrop dry_run (or set it false) to apply. The call returns a 202 with a
job you track to completion.
Branch routes
Section titled “Branch routes”PUT /v1/sites/{id}/branch-routes
Section titled “PUT /v1/sites/{id}/branch-routes”environments:write Map git branches to environment
kinds. The default branch deploys to production; other branches map to staging,
preview, or ignore. See branch routes.
| Parameter | Type | Required | Description |
|---|---|---|---|
routes |
object[] | yes | Each entry maps a branch pattern to a target. |
curl -X PUT https://api.managed.dev/v1/sites/site_01J7.../branch-routes \ -H "Authorization: Bearer mfk_live_..." \ -H "Content-Type: application/json" \ -d '{ "routes": [ { "branch": "main", "target": "production" }, { "branch": "develop", "target": "staging" }, { "branch": "feature/*", "target": "preview" }, { "branch": "dependabot/*","target": "ignore" } ] }'