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

# Export the filesystem changes to a presigned URL

> Archives everything the sandbox changed on top of its base image and streams it, uncompressed, to a presigned S3 PUT URL. The memory of the sandbox is not archived.
The sandbox is quiesced first: the process list is saved (unless saveProcesses is false), every process is stopped, and the API then refuses the calls that would write to the filesystem. The freeze is not lifted afterwards, since an exported sandbox is meant to be restored elsewhere; call POST /archive/resume to lift it.
Use dryRun to get the archive's content and exact size without stopping anything and without uploading.
Set async to start the export and answer immediately, which is what archiving a large filesystem needs: the export then reports itself through GET /archive/status.



## OpenAPI

````yaml https://raw.githubusercontent.com/blaxel-ai/sandbox/refs/heads/main/sandbox-api/docs/openapi.yml post /archive/export
openapi: 3.0.0
info:
  contact: {}
  description: API for manipulating filesystem, processes and network.
  title: Sandbox API
  version: 0.0.1
servers:
  - url: https://sbx-{sandbox_id}-{workspace_id}.{region}.bl.run
    variables:
      sandbox_id:
        default: unknown
      workspace_id:
        default: unknown
      region:
        default: unknown
security:
  - BearerAuth: []
paths:
  /archive/export:
    post:
      tags:
        - archive
      summary: Export the filesystem changes to a presigned URL
      description: >-
        Archives everything the sandbox changed on top of its base image and
        streams it, uncompressed, to a presigned S3 PUT URL. The memory of the
        sandbox is not archived.

        The sandbox is quiesced first: the process list is saved (unless
        saveProcesses is false), every process is stopped, and the API then
        refuses the calls that would write to the filesystem. The freeze is not
        lifted afterwards, since an exported sandbox is meant to be restored
        elsewhere; call POST /archive/resume to lift it.

        Use dryRun to get the archive's content and exact size without stopping
        anything and without uploading.

        Set async to start the export and answer immediately, which is what
        archiving a large filesystem needs: the export then reports itself
        through GET /archive/status.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExportOptions'
        description: Export options
        required: true
      responses:
        '200':
          description: Export result
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExportResult'
        '202':
          description: The export was started and runs in the background
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExportProgress'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: An export is already in progress
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Export failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    ExportOptions:
      properties:
        async:
          description: >-
            Async starts the export and answers immediately, leaving it to run:
            an

            archive of a large filesystem takes longer than a request may be
            held

            open. Its progress is reported by /archive/status.
          example: false
          type: boolean
        dryRun:
          description: |-
            DryRun reports what would be archived, and its exact size, without
            stopping anything and without uploading.
          example: false
          type: boolean
        excludes:
          description: Excludes are added to the paths excluded by default.
          items:
            type: string
          type: array
        headers:
          additionalProperties:
            type: string
          description: >-
            Headers are sent with the upload request as given. A presigned URL
            only

            accepts the headers it was signed for, so these have to match what
            the

            caller signed: sending one that was not signed, or signing one that
            is not

            sent, is rejected as a signature mismatch. Typical use is a storage
            class,

            x-amz-storage-class: GLACIER_IR.
          type: object
        imageDevice:
          description: >-
            ImageDevice is the device holding the pristine image, /dev/vda by
            default.

            A generation that attaches the image elsewhere names its device
            here.
          example: /dev/vda
          type: string
        imageMountPoint:
          description: >-
            ImageMountPoint is a directory where the pristine image is already
            mounted.

            When set the image device is neither mounted nor unmounted.
          example: /mnt/lower
          type: string
        multipart:
          allOf:
            - $ref: '#/components/schemas/MultipartUpload'
          description: >-
            Multipart uploads the archive part by part instead, which is how an

            archive larger than the 5 GB a single PUT accepts is stored. It
            takes

            precedence over URL.
        saveProcesses:
          description: |-
            SaveProcesses stores the process list in the archive so restore can
            relaunch the workload. Defaults to true; set it to false to archive
            storage only.
          example: true
          type: boolean
        stopTimeoutSeconds:
          description: StopTimeoutSeconds bounds the graceful stop of each process.
          example: 30
          type: integer
        url:
          description: >-
            URL is a presigned S3 PUT URL the archive is streamed to. Empty is
            only

            valid with DryRun, or with Multipart.
          example: https://bucket.s3.amazonaws.com/key?...
          type: string
      type: object
    ExportResult:
      properties:
        changes:
          description: |-
            Changes lists every path in the archive. Only filled for a dry run,
            where it is the point of the call.
          items:
            $ref: '#/components/schemas/archive.Change'
          type: array
        duration:
          example: 4.2s
          type: string
        manifest:
          $ref: '#/components/schemas/ArchiveManifest'
        size:
          description: |-
            Size is the exact number of bytes uploaded, known before the upload
            starts since the archive is not compressed.
          example: 3074211
          type: integer
        stoppedProcesses:
          description: StoppedProcesses are the processes stopped to freeze the filesystem.
          items:
            type: string
          type: array
        uploaded:
          description: Uploaded is false for a dry run.
          example: true
          type: boolean
      required:
        - manifest
      type: object
    ExportProgress:
      properties:
        error:
          description: Error is why the export failed, without the presigned URL it used.
          type: string
        finishedAt:
          type: string
        size:
          description: >-
            Size is the archive's exact size, known once the filesystem is
            scanned.
          example: 3074211
          type: integer
        startedAt:
          type: string
        state:
          allOf:
            - $ref: '#/components/schemas/archive.ExportState'
          example: running
        uploaded:
          description: Uploaded reports whether the storage holds the archive.
          example: false
          type: boolean
      type: object
    ErrorResponse:
      properties:
        error:
          example: Error message
          type: string
      required:
        - error
      type: object
    MultipartUpload:
      properties:
        abortUrl:
          description: >-
            AbortURL is a presigned DELETE URL that discards the parts already

            uploaded. Without it a failed export leaves them on the storage
            until a

            lifecycle rule removes them.
          type: string
        completeUrl:
          description: CompleteURL is a presigned POST URL that assembles the parts.
          type: string
        partSize:
          description: PartSize is the number of bytes sent to every part but the last.
          example: 536870912
          type: integer
        partUrls:
          description: >-
            PartURLs are presigned PUT URLs, one per part, in order. Extra ones
            are

            left unused.
          items:
            type: string
          type: array
      type: object
    archive.Change:
      properties:
        kind:
          allOf:
            - $ref: '#/components/schemas/archive.ChangeKind'
          example: added
        path:
          description: Path is relative to the root, without a leading slash.
          example: usr/bin/curl
          type: string
        size:
          description: >-
            Size is the file content size in bytes, 0 for anything but a regular
            file.
          example: 256216
          type: integer
      required:
        - kind
        - path
      type: object
    ArchiveManifest:
      properties:
        added:
          description: Added and Modified count the archive's payload members.
          example: 11
          type: integer
        apiVersion:
          description: APIVersion is the sandbox-api build that produced the archive.
          example: v0.1.0
          type: string
        createdAt:
          type: string
        deleted:
          description: >-
            Deleted are paths the image has and the sandbox deleted. Tar cannot
            carry

            a deletion, so import applies these from the manifest.
          items:
            type: string
          type: array
        excludes:
          description: Excludes are the paths left out of the comparison.
          items:
            type: string
          type: array
        imageDevice:
          description: >-
            ImageDevice is the device the pristine image was read from, for the
            record:

            it says which generation exported the archive (/dev/vda on mk3.1).
          example: /dev/vda
          type: string
        modified:
          example: 3
          type: integer
        payloadBytes:
          description: PayloadBytes is the total content size of the payload members.
          example: 3073449
          type: integer
        processes:
          description: Processes tells whether ProcessesName is present.
          example: true
          type: boolean
        root:
          description: Root is the directory the paths are relative to.
          example: /
          type: string
        version:
          example: 1
          type: integer
      required:
        - createdAt
        - root
        - version
      type: object
    archive.ExportState:
      enum:
        - running
        - succeeded
        - failed
      type: string
      x-enum-varnames:
        - ExportRunning
        - ExportSucceeded
        - ExportFailed
    archive.ChangeKind:
      enum:
        - added
        - modified
        - deleted
      type: string
      x-enum-varnames:
        - ChangeAdded
        - ChangeModified
        - ChangeDeleted
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

````