DOCSThe CLI
DOCS

The CLI

caas is the caas.sh command line. Use it to run commands in new sandboxes, manage sandboxes and their snapshots, deploy MCP servers, push images, start workflows, connect credentials and manage billing from a terminal or a script. It calls the same API as the console, with an API key from your workspace.

Install the CLI

The CLI needs Node 22 or later. Install the @caascade/cli package globally:

shell
npm i -g @caascade/cli

The package isn't on npm yet. Once it's published, this command installs it.

This installs the caas command. To list every command and option, run caas help, or caas on its own. Adding --help to any command does the same.

Some commands use other tools: caas registry login runs Docker, and --from uses Git.

Connect the CLI to your workspace

The CLI doesn't sign in with your email and password. It uses an API key, which belongs to one workspace, together with that workspace's tenant ID.

Create an API key

  1. Sign in to the console and open Settings.

  2. Under Workspace, copy the Tenant ID.

  3. Under API keys, enter a Key name, such as my laptop. If you're an owner and want to use caas billing, check Billing access.

  4. Choose Create key, then copy the key. It starts with ck_, and the console shows it only once.

Owners and operators can create keys. Viewers can't.

Configure the CLI

Save the tenant ID and key:

shell
caas configure --tenant <tenant-id> --key <api-key>

The CLI saves them in ~/.config/caas/config.json, or in $XDG_CONFIG_HOME/caas/config.json if XDG_CONFIG_HOME is set. Only you can read the file. Every later command uses what you saved. To check that everything works, list your sandboxes:

shell
caas sandboxes list

Running caas configure again replaces the saved tenant ID and key.

What a key can do

A new key can:

  • list, create, start, stop and delete sandboxes, and run commands in them

  • deploy MCP servers and manage their client tokens

  • push and pull images in the registry

  • start and control workflow runs

  • read credentials, egress rules and the audit log

A key with Billing access can also read the balance and usage and add funds (caas billing).

A key can never do more than the member who created it. An operator's key can't use caas billing, and only an owner's key can connect or remove credentials or apps, or change egress rules. If the member who created a key leaves the workspace, the key stops working. To revoke a key, choose Revoke next to it under Settings → API keys.

Choose a workspace

The CLI always works in one workspace: the one whose tenant ID you pass, with a key created in that workspace. A key from one workspace doesn't work in another.

To work in another workspace:

  1. In the console, open the workspace card at the top of the sidebar and switch to that workspace.

  2. Create an API key there, as in Create an API key, and copy that workspace's tenant ID.

  3. Either save the new pair, which replaces the one you saved before:

    shell
    caas configure --tenant <other-tenant-id> --key <other-api-key>

    Or pass the pair to a single command and keep what you saved:

    shell
    caas sandboxes list --tenant <other-tenant-id> --key <other-api-key>

Options for every command

OptionWhat it does
--tenant IDUse this workspace instead of the saved one. Pass --key with it.
--key KEYUse this API key instead of the saved one.
--api-url URLUse another API address. The default is https://api.caas.sh. It must use https://, except on localhost. caas configure saves it.
--jsonPrint the API's JSON response instead of the text output.
--helpPrint every command and option.

caas run, caas mcp deploy, caas sandboxes exec, caas workflows run and caas billing add-funds send their request with an idempotency key. If the CLI can't reach the API, the error names the key. Run the same command again with --idempotency-key KEY to retry without creating a second sandbox, command, run or payment.

Exit codes

CodeMeaning
0Success.
1The request or the command failed.
2The command line isn't valid, for example an unknown option, a missing value or a value out of range. Nothing was changed.
3The API or the registry refused the key: it's revoked, from another workspace, or lacks the access the command needs.

caas run and caas sandboxes exec exit with the command's own exit code when it's between 1 and 125, and with 1 for any other failure. Errors are printed to standard error as caas: <message>. When the workspace is out of funds, the error also links to the console page where an owner adds them.

Sizes

--size sets a sandbox's vCPU, memory and disk. The default is m.

Size--sizevCPUMemoryDisk
XSxs1/16256 MiB2 GB
Ss1/41 GiB4 GB
Mm1/24 GiB8 GB
Ll16 GiB12 GB
XLxl28 GiB16 GB
2XL2xl412 GiB20 GB
Customcustom1 to 4At least 3 GiB per vCPU, at most 12 GiB2 to 20 GB

For a custom size, add --vcpu N --memory GIB --disk GB, all whole numbers:

shell
caas run --size custom --vcpu 2 --memory 6 --disk 12 -- node --version

A sandbox that runs your own image needs size M or larger. vCPU bills only while the sandbox computes; memory and disk bill while it runs. See pricing for the rates.

Run a command in a new sandbox

caas run creates a sandbox, runs one command in it, waits for the command to end, and prints its output:

shell
caas run -- node --version
caas run --from . node task.js
caas run --name build-agent --size xl --from . node task.js
caas run --image worker:latest -- python task.py
caas run --from . --detach node long-task.js
caas run --ephemeral --egress-host api.example.com -- node --version
caas run --from . --expose 3000 -- node server.js

The command runs as an executable with its arguments, not through a shell. To use shell features, run a shell:

shell
caas run --from . -- sh -c 'node build.js && node test.js'

Options can come anywhere before --, and everything after -- is the command. Put -- before a command whose arguments start with --.

Without --image, the sandbox uses the Default image: Alpine Linux with bash, coreutils, Node and Docker. It has no coding agents installed; install one in your command, or use your own image.

The command has a time limit of two hours, and runs once. When caas run is done, the sandbox keeps running until its idle stop. Delete it with caas sandboxes delete when you no longer need it.

OptionWhat it does
--from DIRUpload your code into /workspace. See Upload your code.
--image IMAGERun in your own image from the registry. See Push images to the registry. Can't be combined with --from.
--name NAMEName the sandbox: up to 63 lowercase letters, digits and hyphens, starting and ending with a letter or digit, unique in the workspace.
--size SIZEThe sandbox's size. See Sizes.
--egress-host HOSTAllow outbound requests to this exact host. Repeat it for each host, up to 32. Other hosts are blocked unless you change the sandbox's egress policy. A command that starts with npx also gets registry.npmjs.org.
--expose PORTServe this port at the sandbox's own URL: 1024 to 65535, except 8788. See Sandbox URLs.
--publicWith --expose: let anyone with the link open the URL, without an access token.
--idle-stop MINUTESStop the sandbox after this many minutes with no command, file transfer, MCP request or URL request: 5 to 240. The default is 15.
--wake-on-requestLet a command, a file transfer, an MCP request or a URL request start the sandbox again after you stopped it yourself. A sandbox that stopped while idle starts again on a request either way.
--ephemeralKeep nothing between restarts: the sandbox starts fresh each time, and the sandbox takes no automatic or nightly snapshots. Can't be combined with --from.
--detachReturn as soon as the sandbox is created, without waiting for the command.

With --detach, the CLI prints the new sandbox and the ID of its first command, initial-agent-command. Check on the command later:

shell
caas sandboxes command <sandbox-id> initial-agent-command

Upload your code

--from DIR uploads the committed Git tree of the repository at DIR, usually ., and unpacks it into /workspace when the sandbox first starts. You can use it with caas run and with caas mcp deploy --stdio.

  • DIR must be the root of a Git repository with at least one commit.

  • Commit your changes first. The CLI refuses a repository with uncommitted changes or untracked files. Files that Git ignores are never uploaded.

  • The CLI refuses to upload a repository that tracks a sensitive-looking file: .env files, .dev.vars, .npmrc, id_rsa, credentials, or any .pem or .key file.

  • The compressed upload can be at most 250 MiB.

  • A sandbox started from an upload keeps its state, so you can't combine --from with --ephemeral. caas.sh keeps the upload for seven days; after that, your files live on in the sandbox's own snapshots.

Manage sandboxes

caas sandboxes commands take the sandbox's ID, not its name. caas sandboxes list shows both.

List and inspect

shell
caas sandboxes list
caas sandboxes inspect <sandbox-id>
caas sandboxes events <sandbox-id>
CommandWhat it does
caas sandboxes listLists every sandbox and MCP server that isn't deleted: its ID, name, kind (agent or mcp) and record state (active once it's created). inspect shows whether it's running.
caas sandboxes inspect IDShows the sandbox's details: its status, settings, size, URL, and usage, including what it costs per hour now and what it has cost today.
caas sandboxes events IDLists the sandbox's events, such as its starts and stops.

Start, stop and delete

shell
caas sandboxes stop <sandbox-id>
caas sandboxes start <sandbox-id>
caas sandboxes delete <sandbox-id>

A sandbox that keeps state takes a snapshot as it stops, and starts again with its /workspace.

Run commands in a sandbox

shell
caas sandboxes exec <sandbox-id> -- node --version
caas sandboxes exec <sandbox-id> -- sh -c 'cd /workspace && ls -la'
caas sandboxes exec <sandbox-id> --timeout-ms 1800000 --detach -- node long-task.js
caas sandboxes command <sandbox-id> <command-id>
caas sandboxes cancel-command <sandbox-id> <command-id>
CommandWhat it does
caas sandboxes exec ID -- COMMAND [ARGS...]Runs a command in the sandbox, waits for it, prints its output and exits with its exit code.
caas sandboxes command ID COMMAND_IDShows a command's state, exit code and output.
caas sandboxes cancel-command ID COMMAND_IDStops a running command.

exec takes these options before --:

OptionWhat it does
--timeout-ms MSThe command's time limit in milliseconds: 1000 (1 second) to 7200000 (2 hours). The default is 600000 (10 minutes).
--detachPrint the command's ID and return without waiting.

As with caas run, the command runs without a shell. A command sent to a sandbox that stopped while idle starts it again.

Snapshots

A sandbox that keeps state takes a snapshot of /workspace every hour, when it stops, and every night, at 02:00 in the workspace's time zone unless you move it. You can also take your own.

shell
caas sandboxes snapshot <sandbox-id> --name before-upgrade
caas sandboxes snapshots <sandbox-id>
caas sandboxes stop <sandbox-id>
caas sandboxes restore <sandbox-id> --snapshot <snapshot-id>
caas sandboxes delete-snapshot <sandbox-id> <snapshot-id>
caas sandboxes schedule <sandbox-id> --at 03:30 --time-zone Europe/Berlin
caas sandboxes schedule <sandbox-id> --off
CommandWhat it does
caas sandboxes snapshot ID [--name NAME]Takes a snapshot of a running sandbox. Without --name, it's named manual. Names follow the same rules as sandbox names.
caas sandboxes snapshots IDLists the snapshots: ID, name, kind, when each was taken, its size and which one is current. Then the bytes stored and the nightly schedule.
caas sandboxes restore ID --snapshot SNAPSHOT_IDRestores a snapshot onto a stopped or failed sandbox and starts it. Stop the sandbox first.
caas sandboxes delete-snapshot ID SNAPSHOT_IDDeletes a snapshot.
caas sandboxes schedule ID --at HH:MM [--time-zone ZONE]Moves the nightly snapshot to this 24-hour time, in an IANA time zone such as Europe/Berlin.
caas sandboxes schedule ID --offTurns the nightly snapshot off.

Snapshots you take stay until you delete them. caas.sh keeps the newest 7 nightly snapshots. See Sandboxes for how snapshots work.

Sandbox URLs

A sandbox can serve one HTTP port at its own address, https://<label>.caa.sh, where the label is an opaque name that reveals neither your workspace nor the sandbox's ID. The URL needs an access token unless you make it public.

shell
caas sandboxes expose <sandbox-id> 8080
caas sandboxes url-token <sandbox-id> --ttl 600
caas sandboxes expose <sandbox-id> 8080 --public
caas sandboxes expose <sandbox-id> --off
CommandWhat it does
caas sandboxes expose ID PORT [--public]Serves PORT (1024 to 65535, except 8788) at the sandbox's URL, or changes the port. With --public, anyone with the link can open it.
caas sandboxes expose ID --offTurns the URL off and revokes every access token for it.
caas sandboxes url-token ID [--ttl SECONDS]Prints an access token for the URL, its expiry, and a curl command that uses it. --ttl is 60 to 86400 seconds; the default is 3600.

Send the token as an Authorization: Bearer header. caas sandboxes inspect shows the URL. A request to the URL starts a sandbox that stopped while idle, and keeps it from stopping.

Logs and outbound requests

shell
caas sandboxes logs <sandbox-id>
caas sandboxes log-archives <sandbox-id>
caas sandboxes log-archive <sandbox-id> <archive-id> > runtime.jsonl
caas sandboxes egress <sandbox-id>
CommandWhat it does
caas sandboxes logs IDPrints the sandbox's recent runtime log.
caas sandboxes log-archives ID [--cursor ARCHIVE_ID]Lists the log archives: each one's ID, time span, entries and size. Pass the printed Next cursor as --cursor for older ones. Archives are kept for 90 days.
caas sandboxes log-archive ID ARCHIVE_IDPrints one archive as JSON Lines.
caas sandboxes egress ID [--cursor N]Lists the outbound requests the sandbox tried to make, newest first. See below.

Each line of caas sandboxes egress shows the time, method, host and path, whether the request was allowed or blocked, the rule that decided, the response status (- when the request failed), the bytes sent, and key added when a credential was added to it. Query strings, headers and bodies are never kept. caas.sh keeps the newest 1,000 allowed and 1,000 blocked requests for 7 days. Pass the printed Next cursor as --cursor for older ones.

Deploy MCP servers

caas mcp deploy puts an MCP server online at its own endpoint, https://mcp.caa.sh/<endpoint-id>. Choose exactly one source:

shell
caas mcp deploy --stdio "npx -y @modelcontextprotocol/server-filesystem /workspace"
caas mcp deploy --stdio "node server.js" --from .
caas mcp deploy --repo github.com/acme/server --ref main --command "npm start"
caas mcp deploy --image server:1.2.3
caas mcp deploy --image server:1.2.3 --transport http --port 3000 --command "node http.js"
OptionWhat it does
--stdio "COMMAND"Runs a server that speaks MCP over standard input and output. Add --from DIR to upload your code first.
--repo URLClones an HTTPS Git repository (https:// is added if you leave it out) and runs --command, which defaults to npm start.
--ref REFWith --repo: the branch, tag or commit to deploy.
--image IMAGERuns your own image from the registry. Without --command, the image's own entrypoint and command run.
--command "COMMAND"With --repo or --image: the command that starts the server. With --image, it replaces the image's entrypoint and command.
--transport TRANSPORTWith --image: stdio (the default) or http.
--port PORTWith --transport http: the port your server listens on, serving Streamable HTTP at /mcp. 1024 to 65535, except 8788.

--stdio and --command take a quoted command line. The CLI splits it into words like a shell does, with quotes and backslashes, but doesn't run it through a shell. A command can have up to 32 words.

These options work as they do for caas run: --name, --size (with --vcpu, --memory and --disk), --egress-host, --expose, --public, --idle-stop, --wake-on-request and --ephemeral. A stdio server on your own image needs Node in the image. When a server from --repo or --from first starts and has a package.json, its production dependencies are installed.

The CLI prints the new server's details, including its endpoint (endpointUrl) and a first client token (clientToken) that can call every tool and doesn't expire. The token is shown only once. Clients send a token as an Authorization: Bearer header. A retry with the same --idempotency-key doesn't print the token again; create a new one with caas mcp tokens create.

Deploy from a file

caas mcp deploy -f FILE (or --file FILE) deploys a server declared in a YAML or JSON file, the same format the console's Deploy from a server file page takes (under MCP servers → Deploy server):

yaml
server: search-mcp
source:
  stdio: npx search-mcp
size: s
state:
  persistent: true
  snapshots: nightly at 02:00
idle: stop after 30m
tokens:
  - name: laptop-claude
    tools: [search.query, search.fetch]
  - name: ci-pipeline
    tools: [search.query]
    expires: 30d
egress: [api.search.example.com]
shell
caas mcp deploy -f search-mcp.yaml

The CLI checks the whole file before it uploads or creates anything, creates the server and its tokens in one request, and prints the endpoint and each token's tools, expiry and secret once. The file declares the whole server, so only --from (with a stdio source and persistent: true), --wake-on-request, --idempotency-key and --json can be combined with -f. See MCP servers for every field.

Client tokens

shell
caas mcp tokens list <sandbox-id>
caas mcp tokens create <sandbox-id> --name "Claude Desktop"
caas mcp tokens create <sandbox-id> --name ci --expires-days 30 --allow-tool search.query
caas mcp tokens revoke <sandbox-id> <token-id>
CommandWhat it does
caas mcp tokens list IDLists the server's client tokens: ID, name, whether each is active, revoked or expired, the tools it may call, and its calls and errors.
caas mcp tokens create ID --name LABELCreates a token and prints its secret once.
caas mcp tokens revoke ID TOKEN_IDRevokes a token. The server keeps running.

create takes these options:

OptionWhat it does
--name LABELRequired. A label for the client that uses the token.
--expires-days DAYSWhen the token expires: 1 to 365 days. The default is 90.
--allow-tool NAMELet the token call only this tool. Repeat it for each tool. Without it, the token can call every tool.

Push images to the registry

Your workspace has its own namespace in the caas.sh registry, registry.caas.sh/<tenant-id>/. Log Docker in with your saved key, then build and push a linux/amd64 image:

shell
caas registry login
docker build --platform linux/amd64 -t registry.caas.sh/<tenant-id>/server:1.2.3 .
docker push registry.caas.sh/<tenant-id>/server:1.2.3
caas mcp deploy --image server:1.2.3

caas registry login runs docker login registry.caas.sh, with your tenant ID as the username and your API key as the password. New keys can push and pull.

Wherever a command takes --image, you can write the image as NAME[:TAG] or NAME@sha256:DIGEST, optionally under registry.caas.sh/ or registry.caas.sh/<tenant-id>/. The CLI looks a tag up in the registry (latest when you give none) and always deploys its digest. Images from other registries or other workspaces are refused: push them to your namespace first. See Images and the registry.

Run workflows

A workflow is a YAML or JSON file of steps. Each step runs in a sandbox of its own, and every finished step is a checkpoint you can resume from:

yaml
workflow: hello
inputs:
  name: world
steps:
  - id: greet
    name: Write greeting
    run: echo "Hello, ${{ inputs.name }}" > greeting.txt
    outputs: [greeting.txt]
  - id: show
    name: Show greeting
    run: cat greeting.txt
    inputs: [greet]
shell
caas workflows run hello.yaml --input name=caas --follow
caas workflows list
caas workflows show <run-id>
caas workflows pause <run-id>
caas workflows resume <run-id>
caas workflows resume <run-id> --from cp-1 --follow
caas workflows cancel <run-id>
CommandWhat it does
caas workflows run FILEChecks the file and its inputs, pins each image tag to its digest, starts the run, and prints its ID and a link to it in the console.
caas workflows listLists the runs: name and number, status, progress, cost and ID.
caas workflows show RUN_IDShows a run's steps: each one's state, machine and checkpoint, a failed step's exit code and log, and a running step's newest output. If the run can be resumed, it says how.
caas workflows pause RUN_IDLets the steps that are running finish, and starts nothing more.
caas workflows resume RUN_IDLifts a pause, or runs again the steps that didn't finish in a run that ended.
caas workflows cancel RUN_IDEnds the run.
OptionWhat it does
--input NAME=VALUEWith run: sets one of the file's inputs. Repeat it for each input. Inputs the file declares without a default are required.
--followWith run, show and resume: print each step as its state changes, and a running step's new output, until the run ends. The CLI exits with 1 unless the run succeeded.
--from CHECKPOINTWith resume: replay the run from that checkpoint, such as cp-2, with the same inputs.

A workspace can have up to 10 runs queued, running or paused at once. A run's checkpoints are kept for 7 days after it ends; until then, you can resume it. See Workflows for the file format.

Credentials and outbound access

caas.sh keeps your API keys and tokens out of your sandboxes. You connect each one as a credential of the workspace, and egress rules tell caas.sh which outbound requests to add it to. Inside a sandbox whose rules add it, the credential's name is a variable that holds only a placeholder.

Only an owner's key can connect, reconnect or remove credentials, add or remove apps, and add or remove egress rules. See Credentials and outbound access for how it all fits together.

Credentials

shell
caas credentials connect ANTHROPIC_API_KEY --api-key < anthropic-key.txt
caas credentials connect GITHUB_TOKEN --github
caas credentials connect CODEX --codex
caas credentials list
caas credentials reconnect ANTHROPIC_API_KEY < new-anthropic-key.txt
caas credentials remove ANTHROPIC_API_KEY
CommandWhat it does
caas credentials connect NAME METHODConnects a credential. See the methods below.
caas credentials listLists the credentials: name, method, status, scopes and number of rules, and how to reconnect any that need it.
caas credentials reconnect NAMEFor an API key, reads the new value from standard input. For a sign-in, starts a new one.
caas credentials remove NAMEDeletes the credential, its stored value and its egress rules.

NAME is capital letters, digits and _, such as GITHUB_TOKEN, and can't start with CAAS_. connect takes exactly one method:

MethodWhat it does
--api-keyReads the key from standard input. The CLI never takes a key as an option.
--githubSigns in to GitHub through caas.sh's own GitHub App.
--github-app APPInstalls your own GitHub App, added with caas credentials apps add.
--oauth APPSigns in through your own OAuth app, added with caas credentials apps add. Add --scope SCOPE for each scope to ask for; without it, the sign-in asks for every scope the app lists.
--codexConnects a ChatGPT account for Codex: the CLI prints a code and OpenAI's page to enter it on.

A sign-in prints a page to open. It returns to the console's Credentials page, which finishes it while you're signed in there as the owner who started it. The CLI then waits until the credential is ready; --detach returns at once instead, on connect and reconnect.

Apps for sign-ins

Before you connect an --oauth or --github-app credential, add the app it signs in through. The app's secret is read from standard input:

shell
caas credentials apps add google --type oauth2 --preset google \
  --client-id 1234.apps.googleusercontent.com \
  --scope https://www.googleapis.com/auth/drive.readonly < client-secret.txt
caas credentials connect GOOGLE_DRIVE --oauth google

caas credentials apps add acme-bot --type github-app --client-id Iv1.0123abcd --slug acme-bot < private-key.pem
caas credentials connect GITHUB_APP_TOKEN --github-app acme-bot

caas credentials apps list
caas credentials apps remove acme-bot
OptionWhat it does
--type TYPEoauth2 or github-app.
--preset PRESETWith oauth2: google, gitlab or linear, which fills in the provider's endpoints.
--authorize-url URL, --token-url URLWith oauth2 and no preset: the provider's endpoints, https:// URLs on a public host.
--token-auth METHODWith oauth2 and no preset: how the token endpoint takes the client secret, post (the default) or basic.
--client-id IDThe app's client ID. For a GitHub App, its Client ID.
--scope SCOPEWith oauth2: each scope the app's credentials may ask for. At least one is required.
--slug SLUGWith github-app: the app's slug, as in github.com/apps/<slug>.

The app ID is up to 32 lowercase letters, digits and hyphens. Set the app's redirect URI (for a GitHub App, its callback and setup URL) to https://api.caas.sh/v1/credential-interactions/callback.

Egress rules

An egress rule adds a credential to HTTPS requests for a host, on every path:

shell
caas egress rules add --preset anthropic --credential ANTHROPIC_API_KEY
caas egress rules add --preset github --credential GITHUB_TOKEN --sandbox <sandbox-id>
caas egress rules add --credential NPM_TOKEN --host registry.npmjs.org --header authorization --scheme bearer
caas egress rules list
caas egress rules remove <rule-id>
OptionWhat it does
--credential NAMERequired. The credential to add.
--preset PRESETgithub (api.github.com by bearer token, and github.com by basic auth for Git), or anthropic, openai or google (the provider's API key in the header its SDKs send). A model provider preset also gives the sandbox the provider's usual key variable, such as ANTHROPIC_API_KEY, holding a placeholder.
--host HOSTWithout a preset: the host. *.example.com covers example.com and every name under it.
--header NAMEWithout a preset: the request header to set, such as authorization.
--scheme SCHEMEWithout a preset: bearer, basic or raw (the value as is).
--username USERWith --scheme basic: the username. Required for basic.
--sandbox IDApply the rule to one sandbox only. Without it, the rule applies to every sandbox.

A sandbox can have up to 16 rules. A running sandbox picks up changed rules the next time it starts; a credential's new value applies at once. A rule only adds the credential: the sandbox's egress policy must still allow the host. A Codex credential isn't added by egress rules.

Egress policy

Each sandbox has an ordered list of hosts it may and may not reach. The first match wins, and the list always ends by denying everything else. A new sandbox's policy allows its --egress-host hosts.

shell
caas egress policy show <sandbox-id>
caas egress policy set <sandbox-id> --deny uploads.example.com --allow '*.example.com' --allow pypi.org

caas egress policy set ID replaces the policy with the --allow HOST and --deny HOST options, in the order you give them, and applies it to a running sandbox at once. Owners and operators can change it.

Billing

caas billing needs a key with Billing access, which only an owner can create.

shell
caas billing balance
caas billing add-funds 25
caas billing auto-recharge show
caas billing auto-recharge set --below 10 --recharge-to 50
caas billing auto-recharge set --off
caas billing usage
caas billing usage --month 2026-09
caas billing usage --csv > caas-usage.csv
CommandWhat it does
caas billing balancePrints the balance, the auto-recharge setting and recent top-ups with their receipts.
caas billing add-funds AMOUNTAdds funds: $5 to $2,000, written as 25, 25.50, $25.50 or 1,000. It charges the card on file, or prints a Stripe Checkout link to pay and save a card.
caas billing auto-recharge showPrints the auto-recharge setting.
caas billing auto-recharge setTurns auto-recharge on, changing only the amounts you give. With --off, turns it off.
caas billing usagePrints a month's spend: the total so far, the projection and today while the month is current, the amount for each meter, and the spend alert.
OptionWhat it does
--below AMOUNTWith auto-recharge set: recharge when the balance falls below this, $5 to $1,000. It's $10 until you change it.
--recharge-to AMOUNTWith auto-recharge set: charge the card back up to this, at least $5 above --below and at most $2,000. It's $50 until you change it.
--offWith auto-recharge set: turn auto-recharge off. You get an email when the balance falls below the amount instead.
--month YYYY-MMWith usage: the month to show. The default is this month.
--csvWith usage: print the month as CSV, one row per UTC day and meter, with the columns day,meter,quantity,unit,rate_usd,amount_usd. The amounts add up exactly to the month's total. Can't be combined with --json.

Auto-recharge starts off, so adding funds never charges your card again on its own. Sandboxes run only while the balance is above $0. See Billing and usage.

Workspace settings and the audit log

shell
caas settings
caas settings --time-zone Europe/Berlin
caas audit
caas audit --action sandbox --since 2026-10-01
caas audit --action sandbox.stop --outcome failure --limit 20

caas settings prints the workspace's time zone, its one setting. --time-zone ZONE sets it, an IANA name such as Europe/Berlin; new sandboxes take their nightly snapshot at 02:00 in it.

caas audit lists who changed what in the workspace, newest first: the time, who did it, the action, its target, the outcome and the request ID. Records are kept for 365 days.

OptionWhat it does
--action ACTIONAn action, such as sandbox.stop or api_key.create, or a group: sandbox, command, mcp_token, secret, egress, api_key, member, invite, tenant, billing or workflow.
--actor IDA user or API key ID, or operator or system.
--target IDThe ID of what was changed.
--outcome OUTCOMEsuccess or failure.
--since TIME, --until TIMEISO 8601 times, such as 2026-10-01 or 2026-10-01T12:00:00Z.
--limit NRecords per page, 1 to 100.
--cursor CURSORThe next page: the value the previous page printed.

An API key never sees records about API keys, members or invites, and sees billing records only with Billing access. In what a key reads, users show as their user ID rather than their email.