> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tensorlake.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Copy Sandbox

> Boot one or more new sandboxes from a running or suspended source, restoring filesystem, memory, and running processes so each copy warm-starts. A running source is copied from the executor hosting it; a suspended source is copied from the snapshot its suspend produced. Copies inherit the source's image, resources, entrypoint, network policy, and exposed ports. Takes no request body.

Boot one or more new sandboxes from a running or suspended source, restoring filesystem, memory, and running processes so each copy warm-starts.

* This path accepts either the sandbox ID or the sandbox name.
* The source must be running or suspended. Any other state returns `400 Bad Request`.
* A running source is copied from the executor hosting it. A suspended source is copied from the snapshot its suspend already produced, so a copy does not leave a new checkpoint behind for you to clean up.
* Copies inherit the source's image, resources, entrypoint, network policy, and exposed ports.
* The request takes no body. `times` and `name` are query parameters.

## Endpoint

```http theme={null}
POST /sandboxes/{sandbox_id}/copy
```

## Example Request

```bash theme={null}
curl -X POST "https://api.tensorlake.ai/sandboxes/<sandbox-id>/copy?times=1" \
  -H "Authorization: Bearer $TENSORLAKE_API_KEY"
```

## Example Response

```json theme={null}
{
  "source_sandbox_id": "sbx_01HK9ZA4MT",
  "sandboxes": [
    {
      "sandbox_id": "sbx_01HKA1B7QP",
      "status": "running",
      "ingress_endpoint": "https://sbx_01HKA1B7QP.sandbox.tensorlake.ai"
    }
  ]
}
```

## Fanning Out

Pass `times` to create several copies from the same source in one call. Each copy is an independent sandbox with its own ID.

```bash theme={null}
curl -X POST "https://api.tensorlake.ai/sandboxes/<sandbox-id>/copy?times=4" \
  -H "Authorization: Bearer $TENSORLAKE_API_KEY"
```

## Naming Copies

Sandbox names are unique per namespace, so copies cannot reuse the source's name. Names are derived instead:

| `name`   | `times` | Source            | Copy names                             |
| -------- | ------- | ----------------- | -------------------------------------- |
| `worker` | 1       | any               | `worker`                               |
| `worker` | 3       | any               | `worker-1`, `worker-2`, `worker-3`     |
| omitted  | 1       | named `build-env` | `build-env-copy`                       |
| omitted  | 2       | named `build-env` | `build-env-copy-1`, `build-env-copy-2` |
| omitted  | any     | unnamed           | unnamed                                |

```bash theme={null}
curl -X POST "https://api.tensorlake.ai/sandboxes/<sandbox-id>/copy?times=3&name=worker" \
  -H "Authorization: Bearer $TENSORLAKE_API_KEY"
```

Naming matters for lifecycle: only named sandboxes can be [suspended and resumed](/sandboxes/lifecycle). An unnamed copy terminates at its idle timeout instead. A named source therefore keeps its copies named by default, so a copy behaves like the sandbox it came from.

Pass `name` explicitly to give an unnamed source's copies a name.

Derived names are validated before any copy is created:

* `400` if a derived name is malformed, or exceeds the 63-character DNS label limit once suffixed. A base that fits on its own can still overflow with `-N` appended.
* `409` if a derived name is already claimed by a live sandbox in the namespace. This is checked up front, so a rejected request creates nothing — re-running the same named fan-out is safe and will not leave partial copies behind.

## Partial Failures

A `200` means every requested copy is running. Two other statuses return the same body shape, so inspect each entry's `status` to see which copies succeeded:

* `422` — one or more copies failed before becoming ready.
* `504` — one or more copies did not become ready within the timeout.

## Related

<CardGroup cols={2}>
  <Card title="Snapshot and Clone" icon="camera" href="/sandboxes/snapshots">
    Capture a reusable artifact and restore it into new sandboxes later.
  </Card>

  <Card title="Lifecycle" icon="arrows-spin" href="/sandboxes/lifecycle">
    Create, suspend, resume, and terminate sandboxes.
  </Card>
</CardGroup>


## OpenAPI

````yaml post /sandboxes/{sandbox_id}/copy
openapi: 3.1.0
info:
  title: Tensorlake API
  description: >-
    Tensorlake Cloud APIs for Sandboxes, Document Ingestion, and Serverless
    Workflows
  license:
    name: ''
  version: 0.1.0
servers:
  - url: https://api.tensorlake.ai/
security:
  - bearerAuth: []
tags:
  - name: Tensorlake Cloud API
    description: >-
      Tensorlake Cloud APIs for Sandboxes, Document Ingestion, and Serverless
      Workflows
paths:
  /sandboxes/{sandbox_id}/copy:
    parameters:
      - name: sandbox_id
        in: path
        description: The running or suspended source sandbox ID or name.
        required: true
        schema:
          type: string
    post:
      tags:
        - sandboxes
      summary: Copy a sandbox
      description: >-
        Boot one or more new sandboxes from a running or suspended source,
        restoring filesystem, memory, and running processes so each copy
        warm-starts. A running source is copied from the executor hosting it; a
        suspended source is copied from the snapshot its suspend produced.
        Copies inherit the source's image, resources, entrypoint, network
        policy, and exposed ports. Takes no request body.
      operationId: copy_sandbox
      parameters:
        - name: times
          in: query
          description: Number of copies to create from the source sandbox. Defaults to 1.
          required: false
          schema:
            type: integer
            minimum: 1
        - name: name
          in: query
          description: >-
            Name for the copies. Used verbatim when `times` is 1, and suffixed
            `-1`..`-N` when it is greater, since sandbox names are unique per
            namespace. When omitted, a named source produces
            `<source-name>-copy` (suffixed the same way) and an unnamed source
            produces unnamed copies. Named copies can be suspended and resumed;
            unnamed ones terminate at their idle timeout.
          required: false
          schema:
            type: string
      responses:
        '200':
          description: All requested sandbox copies are running
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CopySandboxResponse'
        '400':
          description: >-
            Invalid request, the source sandbox is neither running nor
            suspended, or a derived copy name is malformed or exceeds the
            63-character limit
          content:
            text/plain: {}
        '401':
          description: Unauthorized. Invalid or missing credentials
        '403':
          description: Forbidden. You do not have permission to access this resource
        '404':
          description: Source sandbox not found
          content:
            text/plain: {}
        '409':
          description: >-
            A derived copy name is already claimed by a live sandbox in the
            namespace. Rejected before any copy is created.
          content:
            text/plain: {}
        '422':
          description: One or more copies failed before becoming ready
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CopySandboxResponse'
        '500':
          description: Internal server error
          content:
            text/plain: {}
        '504':
          description: One or more copies did not become ready within the timeout
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CopySandboxResponse'
components:
  schemas:
    CopySandboxResponse:
      type: object
      required:
        - source_sandbox_id
        - sandboxes
      properties:
        source_sandbox_id:
          type: string
          description: The sandbox the copies were made from.
        sandboxes:
          type: array
          description: >-
            One entry per requested copy, in creation order. On a 422 or 504 the
            entries report per-copy status, so inspect each one to see which
            copies became ready.
          items:
            $ref: '#/components/schemas/CreateSandboxResponse'
    CreateSandboxResponse:
      type: object
      required:
        - sandbox_id
        - status
      properties:
        sandbox_id:
          type: string
        status:
          $ref: '#/components/schemas/SandboxStatus'
        pending_reason:
          $ref: '#/components/schemas/SandboxPendingReason'
        ingress_endpoint:
          type:
            - string
            - 'null'
          description: Base ingress origin for this sandbox's current placement.
    SandboxStatus:
      type: string
      enum:
        - pending
        - running
        - snapshotting
        - suspending
        - suspended
        - terminated
    SandboxPendingReason:
      type: string
      enum:
        - scheduling
        - waiting_for_container
        - no_executors_available
        - no_resources_available
        - pool_at_capacity
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer

````