> ## 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 and start a rebuild

> Creates a new Build from the given definition and starts it immediately.
A rebuild inherits the most recent Build's IDC placement and resources, so a
Template with no Build records left has nothing to inherit and returns
409. Not supported in every IDC; IDCs without rebuild support reject it with 422.

A rebuild supersedes the Template's still-running Builds: each one is
finalized as `error` with failure code `TemplateBuild.Superseded`, its
backing build in the selected IDC is cancelled, and its partial
artifacts are reclaimed, best-effort. When the new Build turns `ready`
it becomes the Template's default Build; the previously bound Build's
artifact is then reclaimed where the selected IDC permits it (an
artifact still referenced by dependent resources is retained and
reclaimed on Template deletion instead). If the new Build fails, the
previous binding is unchanged.

This operation is not idempotent and does not accept an `Idempotency-Key`
header. Every call creates a new Build and supersedes the running ones, so
before retrying a request whose outcome is unknown, check
`GET /templates/{template_id}/builds` for the Build it may already have created.




## OpenAPI

````yaml /api-spec/sandbox_api.yaml post /templates/{template_id}/builds
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:
  /templates/{template_id}/builds:
    parameters:
      - $ref: '#/components/parameters/TemplateBuildTemplateIdPathParam'
    post:
      tags:
        - SandboxTemplate
      summary: Create and start a rebuild
      description: >
        Creates a new Build from the given definition and starts it immediately.

        A rebuild inherits the most recent Build's IDC placement and resources,
        so a

        Template with no Build records left has nothing to inherit and returns

        409. Not supported in every IDC; IDCs without rebuild support reject it
        with 422.


        A rebuild supersedes the Template's still-running Builds: each one is

        finalized as `error` with failure code `TemplateBuild.Superseded`, its

        backing build in the selected IDC is cancelled, and its partial

        artifacts are reclaimed, best-effort. When the new Build turns `ready`

        it becomes the Template's default Build; the previously bound Build's

        artifact is then reclaimed where the selected IDC permits it (an

        artifact still referenced by dependent resources is retained and

        reclaimed on Template deletion instead). If the new Build fails, the

        previous binding is unchanged.


        This operation is not idempotent and does not accept an
        `Idempotency-Key`

        header. Every call creates a new Build and supersedes the running ones,
        so

        before retrying a request whose outcome is unknown, check

        `GET /templates/{template_id}/builds` for the Build it may already have
        created.
      operationId: createTemplateBuild
      parameters:
        - $ref: '#/components/parameters/IdcNameQueryParam'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BuildDefinition'
      responses:
        '201':
          description: |
            The Build record is created and immediately addressable via
            `GET /templates/{template_id}/builds/{id}`; build progress is
            reported by `status`, not by the status code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TemplateBuildMutation'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: >
            State conflict (`Resource.StateConflict` or an operation-specific
            code), or the selected IDC is under maintenance
            (`IDC.UnderMaintenance`): write operations are rejected until the
            IDC is usable again. Read operations are unaffected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          $ref: '#/components/responses/Unsupported'
        '429':
          $ref: '#/components/responses/QuotaExceeded'
        '499':
          $ref: '#/components/responses/RequestCanceled'
        '500':
          $ref: '#/components/responses/InternalError'
        '504':
          $ref: '#/components/responses/RequestTimeout'
components:
  parameters:
    TemplateBuildTemplateIdPathParam:
      name: template_id
      in: path
      required: true
      description: Owning GMI Template identifier.
      schema:
        type: string
        format: uuid
    IdcNameQueryParam:
      name: idc_name
      in: query
      description: Filter by data center name, e.g. us-denver-1
      schema:
        type: string
  schemas:
    BuildDefinition:
      type: object
      additionalProperties: false
      required:
        - source
      properties:
        default_user:
          $ref: '#/components/schemas/TemplateDefaultUser'
        source:
          $ref: '#/components/schemas/BuildSource'
        commands:
          type: array
          maxItems: 100
          description: >
            Shell command strings executed sequentially during the Build. They
            may

            run as a non-root account with passwordless sudo: prefix privileged

            commands with `sudo`, and set ownership of files that the runtime

            account must use. To control the build identity explicitly, use a

            Dockerfile source with `USER` instructions, as in a regular
            Dockerfile.
          items:
            type: string
            minLength: 1
            maxLength: 8192
        envs:
          type: object
          maxProperties: 256
          additionalProperties:
            type: string
            maxLength: 32768
          description: >
            Environment variables available only during the Template Build.

            They are visible to subsequent build commands/steps and are not
            persisted

            into the resulting template artifact as sandbox runtime environment

            variables. Pass runtime env when creating a Sandbox instead.
            Write-only:

            values are never returned on Template or TemplateBuild responses.

            Keys must be unique (JSON object); the server orders them

            deterministically by key. Key names must match

            `[A-Za-z_][A-Za-z0-9_]*`.
        build_timeout_sec:
          type: integer
          minimum: 60
          maximum: 3600
          description: |
            Wall-clock budget for this Build in seconds. Omit or null to use the
            platform default (600). Allowed range: 60–3600. On expiry the Build
            is finalized as `error` with failure code `TemplateBuild.TimedOut`,
            its backing build in the selected IDC is cancelled, and its partial
            artifacts are reclaimed, best-effort.
        start_cmd:
          type: string
          minLength: 1
          maxLength: 8192
          description: >
            Launch command persisted with the Build and applied when Sandboxes

            created from this Template start.


            It runs as a boot script before the sandbox's main process, and the

            sandbox only becomes ready once it returns, so the command must

            terminate. A foreground long-running command (`sleep infinity`, a

            server started in the foreground) leaves the Sandbox stuck

            initializing and every exec against it rejected.


            Appending `&` alone is not sufficient: a backgrounded process that

            still holds the inherited stdout/stderr keeps boot blocked just the

            same. Long-running processes must be backgrounded *and* detached

            from those streams, e.g.

            `my-server > /var/log/my-server.log 2>&1 &`.


            Resume continues the saved processes without re-running this
            command.
        file_context:
          $ref: '#/components/schemas/TemplateFileContext'
    TemplateBuildMutation:
      type: object
      additionalProperties: false
      required:
        - request_id
        - data
      properties:
        request_id:
          type: string
          description: HTTP request correlation identifier.
        data:
          type: object
          additionalProperties: false
          required:
            - id
            - template_id
            - status
          properties:
            id:
              type: string
              description: The Build this mutation created or started.
            template_id:
              type: string
              description: Owning GMI Template identifier.
            status:
              $ref: '#/components/schemas/BuildStatus'
    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
    TemplateDefaultUser:
      type: object
      additionalProperties: false
      required:
        - username
      description: >
        Runtime default identity for Sandboxes launched from this Build.

        Without it, Sandboxes run as `docker run` would: as the Dockerfile's
        final

        USER, else the image's USER, else root, in the final WORKDIR, else the

        image's, else `/`.

        Sandboxes run commands as a named account: an image USER given as a

        numeric uid (or uid:gid) needs a matching /etc/passwd entry in the
        image,

        otherwise the Build fails with a reason that names the USER. The group

        part is ignored.

        It is applied after all build commands and overrides the final
        Dockerfile

        USER at runtime; it does not change the identity of earlier build
        commands.


        Recommended setup for a custom account: create it in the Dockerfile,
        give

        it a working directory it can access, and pass its uid, for example

        `RUN useradd --uid 9999 --create-home --shell /bin/bash app`,

        `WORKDIR /home/app`, and `default_user: {username: app, uid: 9999}`.


        - default_user changes the identity only, not the working directory or
        its
          permissions. If the account cannot enter the final working directory,
          commands cannot start there and the Build may fail; declare an
          accessible WORKDIR to fix it.
        - With uid, the account must already exist with that UID and an existing
          home directory; otherwise the Build fails. The platform does not change
          UID, ownership, groups, or sudo privileges.
        - A non-root username without uid may be rejected with HTTP 422
          (Template.ProviderNotSupported); supply uid to avoid this. root may omit uid.
        - Invalid username, out-of-range uid, or root with a nonzero uid returns
          HTTP 400 (Parameter.Invalid).
        - A Build from a base template keeps the base template's user and
        working
          directory, as Docker FROM does; set default_user on the child Build to
          select another. Changing it requires a new Build.

        When omitted, the template's default runtime identity is used. A Build

        response reports the requested setting; an omitted uid stays omitted.
      properties:
        username:
          type: string
          minLength: 1
          maxLength: 32
          pattern: ^[a-z_][a-z0-9_-]{0,31}$
          example: app
        uid:
          type: integer
          format: int32
          minimum: 0
          maximum: 2147483647
          description: >-
            UID of the account. Recommended for non-root usernames. root only
            accepts 0.
          example: 9999
    BuildSource:
      oneOf:
        - $ref: '#/components/schemas/ImageSource'
        - $ref: '#/components/schemas/TemplateSource'
        - $ref: '#/components/schemas/DockerfileSource'
      discriminator:
        propertyName: type
        mapping:
          image: '#/components/schemas/ImageSource'
          template: '#/components/schemas/TemplateSource'
          dockerfile: '#/components/schemas/DockerfileSource'
      description: Manual Build source. Sandbox sources use the snapshot endpoint.
    TemplateFileContext:
      type: object
      additionalProperties: false
      required:
        - file_id
      properties:
        file_id:
          type: string
          format: uuid
          description: GMI file identifier returned by the upload initialization endpoint.
        destination:
          type: string
          minLength: 1
          maxLength: 4096
          pattern: ^/
          description: |
            Absolute destination copied from the archive root during the Build.
            Required for image/template sources; forbidden for a dockerfile
            source, whose `COPY {{file:...}} /dest` lines carry their own
            destinations.
    BuildStatus:
      type: string
      enum:
        - waiting
        - building
        - ready
        - error
      description: Normalized Template Build status.
    ImageSource:
      type: object
      additionalProperties: false
      required:
        - type
        - image
      properties:
        type:
          type: string
          enum:
            - image
        image:
          type: string
          minLength: 1
          description: |
            OCI container image reference. The following distributions have
            been validated: Debian/Ubuntu, Fedora/CentOS Stream/Rocky Linux/
            AlmaLinux, Arch Linux, and Alpine Linux.
        registry_credential:
          $ref: '#/components/schemas/GeneralRegistryCredential'
    TemplateSource:
      type: object
      additionalProperties: false
      required:
        - type
        - template_id
      properties:
        type:
          type: string
          enum:
            - template
        template_id:
          type: string
          description: Parent GMI Template identifier in the same IDC.
        build_id:
          type: string
          description: |
            Optional parent Build identifier. When omitted, the parent's
            current successful Build is used.
    DockerfileSource:
      type: object
      additionalProperties: false
      required:
        - type
        - dockerfile
      properties:
        type:
          type: string
          enum:
            - dockerfile
        dockerfile:
          type: string
          minLength: 1
          maxLength: 262144
          description: >
            Raw Dockerfile text. Supported instructions: FROM (exactly one; no

            multi-stage), RUN, ENV, WORKDIR, USER, COPY/ADD, CMD/ENTRYPOINT;

            EXPOSE and VOLUME are skipped; anything else is rejected with 400.


            A trailing backslash continues an instruction on the next line;
            blank

            and comment lines inside a continuation are skipped.


            The Dockerfile's final USER is the runtime identity of Sandboxes
            unless

            `default_user` is set. A Build fails when that account cannot enter
            the

            final working directory; declare an accessible WORKDIR.


            COPY/ADD sources must reference an uploaded Template file as

            `COPY {{file:<file_id>}} /dest` — local paths and URLs are

            rejected, and at most one file may be referenced per build (its

            `file_id` must also be attached via `file_context`, with

            `file_context.destination` omitted).


            With a dockerfile source, the sibling `commands` and `envs` fields

            are forbidden: write RUN/ENV lines in the Dockerfile instead.

            CMD/ENTRYPOINT are extracted into the Build's start command; an

            explicit `start_cmd` takes precedence over them.


            ENV values are visible to subsequent build steps and are part of

            the sandbox runtime environment, as under `docker run`; a value

            passed as `env_vars` when creating a Sandbox overrides one of the

            same name. Do not put build-time secrets in ENV: build the Template

            from an image or template source and pass them in `envs`, which

            reach the build steps only.
    GeneralRegistryCredential:
      type: object
      additionalProperties: false
      required:
        - type
        - username
        - password
      description: >-
        A one-time registry credential used to pull the private image named by
        `image`. `username` and `password` are used only for this build request:
        they are never persisted and never returned in any response. The Build
        detail's `registry_authentication` reports only whether a credential was
        used and of what kind, never the username or password.
      properties:
        type:
          type: string
          enum:
            - general
        username:
          type: string
        password:
          type: string
          description: Can be a password or an access token.
  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
    Unsupported:
      description: |
        The request is valid but the selected IDC does not support
        the requested capability or resolved resource specification.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    QuotaExceeded:
      description: The configured or temporary resource quota would be exceeded.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    RequestCanceled:
      description: The caller canceled the current HTTP request.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            code: Request.Canceled
            message: Request canceled
            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
    RequestTimeout:
      description: The current HTTP request exceeded the control-plane processing deadline.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            code: Request.Timeout
            message: Request timed out
            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.