Skip to content
LogoLogo

Disks

Disks let you mount an S3-compatible bucket into a sandbox as a filesystem path. Register a bucket once as a named disk, then attach it to any sandbox at create time or live.

Credentials are encrypted at rest (AES-256-GCM) and are never returned in any API response.

Get your API key from https://createos.sh/app/profile. Pass it as X-Api-Key: <token> on every request.

Base URL: https://api.sb.createos.sh


At a glance

  • Base URL: https://api.sb.createos.sh
  • Auth: X-Api-Key: <token> header. Get a token
  • Response envelope: JSend, {"status": "...", "data": ...}

GET /v1/disks

List all disks registered by the caller. Credentials are never included.

Auth required: Yes

Query parameters

ParameterTypeDefaultDescription
limitinteger50Max items to return (maximum 500).
offsetinteger0Pagination offset.

Example

curl https://api.sb.createos.sh/v1/disks \
  -H "X-Api-Key: $CREATEOS_API_KEY"

Success response 200

{
  "status": "success",
  "data": {
    "data": [
      {
        "id": "disk_01KSHT…",
        "name": "my-data",
        "kind": "s3",
        "config": {
          "bucket": "my-data-bucket",
          "endpoint": "https://s3.amazonaws.com",
          "region": "us-east-1",
          "use_path_style": false
        },
        "created_at": "2024-01-15T10:00:00Z"
      }
    ],
    "pagination": { "total": 1, "limit": 50, "offset": 0, "count": 1 }
  }
}

Notable errors: 401 unauthorized. 503 disks feature not configured on this cluster.

POST /v1/disks

Register an S3-compatible bucket as a named disk. The API probes the bucket at registration time (3-second HEAD request) to catch typos early. Credentials are encrypted and stored; they are write-only and never returned.

Auth required: Yes

Request body

FieldTypeRequiredDescription
namestringYesUser-scoped disk name. Lowercase alphanumeric and dash, 1-63 chars, must start with letter or digit. Pattern: ^[a-z0-9][a-z0-9-]{0,62}$.
kindstringYesMust be "s3".
config.bucketstringYesS3 bucket name.
config.endpointstringYesFull HTTP(S) base URL of the S3 endpoint (e.g. https://s3.amazonaws.com).
config.regionstringNoS3 region. Defaults to "auto" for R2/MinIO.
config.use_path_stylebooleanNoUse path-style URLs (<endpoint>/<bucket>/). Required for MinIO and most self-hosted S3-compatibles.
credentials.access_keystringYesS3 access key ID. Write-only, never returned.
credentials.secret_keystringYesS3 secret access key. Write-only, never returned.

Example

curl -X POST https://api.sb.createos.sh/v1/disks \
  -H "X-Api-Key: $CREATEOS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-data",
    "kind": "s3",
    "config": {
      "bucket": "my-data-bucket",
      "endpoint": "https://s3.amazonaws.com",
      "region": "us-east-1"
    },
    "credentials": {
      "access_key": "AKIA…",
      "secret_key": "wJalrX…"
    }
  }'

Success response 200

{
  "status": "success",
  "data": {
    "id": "disk_01KSHT…",
    "name": "my-data",
    "kind": "s3",
    "config": {
      "bucket": "my-data-bucket",
      "endpoint": "https://s3.amazonaws.com",
      "region": "us-east-1",
      "use_path_style": false
    },
    "created_at": "2024-01-15T10:00:00Z"
  }
}

Notable errors:

StatusCause
400Malformed name, unsupported kind, missing bucket/endpoint/credentials, unreachable endpoint (probe failed), or bucket not found (404 probe).
401Unauthorized.
409Disk name already exists for this user.
503Disks feature not configured.

GET /v1/disks/{idOrName}

Get a single disk by id or user-scoped name. Credentials are never returned.

Auth required: Yes

Path parameters

ParameterDescription
idOrNamedisk_<ulid> id or user-scoped name (e.g. my-data).

Example

curl https://api.sb.createos.sh/v1/disks/my-data \
  -H "X-Api-Key: $CREATEOS_API_KEY"

Success response 200, same shape as the object in POST /v1/disks response.

Notable errors: 401 unauthorized. 404 not found or owned by another user (identical body, no existence leak across tenants). 503 disks feature not configured.

PATCH /v1/disks/{idOrName}

Replace the credentials for an existing disk without deleting its registration. Use the disk ID or your disk name. Authenticate with X-Api-Key.

{
  "credentials": {
    "access_key": "<new-access-key>",
    "secret_key": "<new-secret-key>"
  }
}

Both credential fields are required. The response is the same DiskView as GET and does not include credentials. The API saves the new credentials and requests updates to running attachments. A successful response does not guarantee that every active mount has refreshed; check mount status before retiring the old credentials. Paused sandboxes use the saved credentials on resume.

Notable errors: 400 invalid credentials or bucket probe failure, 404 disk not found or not owned by you, 503 disks unavailable.

SDK equivalent: client.disks.rotateCredentials().

DELETE /v1/disks/{idOrName}

Soft-delete a disk. Returns 409 if the disk is currently attached to any sandbox; detach it first.

Auth required: Yes

Path parameters

ParameterDescription
idOrNamedisk_<ulid> id or user-scoped name.

Example

curl -X DELETE https://api.sb.createos.sh/v1/disks/my-data \
  -H "X-Api-Key: $CREATEOS_API_KEY"

Success response 200

{
  "status": "success",
  "data": { "deleted": true }
}

Notable errors: 401 unauthorized. 404 not found. 409 disk still attached to one or more sandboxes.

GET /v1/sandboxes/{id}/disks

List all disks attached to a sandbox, including live mount_status reported by the in-VM agent (polled every 30 seconds).

Auth required: Yes

Path parameters

ParameterDescription
idSandbox id.

Example

curl https://api.sb.createos.sh/v1/sandboxes/sb-01K.../disks \
  -H "X-Api-Key: $CREATEOS_API_KEY"

Success response 200

{
  "status": "success",
  "data": {
    "data": [
      {
        "disk_id": "disk_01KSHT…",
        "name": "my-data",
        "kind": "s3",
        "config": {
          "bucket": "my-data-bucket",
          "endpoint": "https://s3.amazonaws.com"
        },
        "mount_path": "/mnt/data",
        "sub_path": "",
        "mount_status": "mounted",
        "mount_error": null
      }
    ],
    "pagination": { "total": 1, "limit": 50, "offset": 0, "count": 1 }
  }
}

mount_status values

ValueMeaning
pendingAttachment recorded; agent has not yet mounted it.
mountedBucket mounted successfully.
failedMount errored; see mount_error for the truncated agent error (~1 KiB).

Notable errors: 401 unauthorized. 404 sandbox not found.

POST /v1/sandboxes/{id}/disks

Live-attach a disk to a running sandbox. The agent mounts it within ~1 second of detection. Only works on sandboxes with status = "running".

Auth required: Yes

Path parameters

ParameterDescription
idSandbox id.

Request body

FieldTypeRequiredDescription
disk_idstringYesdisk_<ulid> id or user-scoped name of the registered disk.
mount_pathstringYesAbsolute path inside the VM (e.g. /mnt/data). Must be absolute; .. rejected. One path per disk per sandbox; attaching the same disk to the same path is idempotent.
sub_pathstringNoOptional prefix inside the bucket to mount (e.g. team-a/). Defaults to bucket root. Leading/trailing slashes are normalised; .. rejected.

Example

curl -X POST https://api.sb.createos.sh/v1/sandboxes/sb-01K.../disks \
  -H "X-Api-Key: $CREATEOS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"disk_id": "my-data", "mount_path": "/mnt/data"}'

Success response 200

{
  "status": "success",
  "data": { "ok": true }
}

Notable errors:

StatusCause
400Empty disk_id, non-absolute or ..-containing mount_path, or mount_path already claimed by a different disk.
401Unauthorized.
404Sandbox or disk not found.
409Sandbox is not in running state, or mount_path already in use by a different disk.

DELETE /v1/sandboxes/{id}/disks/{disk_id}

Live-detach a disk from a sandbox. Only the in-VM mount is dropped; the bucket contents are never touched.

A disk may be mounted at multiple paths in the same sandbox; use the mount_path query parameter to target a specific attachment.

Auth required: Yes

Path parameters

ParameterDescription
idSandbox id.
disk_idDisk id (disk_<ulid>) or user-scoped disk name.

Query parameters

ParameterTypeRequiredDescription
mount_pathstringYesAbsolute path of the attachment to detach. Required because one disk can be mounted at multiple paths in the same sandbox.

Example

curl -X DELETE \
  "https://api.sb.createos.sh/v1/sandboxes/sb-01K.../disks/disk_01KSHT...?mount_path=/mnt/data" \
  -H "X-Api-Key: $CREATEOS_API_KEY"

Success response 200

{
  "status": "success",
  "data": { "detached": true }
}

Notable errors: 401 unauthorized. 404 disk not attached at that path (or sandbox/disk not owned by caller). First DELETE wins; a second call for the same (disk_id, mount_path) returns 404.