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

# Create a durable snapshot

> Creates a durable snapshot from a running sandbox in the current tenant.
The snapshot can be queried immediately, while creation completes asynchronously.
Poll GET /snapshots/{snapshot_id} until `status` becomes `ready` or `error`.
A ready snapshot can be supplied as `snapshot_id` to POST /sandboxes.
A snapshot captures the sandbox filesystem only: running processes and
in-memory state are not preserved, and a sandbox created from it boots fresh
from the saved disk. The source sandbox keeps running.
If snapshot creation is unsupported for the source sandbox, the request
returns 422 `Snapshot.UnsupportedOnProvider`.

`Idempotency-Key` is optional. Within the 24-hour deduplication window,
repeating a key with identical parameters returns the same snapshot with its
current status and `Idempotency-Replayed: true`, including while `creating`
and after it becomes `ready`. Different parameters return 400
`Sandbox.IdempotentParameterMismatch`. Without the header, no deduplication
is performed.

The source sandbox must be `running`, otherwise 409 `Snapshot.SourceNotRunning`.
While another snapshot of the same sandbox is being created, a new request
may return 409 `Snapshot.CreateInProgress`, including temporarily after a
previous snapshot was cancelled with DELETE. Wait before retrying and ensure
the source sandbox is `running`.

A definitive snapshot creation failure returns 201 with a queryable snapshot in
`error` and `failure_code: Snapshot.ProviderCreateFailed`. Replaying that
key returns the same error snapshot without creating another.

Some failed creation attempts consume the idempotency key; replay returns
409 `Sandbox.IdempotentKeyConsumed`. Error details include `failure_code`
and `snapshot_id`; the failed snapshot remains readable through GET.
Retry with a new `Idempotency-Key`. A deleted snapshot also consumes its
original key.

Non-empty names are case-sensitive and unique within the organization across
all IDCs. A name held by another snapshot returns 409 `Resource.AlreadyExists`.
Empty names may be shared. Creation failure clears the name atomically;
the failed record remains readable by snapshot_id. Use a new Idempotency-Key
to retry with the same name once the source sandbox is running again.
Name release does not change whether a key can be replayed. A definitive
Snapshot.ProviderCreateFailed result remains replayable and returns the
current record, whose name is cleared on failure. Failures detected while
the create request is being handled, such as a source lease or workflow
handoff failure, consume the key; replay returns 409
Sandbox.IdempotentKeyConsumed without a snapshot record. Failures settled
later in the background, such as a failed creation workflow or an expired
creation deadline, leave the key replayable; replay returns the current
error record with its cleared name.
Use snapshot_id to query a failed attempt; use a new key to create another.




## OpenAPI

````yaml /api-spec/sandbox_api.yaml post /snapshots
openapi: 3.0.3
info:
  title: GMI Sandbox API
  description: >-
    REST API for GMI Sandbox: create isolated execution environments from
    templates or durable snapshots, manage their lifecycle on the control plane,
    and run commands or transfer files through each sandbox's own data plane.
  contact:
    name: GMI Cloud Support
    email: support@gmicloud.ai
  version: '2.0'
servers:
  - url: https://console.gmicloud.ai/api/v2
    description: Control plane
security:
  - bearerAuth: []
tags:
  - name: Sandbox
    description: |
      Sandbox instance lifecycle management (Sandbox v2, /api/v2/sandboxes)
  - name: SandboxSnapshot
    description: Durable sandbox snapshot management (Sandbox v2, `/api/v2/snapshots`)
  - name: SandboxTemplate
    description: Sandbox template management (Sandbox v2, `/api/v2/templates`)
  - name: Sandbox-Exec
    description: >
      Sandbox execution data plane (accessed via the sandbox host and sandbox
      access token). These endpoints are not under the control plane's `/api/v2`
      path; clients connect directly to `https://{sandbox_key}.{domain}` and
      authenticate with `X-Access-Token`.
  - name: Sandbox-Shell
    description: >
      Sandbox interactive terminal (PTY) data plane. **These endpoints are not
      under `/api/v2`**: clients connect directly to
      `https://{sandbox_key}.{domain}` and authenticate with `X-Access-Token`.
      `{sandbox_key}`, `{domain}` and the `X-Access-Token` value are the
      `sandbox_key`, `domain` and `sandbox_access_token` returned by the
      control-plane create/connect endpoints; no extra endpoint is needed.


      Each sandbox has exactly **one logical shell session** and at most **one
      active WebSocket connection** at a time (a second concurrent attach is
      refused at handshake with `409`). Disconnecting does not destroy the shell
      — re-attaching resumes the same session; only `POST /shell/control` with
      `action=close` destroys it.
  - name: Sandbox-Files
    description: >
      Sandbox file data plane (`/files`). **These endpoints are not under
      `/api/v2`** and do not use `Authorization: Bearer`: they are served by the
      sandbox's own data-plane entry point — clients connect directly to
      `https://{sandbox_key}.{domain}` and authenticate with `X-Access-Token`.
      `{sandbox_key}` is the `sandbox_key` returned by the create/connect
      endpoints, used for data-plane host addressing. `{domain}` and
      `X-Access-Token` are the `domain` and `sandbox_access_token` from the same
      responses — no extra endpoint is needed to obtain them.


      This split is not historical baggage but the nature of a data plane: file
      transfer is long-lived, high-volume, and addressed per sandbox, differing
      from the control plane's short requests in both capacity model and failure
      domain, so they do not share an entry point.


      **One unified abstraction.** The same contract is served by two backend
      kinds (an in-sandbox file service / a data-center data-plane proxy);
      clients need not — and cannot — tell them apart. The cost is that the
      contract is their intersection: `Content-Length` on download and resumable
      download (`Range`/`206`) are **optional capabilities** that vary by data
      center, and clients must work correctly when they are absent. See the
      per-operation notes below.
paths:
  /snapshots:
    post:
      tags:
        - SandboxSnapshot
      summary: Create a durable snapshot
      description: >
        Creates a durable snapshot from a running sandbox in the current tenant.

        The snapshot can be queried immediately, while creation completes
        asynchronously.

        Poll GET /snapshots/{snapshot_id} until `status` becomes `ready` or
        `error`.

        A ready snapshot can be supplied as `snapshot_id` to POST /sandboxes.

        A snapshot captures the sandbox filesystem only: running processes and

        in-memory state are not preserved, and a sandbox created from it boots
        fresh

        from the saved disk. The source sandbox keeps running.

        If snapshot creation is unsupported for the source sandbox, the request

        returns 422 `Snapshot.UnsupportedOnProvider`.


        `Idempotency-Key` is optional. Within the 24-hour deduplication window,

        repeating a key with identical parameters returns the same snapshot with
        its

        current status and `Idempotency-Replayed: true`, including while
        `creating`

        and after it becomes `ready`. Different parameters return 400

        `Sandbox.IdempotentParameterMismatch`. Without the header, no
        deduplication

        is performed.


        The source sandbox must be `running`, otherwise 409
        `Snapshot.SourceNotRunning`.

        While another snapshot of the same sandbox is being created, a new
        request

        may return 409 `Snapshot.CreateInProgress`, including temporarily after
        a

        previous snapshot was cancelled with DELETE. Wait before retrying and
        ensure

        the source sandbox is `running`.


        A definitive snapshot creation failure returns 201 with a queryable
        snapshot in

        `error` and `failure_code: Snapshot.ProviderCreateFailed`. Replaying
        that

        key returns the same error snapshot without creating another.


        Some failed creation attempts consume the idempotency key; replay
        returns

        409 `Sandbox.IdempotentKeyConsumed`. Error details include
        `failure_code`

        and `snapshot_id`; the failed snapshot remains readable through GET.

        Retry with a new `Idempotency-Key`. A deleted snapshot also consumes its

        original key.


        Non-empty names are case-sensitive and unique within the organization
        across

        all IDCs. A name held by another snapshot returns 409
        `Resource.AlreadyExists`.

        Empty names may be shared. Creation failure clears the name atomically;

        the failed record remains readable by snapshot_id. Use a new
        Idempotency-Key

        to retry with the same name once the source sandbox is running again.

        Name release does not change whether a key can be replayed. A definitive

        Snapshot.ProviderCreateFailed result remains replayable and returns the

        current record, whose name is cleared on failure. Failures detected
        while

        the create request is being handled, such as a source lease or workflow

        handoff failure, consume the key; replay returns 409

        Sandbox.IdempotentKeyConsumed without a snapshot record. Failures
        settled

        later in the background, such as a failed creation workflow or an
        expired

        creation deadline, leave the key replayable; replay returns the current

        error record with its cleared name.

        Use snapshot_id to query a failed attempt; use a new key to create
        another.
      operationId: createSandboxSnapshot
      parameters:
        - $ref: '#/components/parameters/IdempotencyKeyOptionalParam'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateSandboxSnapshotRequest'
      responses:
        '201':
          description: >-
            Snapshot record is addressable; status may be creating, ready, or
            error.
          headers:
            Idempotency-Replayed:
              description: Present and true when the original request was replayed.
              schema:
                type: boolean
            Idempotency-Key:
              description: The accepted idempotency key, when supplied.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SandboxSnapshotResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: >-
            Name conflict (Resource.AlreadyExists), source not running
            (Snapshot.SourceNotRunning), capture in progress
            (Snapshot.CreateInProgress), consumed key
            (Sandbox.IdempotentKeyConsumed), or IDC maintenance
            (IDC.UnderMaintenance).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  parameters:
    IdempotencyKeyOptionalParam:
      name: Idempotency-Key
      in: header
      required: false
      description: |
        Optional caller-generated idempotency key (a UUID is recommended).
        Matched byte-for-byte: 1-64 printable ASCII characters, no whitespace.
        Absent means no deduplication. The same key with a different request
        body returns 400 Sandbox.IdempotentParameterMismatch. Echoed on
        responses; replays add Idempotency-Replayed: true. Keys are remembered
        for 24 hours.
      schema:
        type: string
        minLength: 1
        maxLength: 64
  schemas:
    CreateSandboxSnapshotRequest:
      type: object
      required:
        - sandbox_id
      properties:
        sandbox_id:
          type: string
          format: uuid
        name:
          type: string
          maxLength: 255
          description: >
            Customer-defined name. Leading and trailing whitespace is removed;

            whitespace-only names become empty.

            Non-empty names are unique within the organization across all IDCs;

            conflicts return 409 Resource.AlreadyExists. Creation failure clears
            the name.
        metadata:
          type: object
          additionalProperties:
            type: string
    SandboxSnapshotResponse:
      type: object
      required:
        - request_id
        - data
      properties:
        request_id:
          type: string
        data:
          $ref: '#/components/schemas/SandboxSnapshot'
    ErrorResponse:
      type: object
      required:
        - code
        - message
        - request_id
      properties:
        code:
          type: string
          description: Machine-readable business error code
          example: Resource.QuotaExceeded
        message:
          type: string
          description: Human-readable error description
          example: The resource quota is not enough.
        request_id:
          type: string
          description: Tracing ID
          example: req-xxxx
        trace_id:
          type: string
          description: >-
            Server-side trace identifier for this request; quote it when
            reporting a problem.
        details:
          type: object
          description: Field-level error details
          additionalProperties: true
    SandboxSnapshot:
      type: object
      required:
        - snapshot_id
        - idc_name
        - name
        - status
        - source_sandbox_id
        - source_template_id
        - source_build_id
        - vcpu
        - ram_mb
        - disk_size_mb
        - architecture
        - metadata
        - created_at
        - updated_at
      properties:
        snapshot_id:
          type: string
          format: uuid
          description: Stable durable snapshot identifier.
        idc_name:
          type: string
        name:
          type: string
          maxLength: 255
        status:
          $ref: '#/components/schemas/SandboxSnapshotStatus'
        source_sandbox_id:
          type: string
          format: uuid
        source_template_id:
          type: string
          format: uuid
        source_build_id:
          type: string
          format: uuid
        vcpu:
          type: integer
          format: int64
        ram_mb:
          type: integer
          format: int64
        disk_size_mb:
          type: integer
          format: int64
        architecture:
          type: string
        product:
          type: string
          description: Catalog SKU inherited from the source sandbox, when available.
        product_name:
          type: string
          description: Product display name inherited from the source sandbox.
        metadata:
          type: object
          additionalProperties:
            type: string
        failure_code:
          type: string
          description: Stable failure code, present on creation or deletion failure.
        status_reason:
          type: string
          description: Failure detail, present on creation or deletion failure.
        ready_at:
          type: string
          format: date-time
          description: Time the snapshot became ready.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    SandboxSnapshotStatus:
      type: string
      enum:
        - creating
        - ready
        - error
        - deleting
        - delete_failed
  responses:
    BadRequest:
      description: >-
        Invalid request parameters. Two code families are used:
        `Request.InvalidParameter` for request parsing and format validation
        (unknown or malformed body fields, malformed IDs, invalid enum values,
        out-of-range paging) and `Parameter.Invalid` for business validation
        (for example a template or IDC that cannot be found, or a `timeout` over
        the limit). Unknown or invalid fields inside the `params` of `POST
        /sandboxes/{id}/actions` are reported as `Parameter.Invalid`. Other 400
        codes are specific to an operation, for example `Sandbox.SourceConflict`
        (both or neither of `template_id` and `snapshot_id`) and
        `Sandbox.IdempotentParameterMismatch` (an `Idempotency-Key` reused with
        different parameters). Both code families share the same HTTP status, so
        decide by the `code` value, not the status alone.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            code: Parameter.Invalid
            message: Invalid request parameters
            request_id: req-xxxx
    Unauthorized:
      description: Unauthenticated
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            code: Auth.Unauthorized
            message: Authentication required
            request_id: req-xxxx
    Forbidden:
      description: The caller cannot access the organization-scoped resource.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            code: Resource.NotFound
            message: The requested resource was not found
            request_id: req-xxxx
    UnprocessableEntity:
      description: >-
        The request is valid, but the requested capability is not supported in
        the selected environment.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            code: Template.ProviderNotSupported
            message: The selected IDC does not support this template operation
            request_id: req-xxxx
    InternalError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            code: System.Internal
            message: An internal server error occurred
            request_id: req-xxxx
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >
        API Key or Access Token, always sent as `Authorization: Bearer <token>`.
        The gateway recognizes the token type automatically.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.