Migrate from boat.dev#
The TaskCloud REST API follows the resource model of boat.dev's API (sandboxes, commands, files, hosted ports, snapshots, webhooks), so most code ports directly. The main differences:
- Field names are
snake_case. - "Stop" becomes pause, and pause keeps RAM.
- Idle sandboxes pause automatically (default after 5 min) and wake on request, so you pay for active seconds, not for the time until an auto-stop timer fires.
boat.dev compatibility adapter: Coming soon. Until it ships, use the mapping below. The boat.dev details here come from its public documentation as of 2026-11; check boat.dev's current docs for exact behavior.
Key differences#
| boat.dev | TaskCloud | |
|---|---|---|
| Base URL | https://boat.dev/api/v1 |
https://api.task.cloud/v1 |
| JSON style | camelCase, {"ok": true, "type": ...} envelope |
snake_case, plain resource objects |
| Errors | {"ok": false, "code", "message", "error": {...}, "requestId"} |
{"error": {"code", "message", "retryable", "status", "request_id", "details"}} |
| Stop / resume | Stop saves a disk snapshot; resume boots again | Pause snapshots RAM and disk; resume restores the running state (target p95 < 800 ms) |
| Auto-stop | TTL-based auto-stop | Auto-pause when idle (default 5 min) plus wake on request (HTTP, SSH, API) |
| Fork | From the last disk snapshot | From the live VM including memory (target < 2 s) |
| Billing | Per second while the VM runs (until you stop it or its auto-stop timer fires) | Per second while running; $0 compute while paused |
| Delete | Requires the X-Ascii-Confirm-Delete header |
Plain DELETE (no confirmation header) |
| Idempotency | idempotencyKey field |
Idempotency-Key header |
| Rate-limit headers | RateLimit-Policy / RateLimit |
Same headers (IETF draft), with policies default and starts |
Endpoint mapping#
| boat.dev | TaskCloud | Notes |
|---|---|---|
POST /sandboxes (type, ttlSeconds, from, hostedPorts) |
POST /sandboxes (size, ttl_seconds, template or snapshot_id, ports) |
small / default / large map directly. xlarge has no equivalent yet. |
GET /sandboxes, GET /sandboxes/{id} |
same paths | Filters: state, label=key=value, name_prefix |
PATCH /sandboxes/{id} (extend) |
PATCH /sandboxes/{sandbox_id} |
ttl_seconds, auto_pause, always_on |
POST /sandboxes/{id}/stop |
POST /sandboxes/{sandbox_id}/pause |
RAM is kept |
POST /sandboxes/{id}/resume |
POST /sandboxes/{sandbox_id}/resume |
Usually not needed: requests wake the sandbox automatically. The size can't change on resume. |
POST /sandboxes/{id}/fork |
POST /sandboxes/{sandbox_id}/fork |
Includes memory. Same size as the source. Bulk fork: count up to 50 per call, all or nothing. |
DELETE /sandboxes/{id} |
DELETE /sandboxes/{sandbox_id} |
Returns 202 |
POST /sandboxes/{id}/commands (command, timeoutSeconds, detached, stream) |
POST /sandboxes/{sandbox_id}/exec (command, timeout_seconds, background, stream) |
Sync max 600 s. Background has no limit. Stream is SSE. |
GET /sandboxes/{id}/commands/{processId} and .../stream |
GET .../commands/{command_id} and .../stream |
Kill: POST .../commands/{command_id}/kill |
GET / PUT / DELETE /sandboxes/{id}/files |
GET / PUT /sandboxes/{sandbox_id}/files/content, DELETE /sandboxes/{sandbox_id}/files |
Read limit 1 GiB per request (boat.dev: 5 MiB) |
GET .../files/list, .../files/info |
GET .../files, GET .../files/stat |
|
POST .../files/folder, .../files/move |
POST .../files/mkdir, .../files/move |
|
POST .../files/upload-url, .../download-url |
same paths | Up to 10 GiB; URLs valid 15 min by default, 1 h max |
POST /sandboxes/{id}/host (port, public) |
POST /sandboxes/{sandbox_id}/ports (port, visibility) |
URL https://<short_id>-<port>.taskhost.cloud |
POST /sandboxes/{id}/desktop |
POST /sandboxes/{sandbox_id}/desktop |
KasmVNC signed URL with ttl_seconds, read_only. Screenshot and input endpoints are also available. |
POST /sandboxes/{id}/sshkey |
POST /sandboxes/{sandbox_id}/ssh or account-wide POST /ssh-keys |
Gateway ssh.taskhost.cloud |
GET / POST /saved-snapshots |
POST /sandboxes/{sandbox_id}/snapshots, GET /snapshots |
Turn a snapshot into a reusable template with POST /templates |
GET /sandboxes/{id}/usage |
GET /sandboxes/{sandbox_id}/usage |
Also account-wide: GET /usage?group_by=sandbox |
GET /limits |
GET /limits |
|
GET / POST /api-keys, POST /api-keys/scoped |
GET / POST /api-keys |
Presets read-only, full-sandbox, ci, admin are kept; restrict a key with restrict.sandbox_ids / restrict.labels |
GET / POST /webhooks, POST /webhooks/{id}/rotate |
GET / POST /webhooks, POST /webhooks/{webhook_id}/rotate-secret |
See below |
Webhooks#
| boat.dev event | TaskCloud event |
|---|---|
sandbox.ready |
sandbox.ready (new sandbox) and sandbox.resumed (after pause) |
sandbox.error |
sandbox.error |
sandbox.archived (stopped) |
sandbox.paused |
| — | sandbox.deleted |
sandbox.hydrated, sandbox.degraded, sandbox.recovered |
No equivalent. Resume restores memory and disk together, so there is no separate hydration step. |
The signature scheme is the same shape: hex HMAC-SHA256(secret, id + "." + timestamp + "." + raw_body), prefixed v1=, with a 300 s window. Only the header names change:
| boat.dev | TaskCloud |
|---|---|
X-Ascii-Delivery |
Webhook-Id |
X-Ascii-Timestamp |
Webhook-Timestamp |
X-Ascii-Signature |
Webhook-Signature |
X-Ascii-Event |
Webhook-Event |
X-Ascii-Attempt |
Webhook-Attempt |
The payload uses created_at, previous_state and state (instead of camelCase), and adds reason. See Webhooks.
CLI mapping#
| boat | taskcloud |
|---|---|
boat login |
taskcloud login |
boat new --type default |
taskcloud create --size default |
boat new --from <snapshot> |
taskcloud create --snapshot <snapshot_id> or --template <name> |
boat list / boat info <id> |
taskcloud list / taskcloud get <id> |
boat exec <id> -- npm test |
taskcloud exec <id> -- npm test |
boat ssh <id> |
taskcloud ssh <id> |
boat stop <id> |
taskcloud pause <id> |
boat resume <id> |
taskcloud resume <id> |
boat fork <id> |
taskcloud fork <id> |
boat host <id> 3000 --public |
taskcloud port expose <id> 3000 --public |
boat desktop <id> |
taskcloud desktop <id> --open |
boat delete <id> |
taskcloud delete <id> |
See CLI for the full reference.
Example: create, run, stop → create, run, (auto-)pause#
# boat.dev
curl -X POST https://boat.dev/api/v1/sandboxes -H "Authorization: Bearer $BOAT_API_KEY" \
-H "Content-Type: application/json" -d '{"ttlSeconds":3600}'
# TaskCloud
curl -X POST https://api.task.cloud/v1/sandboxes -H "Authorization: Bearer $TASKCLOUD_API_KEY" \
-H "Content-Type: application/json" \
-d '{"template":"base","size":"default","auto_pause":{"enabled":true,"idle_timeout_seconds":300}}'
curl -X POST https://api.task.cloud/v1/sandboxes/$SANDBOX_ID/exec -H "Authorization: Bearer $TASKCLOUD_API_KEY" \
-H "Content-Type: application/json" -d '{"command":"echo hello","timeout_seconds":30}'
# No explicit stop needed: after 5 idle minutes the sandbox pauses; the next request wakes it.
Not available (yet)#
| boat.dev feature | Status on TaskCloud |
|---|---|
Built-in agent harnesses (boat prompt, conversations, steer/interrupt) |
Not planned. We are infrastructure: run Claude Code, Codex or your own agent inside the sandbox. |
| AI credential profiles and AI key proxy | Roadmap |
| Environments with repositories, setup scripts and secrets | Use templates (from an image or snapshot) plus env at creation |
Nested virtualization (/dev/kvm) |
Roadmap (separate class on Cloud Hypervisor) |
| OpenTelemetry export | Not in the MVP. Use webhooks and the usage API. |
xlarge size |
Not available. The largest size is large (8 vCPU / 16 GB). |
Cost comparison#
Hourly price for 4 vCPU / 8 GB, according to battleships.dev as of 2026-10: boat.dev $0.036 per running hour. TaskCloud default is $0.030 per active hour, and $0 compute while paused.
The list prices are close, so the difference comes from how long a VM stays billed after the work stops:
- boat.dev stops a VM on a timer you set (default 1 h). Until the timer fires, the VM is running and billed, and resuming it boots the machine again.
TaskCloudpauses an idle VM after 5 minutes by default, keeps its RAM, and resumes it on the next request.
How much that saves depends on your session pattern and auto-stop setting. Paste a usage export into the bill calculator to see both bills side by side.
See Billing for how active time is measured.