Cubicle

Increase a Box's memory

POST
/v1/boxes/{box}/scale

Sets the Box's memory to memoryMiB and returns it with 202 Accepted. Memory can only grow, and the Box must be fully stopped: desired and observed stopped, with observed.generation equal to desired.generation. Stop a Box first and wait for it. The next start boots the Box with its new memory.

The caller needs a grant on the Box, or the owner or admin role in its organization. API keys need the write scope.

Cubicle reserves the extra memory on the Box's Node when it accepts the request, and advances desired.generation. Asking for the Box's current memory changes nothing and returns 202. CPU and disk cannot be changed.

Authorization

headerAuthorizationBearer <token>

A service account API key (cbk_…), used directly as the bearer token. read keys may call only GET routes.

Path Parameters

box*string

The Box's ID, ORG/NAME with the slash encoded as %2F, or a bare NAME, which ?org= narrows. See Box references.

Query Parameters

org?string

The organization's ID or name, to narrow a bare NAME in {box}. Ignored for an ID or ORG/NAME.

Request Body

The Box's new memory in MiB, at least its current memory.

application/json
  1. body
memoryMiB*integer
Range256 <= value <= 262144

Response Body

The Box with its new memory and desired generation.

application/json
  1. response
storage?

The state of background checkpoint uploads of the Box's disk and saved memory to remote storage. Every Box response includes it. It is informational: no route restores a Box from a checkpoint.

id*string

The Box's ID. It never changes.

baseImage*BaseImageId

The base image the Box's disk was created from. A Box created from a snapshot has its source Box's image.

Value in"default""omarchy"
org*

The organization that owns the Box.

name*string

Unique among the organization's Boxes that are not deleted: the NAME in ORG/NAME.

node*

The Node (host) the Box runs on. A Box never moves to another Node.

spec*

The CPU, memory and disk reserved for the Box on its Node for its whole life, also while it is stopped or hibernated. A free Box (pooled) gives its CPU and memory back while it is stopped or hibernated.

desired*

What the Box was last asked to be.

observed*|

The Node's latest report on the Box, or null before its first report.

state*BoxState

The observed state when the report is fresh. pending before the Node's first report, unknown when the report is stale or the Node is unhealthy, which means neither running nor stopped, and deleted once the Node has removed a deleted Box.

Value in"pending""unknown""deleted""absent""provisioning""starting""running""stopping""stopped""hibernating""hibernated""deleting""failed"
hibernateAt*|

When the Box hibernates automatically: 60 minutes after it first reported running since its latest start; see Box lifecycle. null until that report, and whenever the Box is not desired running or restartRequired is true. After a failed hibernation it stays in the past until the retry.

hibernationRetryAt*|

When Cubicle tries again to hibernate the Box after a failed attempt, 30 s after the first failure and doubling up to 5 min; otherwise null.

pooled*boolean

A free Box: its CPU and memory are reserved only while it runs.

expiresAt*|

When a stopped or hibernated free Box is deleted unless it is started again.

restartRequired*boolean

Whether the Box's host restarted while the Box was desired running. The Box stays down until a start request, which clears it; a stop also clears it.

connectionGeneration*number

Advances with every start, stop, hibernation (automatic ones too), delete and restore, and when the Box's host restarts, but not when a failed hibernation returns the Box to running. SSH and private-network traffic reaches the Box only once it runs at the new value; see Generations.

privateIp*|

The Box's IPv4 address on its Node's private subnet, reachable only over Cubicle's private network. null until the Box is first provisioned; it then stays the same for the Box's life.

console*

Whether the Dashboard console can be used now.

ssh*

Whether the Box is ready for commands and SSH now.

deletion*|

pending from an accepted delete until the Node has removed the Box, after which listings no longer show it; otherwise null. complete appears only when an Idempotency-Key replay of a create returns a Box removed since.

Value in"pending""complete"null
createdAt*string

When the Box was created.

Example Request
curl -X POST 'https://api.cubicle.sh/v1/boxes/acme%2Fjob-1/scale' \  -H 'Content-Type: application/json' \  -d '{  "memoryMiB": 4096}'
Example Response
{  "storage": {    "enabled": true,    "status": "unprotected",    "checkpointId": null,    "checkpointAt": null,    "current": false,    "processedBytes": 0,    "totalBytes": 0,    "error": null,    "retryAt": null  },  "id": "0f6c2a5e-3b1d-4c8e-9a7f-2d4e6b8c1a3f",  "org": {    "id": "6b1f3d2a-8c4e-4f7a-9b2d-1e5c7a9f3b6d",    "name": "acme"  },  "name": "job-1",  "baseImage": "default",  "node": {    "id": "c3a9e1f7-5b2d-4a8c-8e6f-0d1b3c5e7a9f",    "name": "node-1",    "healthy": true  },  "spec": {    "vcpus": 2,    "memoryMiB": 4096,    "diskGiB": 12  },  "sourceSnapshotId": null,  "desired": {    "state": "stopped",    "generation": 3  },  "observed": {    "state": "running",    "generation": 1,    "observedAt": "2026-11-05T10:15:04.000Z",    "ageSeconds": 2,    "fresh": true,    "error": null  },  "state": "stopped",  "hibernateAt": null,  "hibernationRetryAt": null,  "pooled": false,  "expiresAt": null,  "restartRequired": false,  "connectionGeneration": 2,  "privateIp": "10.20.30.17",  "console": {    "ready": false,    "reason": "not_requested"  },  "ssh": {    "ready": false,    "reason": "not_requested"  },  "deletion": null,  "createdAt": "2026-11-05T10:14:21.000Z"}