Restore a Box from a snapshot
Queues replacing a stopped Box's disk with one of its own complete snapshots, and returns the restore operation with 202 Accepted. Poll the operation until it is done, then start the Box: it stays stopped. See Following a request.
The caller needs a grant on the Box, or the owner or admin role in its organization. API keys need the write scope.
- The Box must be desired
stopped, and should bestoppedat the current generation: otherwise the operation can fail withbox must be stopped. - The snapshot must be this Box's. To use another Box's snapshot, create a Box from it.
- The disk is replaced as a whole. The Box keeps its ID, name, private IP, size and grants.
connectionGenerationadvances at once, and guest accounts are applied again from the current grants and SSH keys; see What a restore changes.- Until the operation ends, starting, stopping, hibernating and deleting the Box return
409 conflict.
With an Idempotency-Key, repeating the request with the same body returns 202 with the operation the first request created.
AuthorizationBearer <token>A service account API key (cbk_…), used directly as the bearer token. read keys may call only GET routes.
box*stringThe Box's ID, ORG/NAME with the slash encoded as %2F, or a bare NAME, which ?org= narrows. See Box references.
org?stringThe organization's ID or name, to narrow a bare NAME in {box}. Ignored for an ID or ORG/NAME.
Idempotency-Key?stringMakes the request safe to retry: repeating it with the same key and body returns the first result instead of doing the work again. 1 to 200 characters; a UUID is a good choice.
1 <= length <= 200application/json- body
snapshotId*stringuuidThe restore operation: new, or the original one for an Idempotency-Key replay.
application/json- response
id*stringThe operation's ID.
boxId*stringThe ID of the Box it runs on.
type*stringexec for a command, snapshot or restore.
"exec""snapshot""restore"state*OperationStatepending until the Box's Node picks it up, then running, and finally done, failed or unknown. unknown means it was interrupted and its outcome is not known; it is never retried.
"pending""running""done""failed""unknown"attempt*numberHow many times a Node has picked it up: 0 while pending, then 1.
progress*|Reserved for progress notes. Current Nodes do not send any, so it is null.
result*unknownnull until done. A done exec holds an ExecResult, shown only to the member who requested it and null for everyone else. A done restore holds { "snapshotId": … }. A done snapshot holds an internal manifest; read the snapshot from the Box's snapshot list instead.
error*|Why it failed or became unknown; otherwise null.
createdAt*stringWhen it was requested.
startedAt*|When a Node picked it up, or null while pending.
completedAt*|When it reached done, failed or unknown, or null before.
curl -X POST 'https://api.cubicle.sh/v1/boxes/acme%2Fjob-1/restore' \ -H 'Idempotency-Key: 4f1c7c1e-6a43-4d5e-9b7e-0d2f6c0e9a51' \ -H 'Content-Type: application/json' \ -d '{ "snapshotId": "5a7c9e1b-3d5f-4a6b-8c0d-2e4f6a8b0c3d"}'{ "id": "6c8e0a2c-4e6a-4b8c-9e0a-4c6e8a0c2e5b", "boxId": "0f6c2a5e-3b1d-4c8e-9a7f-2d4e6b8c1a3f", "type": "restore", "state": "pending", "attempt": 0, "progress": null, "result": null, "error": null, "createdAt": "2026-11-05T10:30:00.000Z", "startedAt": null, "completedAt": null}
