> ## 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.

# Initialize a Template build-context upload

> Creates an immutable tar/tgz build context and returns a staging upload
session. Upload the archive directly with a single HTTP PUT to the
returned URL and poll the returned status URL; there is no
client-visible complete operation. The platform verifies the uploaded
object and imports it into the selected IDC. Backend identity and
storage object identifiers are never exposed. Maximum declared size is
1 GiB. `Idempotency-Key` is required. A replay returns the same file
ID. While the file is still awaiting upload and the archive has not
been received yet, the replay issues a fresh upload session for the
same staging object; if the archive has already been received, or the
file has advanced past `awaiting_upload`, `upload` is omitted and
callers should poll `status_url`. Once the file is `failed` or
`expired`, or its upload deadline has passed, the key is consumed and
the replay returns 409 `Sandbox.IdempotentKeyConsumed` — create a new
file with a new key.




## OpenAPI

````yaml /api-spec/sandbox_api.yaml post /templates/{template_id}/files
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}/files:
    parameters:
      - $ref: '#/components/parameters/TemplateBuildTemplateIdPathParam'
      - $ref: '#/components/parameters/IdcNameQueryParam'
    post:
      tags:
        - SandboxTemplate
      summary: Initialize a Template build-context upload
      description: |
        Creates an immutable tar/tgz build context and returns a staging upload
        session. Upload the archive directly with a single HTTP PUT to the
        returned URL and poll the returned status URL; there is no
        client-visible complete operation. The platform verifies the uploaded
        object and imports it into the selected IDC. Backend identity and
        storage object identifiers are never exposed. Maximum declared size is
        1 GiB. `Idempotency-Key` is required. A replay returns the same file
        ID. While the file is still awaiting upload and the archive has not
        been received yet, the replay issues a fresh upload session for the
        same staging object; if the archive has already been received, or the
        file has advanced past `awaiting_upload`, `upload` is omitted and
        callers should poll `status_url`. Once the file is `failed` or
        `expired`, or its upload deadline has passed, the key is consumed and
        the replay returns 409 `Sandbox.IdempotentKeyConsumed` — create a new
        file with a new key.
      operationId: createTemplateFile
      parameters:
        - $ref: '#/components/parameters/TemplateFileIdempotencyKeyRequiredParam'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateTemplateFileRequest'
      responses:
        '201':
          description: |
            Staging upload session initialized, or the original result replayed.
            Replays include `Idempotency-Replayed: true`.
          headers:
            Idempotency-Replayed:
              schema:
                type: string
                enum:
                  - 'true'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TemplateFileUploadResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: >
            The file created under this Idempotency-Key is `failed` or
            `expired`,

            or its upload deadline has passed; the key is consumed. Retry with a

            new Idempotency-Key to create a new file.


            Also returned as `IDC.UnderMaintenance` when the selected IDC is
            under maintenance; write operations are rejected until the IDC is
            usable again.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '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
    TemplateFileIdempotencyKeyRequiredParam:
      name: Idempotency-Key
      in: header
      required: true
      description: |
        Caller-generated key that makes Template file initialization safe to
        retry. Matched byte-for-byte: 1-64 printable ASCII characters with no
        whitespace. The key is scoped to the organization and Template and is
        retained with the Template file lifecycle. A different request body
        under the same key returns 400 Sandbox.IdempotentParameterMismatch.
      schema:
        type: string
        minLength: 1
        maxLength: 64
  schemas:
    CreateTemplateFileRequest:
      type: object
      additionalProperties: false
      required:
        - name
        - content_type
        - sha256
        - size_bytes
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
        content_type:
          type: string
          enum:
            - tar
            - tgz
        sha256:
          type: string
          pattern: ^[0-9a-fA-F]{64}$
        size_bytes:
          type: integer
          format: int64
          minimum: 1
          maximum: 1073741824
    TemplateFileUploadResponse:
      type: object
      additionalProperties: false
      required:
        - request_id
        - data
      properties:
        request_id:
          type: string
        data:
          $ref: '#/components/schemas/TemplateFileUpload'
    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
    TemplateFileUpload:
      type: object
      additionalProperties: false
      required:
        - id
        - state
        - status_url
      properties:
        id:
          type: string
          format: uuid
        state:
          type: string
          enum:
            - awaiting_upload
            - verifying
            - importing
            - ready
            - failed
            - expired
        status_url:
          type: string
        upload:
          type: object
          description: Present only while the file is still awaiting upload.
          additionalProperties: false
          required:
            - method
            - url
            - headers
            - expires_at
          properties:
            method:
              type: string
              enum:
                - PUT
            url:
              type: string
              format: uri
            headers:
              type: object
              additionalProperties:
                type: string
            expires_at:
              type: string
              format: date-time
  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
    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.