Skip to content
Scalpels home

Scalpels is officially launching on October 31, 2026. Special early adopter pricing is available now.

← All guides

Guide

A Comprehensive Agent's Guide to Laravel Cloud

Know your CLI

· Ed Grosvenor

Most of the contradictions we found in our own notes turned out to be two agents running two different CLIs. Settle which one you have before you trust anything else.

Find the binary you will actually run

command -v cloud
cloud --version

Run both in the same shell your commands will run in. An interactive shell and an agent's non-interactive shell can resolve cloud differently. On one machine we used, an alias in the interactive shell pointed at a months-old source checkout, while the agent's shell found the Composer global binary. The two had different commands and different output, so notes written by one were wrong for the other.

Install and upgrade with Composer:

composer global require laravel/cloud-cli
cloud self-update

If you cannot touch the global install, a disposable Composer project with laravel/cloud-cli required at a known version works just as well. Call its vendor/bin/cloud by full path.

Releases that change what is safe

Version What changed for agents
v0.5.0 environment:update --database-id and --cache-id appeared to do nothing, and attachment fields read back null. database-cluster:list failed with a 400 after the API renamed a relationship. cache:list --json printed live cache passwords. bucket-key:get --show-sensitive returned no secret.
v0.5.2 The attachment read bug was fixed. Attaching databases and caches with environment:update works from here.
v0.5.3 Bucket key secrets are returned again with --show-sensitive.
v0.6.0 JSON output masks sensitive values by default, and every command accepts --show-sensitive and --fields. cloud tinker exists.
v0.6.1 Follows the API's move to versionless database types.
v0.6.2 An environment ID or name that cannot be resolved is now an error. Before this, it silently fell back to another environment, and writes landed there. Listings fetch pages up to a cap of 2,000 rows.
v0.6.3 Adds environment:metrics, database-cluster:metrics, cache:metrics and the WebSocket metrics commands.

If you are below v0.6.2, upgrade before any write. The environment fallback is the single most dangerous behaviour in this guide. It is covered on Work in the right organization.

Drive it non-interactively

The CLI decides whether it may prompt. It treats you as non-interactive when standard input is not a terminal, when it detects a coding agent, when CI, GITHUB_ACTIONS, GITLAB_CI, JENKINS_URL, CIRCLECI or TRAVIS is set, or when you pass --json, -n or --no-interaction.

When a non-interactive command needs a choice it cannot make, it writes a JSON error to standard error and exits with status 1. The error usually includes the options it would have offered:

{"error": true, "message": "Multiple environments found. Provide an environment ID or name.", "options": {"env-…": "production", "env-…": "staging"}}

Treat that as an instruction to supply the identifier, not as a list to pick from. See rule 3.

Use these conventions, which match the guidance Laravel ships for agents with cloud skills:install:

  • Always pass -n.
  • Never pass -q or --silent. You need the output.
  • Add --json to reads and creates, and always add --fields alongside it.
  • Add --force to updates and deletes.
  • Run cloud <command> -h at the moment you need a command. Do not rely on a remembered signature. The help output also lists every JSON field a command can return, which is what you pass to --fields.

A few commands are interactive by design and should be left to a human: cloud auth opens a browser, and cloud ship walks through a guided first deployment.

Flags that are not what they look like

  • --env is not a Cloud environment. Every command accepts a global --env option, but it is the CLI framework's own application environment. Passing --env=<environment-id> is silently ignored, so the command runs against whatever environment it resolves on its own. Cloud environments are positional arguments: cloud command:run <environment-id> ….
  • There is no per-command organization flag. Only repo:config accepts --organization. How the organization is chosen is covered on the next page.
  • --tail does not raise the log limit. environment:logs returns at most 100 entries per call, whatever you pass. See Reads that lie.

When the CLI is not enough

The CLI wraps most, but not all, of the API at https://cloud.laravel.com/api. We used the API directly for full deployment logs, environment logs over a time window, attaching a bucket to an environment, and sizing instances. The API has its own traps:

  • Send Accept: application/vnd.api+json, and the same Content-Type on writes. A plain application/json request returns 401 Unauthenticated, which looks exactly like a bad token.
  • Use the published specification with suspicion. It lives at https://cloud.laravel.com/api-docs/api.json. We found it wrong four times on a single endpoint, and on 28 September 2026 it changed by roughly a thousand lines at once. Its enums tell you which values exist, not which ones a given resource accepts. When the specification and a live response disagree, the live response is the truth.
  • One token reaches exactly one organization. That is different from Laravel Forge, where one token can reach several.

Want some help?

After you buy, we will pay for an hour with one of these experts to help you get everything up and running.

  • Artisan Build

    USA

    We run Scalpels, as well as a suite of other tools for developers and development teams.

    Agency Ask for help
    Ask Artisan Build for help