---
title: "Create sandbox"
method: POST
path: "/sandboxes"
tags: ["Sandboxes"]
---

# Create sandbox

`POST /sandboxes`

## Request

- Base URL: `https://api.render.com/v1`
- URL: `https://api.render.com/v1/sandboxes`
- Auth: HTTP bearer

Create a sandbox. Returns the initial sandbox snapshot synchronously.

With `snapshotId`: 404 with `code: snapshot_not_found` if the snapshot does not
exist; 409 with `code: snapshot_not_available` if it is not `available`, or
`code: snapshot_plan_mismatch` if a `runtime` snapshot was requested with a
different `plan`.

With `snapshotName`: 400 with `code: invalid_snapshot_name` if the name is
malformed, 400 without a code if `snapshotId` is also set, and 404 with
`code: snapshot_not_found` if no `available` snapshot in the group has the
name. The 409 cases above apply to the resolved snapshot.

409 with `code: sandbox_group_suspended` if the sandbox group is suspended.

400 with `code: sandbox_group_limit_reached` if the owner has no default
sandbox group and is already at its sandbox group limit.

400 with `code: invalid_sandbox_plan` if `plan` is not one the API currently
accepts. The message lists the accepted plans.

400 with `code: invalid_timeout_seconds` if `timeoutSeconds` is below 0 or
above the plan's maximum: 2592000 (30 days), or 86400 (24 hours) on Hobby
workspaces.

## Request body

- object
  - `ownerId` string, required: The ID of the workspace the sandbox belongs to.
  - `sandboxGroupId` Schema (unresolved $ref)
  - `networkPolicy` object: Set either `type` or its deprecated alias `default`. Sending both is only accepted when they name the same policy.
    - `type` 'allow-all' | 'deny-all' | 'allow-list': How outbound traffic is handled. `allow-all`, `deny-all`, or `allow-list` (requires additional `rules`).
    - `default` 0 (unresolved $ref)
    - `rules` object[]: Destinations the sandbox may reach, required when the policy is `allow-list` and rejected otherwise. Each domain may be listed once.
      - `domain` string, required: Hostname to apply the rule to. Matching is exact: `foo.local` does not cover `api.foo.local`, which needs its own rule or `*.foo.local`. A wildcard is only allowed as the leftmost label.
      - `protocol` 'https': Protocol this rule admits. Only `https` is accepted: under `allow-list` every other outbound protocol is dropped.
  - `plan` union: Compute plan. See `sandboxPlan` for known values.
    - 'starter' | 'standard' | 'pro' | '1c-2g' | '2c-4g' | '4c-8g' | '8c-16g': The compute plan to use. `starter`, `standard` and `pro` are deprecated.
    - string
  - `timeoutSeconds` integer: Maximum sandbox lifetime in seconds. Sandbox is terminated when reached. Use 0 for no timeout.
  - `idleTimeoutSeconds` integer: Seconds of inactivity before the sandbox is suspended. Use 0 to disable automatic idle suspension. Positive values must be at least 300.
  - `env` object: Inline environment variables injected into the sandbox at creation.
  - `snapshotId` Schema (unresolved $ref)
  - `snapshotName` Name (unresolved $ref)

## Response `201`

Sandbox created. Returns the initial sandbox snapshot.

- object
  - `id` Schema, required (unresolved $ref)
  - `sandboxGroupId` Schema (unresolved $ref)
  - `status` Items, required (unresolved $ref)
  - `plan` string, required: Compute plan. See `sandboxPlan` for known values.
  - `networkPolicy` object, required
    - `type` 0, required (unresolved $ref)
    - `default` 0 (unresolved $ref)
    - `rules` Items[]: Destinations the sandbox may reach, present when `type` is `allow-list` and absent otherwise. Each domain may be listed once. (unresolved $ref)
  - `region` string, required: Region the sandbox is running in.
  - `timeoutSeconds` integer, required: Maximum sandbox lifetime in seconds. 0 means the sandbox has no timeout.
  - `idleTimeoutSeconds` integer, required: Seconds of inactivity before the sandbox is suspended. 0 disables automatic idle suspension.
  - `createdAt` string, date-time, required
  - `terminatedAt` string, date-time, nullable: When the sandbox was terminated, or null.

## Other responses

- `400`: The request could not be understood by the server.
- `401`: Authorization information is missing or invalid.
- `403`: You do not have permissions for the requested resource. If a scoped API token does not satisfy the endpoint's minimum scope requirements, the response has code insufficient_token_scope and its message lists all minimum required scopes. Broader scopes that include their permissions also satisfy the requirements. Passing this check does not guarantee access to the requested resource or to conditional operations.
- `404`: Unable to find the requested resource.
- `409`: The current state of the resource conflicts with this request.
- `429`: Rate limit has been surpassed. Rate-limited endpoints also return `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` on successful responses so clients can track their remaining quota.
- `500`: An unexpected server error has occurred.
- `503`: Server currently unavailable.

## Changes

- **2026-11-03** `6ac5d3d47362`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/render/apis/render-public-api/changes/sandboxes/post.md)

---

[API](https://skmtc.dev/render/apis/render-public-api.md) - [All operations](https://skmtc.dev/render/apis/render-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/render/apis/render-public-api/revisions/6ac5d3d47362?raw)
