Deploying with an agent

Read this first when an autonomous coding agent needs the deploy flow for a Cloudbed capsule.

Fast path

Fresh project:

npx cloudbed new my-app --template todo
cd my-app
npx cloudbed deploy --json

Existing project:

cd existing-app
npx cloudbed init . --template todo --json
npx cloudbed deploy --json

cloudbed init [dir] [--template todo|guestbook] scaffolds into an existing directory, including a non-empty one. It never overwrites files, merges the cloudbed dependency into an existing package.json, and supports --json.

With no auth, cloudbed deploy --json creates an anonymous deploy. No account is required. The response includes a live URL.

{
  "deployId": "dep_...",
  "url": "https://example.cloudbed.app",
  "name": "todo",
  "mode": "anonymous",
  "claimed": false,
  "createdAt": "2026-07-02T00:00:00.000Z",
  "updatedAt": "2026-07-02T00:00:00.000Z",
  "expiresAt": "2026-07-09T00:00:00.000Z",
  "claimToken": "cb_claim_...",
  "claimUrl": "https://dashboard.cloudbed.dev/claim?token=...",
  "inspectToken": "cb_inspect_..."
}

Save these fields:

Field Why
claimToken One-time secret returned only on anonymous create. Needed to claim the deploy.
inspectToken Secret returned only on create. Needed by cloudbed inspect and private inspect routes.
deployId Stable deploy id. Needed to update, inspect by id, or recover from lost local context.
url Live app URL. Use it for verification and handoff.

The CLI auto-persists deploy state to .cloudbed/deploy.json with api, deployId, claimToken, and inspectToken. Keep .cloudbed/ gitignored. If a deploy is owned or claimed, the CLI writes cloudbed.json; commit that file so future deploys from the directory update the same app.

Auth for agents

Use CLOUDBED_TOKEN for non-interactive auth. It is a bearer token, checked before ~/.cloudbed/auth.json, and works for deploy, claim, whoami, token, domains, and inspect.

export CLOUDBED_TOKEN="cb_..."
cloudbed whoami --json

To validate and persist a token for later commands:

cloudbed login --token "$CLOUDBED_TOKEN"

To mint tokens for automation:

cloudbed token create --name agent-ci --json
cloudbed token create --name agent-deploy --deploy --json

--deploy scopes the token to the current directory's deploy. The token value is shown once; store it as a secret.

Mode What works What is blocked
Anonymous Live URL with no account; redeploy from the same local state. No outbound fetch, no server env, expires 7 days after the last update.
Claimed/owned No expiry, outbound fetch, .env.cloudbed.server sync on deploy, owner operations. Requires owner credentials.

State files

File Commit? Contents Agent rule
cloudbed.json Yes Committed deploy binding, including deployId. Keep it when the project should update the same owned deploy.
.cloudbed/deploy.json No Local deploy secrets: api, deployId, claimToken, inspectToken. Treat as secret; require .cloudbed/ in .gitignore.
~/.cloudbed/auth.json No User/API login profiles by API origin. Prefer CLOUDBED_TOKEN in automation; login --token writes here.

Error handling

Run commands with --json. On failure, JSON commands print an error envelope to stderr and exit nonzero:

{"error":{"code":"invalid_artifact","message":"artifact.format must be \"cloudbed.capsule.v1\"."}}

Branch on error.code, not the message.

Code Meaning Agent action
unknown_op Protocol operation is not recognized. Fix the client/protocol version or operation name; do not retry unchanged.
unknown_query Query name is not in the deployed artifact. Inspect the manifest, fix the query name, or redeploy the server.
unknown_mutation Mutation name is not in the deployed artifact. Inspect the manifest, fix the mutation name, or redeploy the server.
unknown_endpoint HTTP endpoint is not in the deployed artifact. Fix the method/path or redeploy with that endpoint.
handler_error Capsule server code threw during a query, mutation, or endpoint. Inspect logs, fix server code, redeploy.
quota_exceeded A deploy quota was exceeded. Claim if anonymous, reduce usage/data, or wait for daily counters; avoid tight retries.
rate_limited A platform rate limit was hit. Back off, wait, reuse an existing deploy, or use account auth.
invalid_message Command input, request body, or protocol message is malformed. Fix arguments or JSON shape; do not retry unchanged.
invalid_artifact Deploy artifact or env payload is invalid. Rebuild, fix schema/bundles/endpoint paths, then deploy again.
not_found Deploy, route, token, domain, or session was not found. Check ids and local state; recreate or redeploy if stale.
unauthorized Bearer, claim, or inspect credential is missing or invalid. Set CLOUDBED_TOKEN, login, refresh the token, or restore .cloudbed/deploy.json.
forbidden The credential is valid but not allowed for the operation. Claim the deploy, use owner credentials, or stop the unsupported action.
payload_too_large Bundle, env, request body, or row value is too large. Shrink the payload/env/data and redeploy.
internal Platform or auth service failed internally. Retry with backoff; report if it persists.
not_configured The platform lacks configuration for the requested feature. Skip that feature or target a configured platform.
upstream_error An upstream provider failed or rejected the request. Retry with backoff; verify DNS/provider inputs.

Limits

Storage and handler caps apply to every deploy. Daily counters apply only to anonymous deploys and disappear on claim.

Limit Value
Deploy payload (bundled server + client + optional SSR) 4 MB
State size 1 MB
State rows 16,384
Serialized row size 64 KB
Rows returned per query 1,000
HTTP endpoint request body 2 MB
Handler wall-clock time 10 s
Log retention 1,000 entries / 256 KB
Endpoint requests / day (anonymous only) 10,000
Mutations / day (anonymous only) 1,000
Anonymous deploys per IP / day 50
Server env (claimed only) 64 keys, 16 KB per value, 64 KB total

Verify it worked

deploy_json="$(cloudbed deploy --json)"
url="$(node -e 'console.log(JSON.parse(process.argv[1]).url)' "$deploy_json")"
curl -fsS "$url"
cloudbed inspect --json

For capsule({ ssr: true }) apps, curl -fsS "$url" includes the rendered app markup and the embedded __cloudbed_state__ snapshot. For CSR apps it still returns the boot shell, so use the inspect manifest and app-specific HTTP or WS checks for deeper verification.

cloudbed logs --json shows what the server code actually did (ctx.log entries; add --follow to stream while you exercise the app). If the new deploy is broken, cloudbed releases --json + cloudbed rollback restore the previous release in one command — then fix and redeploy.