Scripting
JSON output, exit codes, waiting and safe retries for scripts, CI and agents.
Output
When stdout is not a terminal — in a pipe, a script or an agent — the CLI prints JSON: the API's own response shapes. In a terminal it prints tables; add --json to get JSON there too.
layerbeat ls --json | jq -r '.data[] | select(.status == "running") | .name'
layerbeat ls -q # names only, one per lineErrors go to stderr, as JSON when stdout is not a terminal, and leave stdout empty.
Never prompt
--no-input makes any command fail instead of asking a question. Without a terminal the CLI never prompts anyway: layerbeat new with a missing flag is an error, not a question.
Saying yes to purchases
Buying or renewing a server or a disk spends credit, so it needs a yes. In a terminal the CLI shows the order and asks. In a script or agent, pass --yes (-y). Without it, the command exits 2 with confirmation_required and nothing is bought.
Exit codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 2 | Usage error (a missing or wrong flag), or a purchase without --yes and without a terminal (confirmation_required) |
| 3 | Not signed in, or the key lacks the permission |
| 4 | Not found |
| 5 | Invalid state: the server is busy, already in that state, or the change conflicts |
| 6 | Not enough credit, or the total is above your --max-price |
| 7 | Rate limited: wait and try again |
| 8 | --wait timed out (the operation may still finish; check it with layerbeat operation) |
| 9 | Layerbeat or the network is unavailable |
| 10 | Out of stock, or a quota is reached |
Don't retry 2, 3, 4, 6 or 10 without changing something; back off before retrying 7 and 9.
Waiting
Changes run as operations. By default a command returns as soon as the change is accepted, with an op_... ID. Then:
layerbeat start agent-01 --wait # wait inside the command
layerbeat wait op_... --timeout 900 # or wait later
layerbeat operation op_... # check without waitingSafe retries
Buying (new, renew, volume new, volume renew, topup) takes an --idempotency-key. The same key never charges twice, so a script that times out or crashes can simply run the same command again with the same key:
KEY=deploy-$(date +%Y%m%d)-agent-01
layerbeat new agent-01 --region sgp --plan SG-B224 --image "Ubuntu 24.04" \
--ssh-key ci --max-price 5 --idempotency-key "$KEY" --no-input --yes --waitAlways pass --max-price in automation: the command refuses a total above it, whatever the price is when it runs. See Safe retries.
Any API call
layerbeat api calls any endpoint with your sign-in or key, for anything without its own command:
layerbeat api GET /v1/billing/wallet
layerbeat api POST /v1/vms/vm_.../firewall-rules -d '{"protocol":"tcp","port":"8080"}'
layerbeat api POST /v1/vms -d @order.json -H "Idempotency-Key: $KEY"-d takes JSON, @file or - for stdin. The API reference lists every endpoint.
In CI
# GitHub Actions
- run: curl -fsSL https://layerbeat.com/install.sh | sh
- run: echo "$HOME/.local/bin" >> "$GITHUB_PATH"
- run: layerbeat template update https-proxy --server web-1 --wait
env:
LAYERBEAT_API_KEY: ${{ secrets.LAYERBEAT_API_KEY }}layerbeat ssh, exec and cp also need an SSH private key that the server accepts, available to the job.