# acli commands

<VersionBadge label="acli" version="4.0.0" href="https://github.com/acquia/cli" />

Lookup material for [acli](/start-here/glossary/#acli), Acquia's Cloud Platform CLI. For task-oriented instructions, see the [CLI quickstart](/cloud-platform/cli/quickstart/) and [everyday workflows](/cloud-platform/cli/everyday-workflows/); for choosing between `acli` and other CLIs, see [Which CLI do I use?](/cloud-platform/cli/#which-cli-do-i-use). `acli <command> --help` is the exhaustive per-command source.

## Find a command by task

| I want to… | Commands | Guide |
| --- | --- | --- |
| Install acli and authenticate | [`auth:login`](#authlogin) | [CLI quickstart](/cloud-platform/cli/quickstart/) |
| Point acli at the right app and [environment](/start-here/glossary/#environment) | [`app:link`](#applink), [`remote:aliases:list`](#remotealiaseslist) | [Everyday workflows](/cloud-platform/cli/everyday-workflows/) |
| Tail logs from an environment | [`app:log:tail`](#applogtail) | [Everyday workflows](/cloud-platform/cli/everyday-workflows/#tail-logs-from-an-environment) |
| Copy a database or files to local | [`pull:database`](#pulldatabase), [`pull:files`](#pullfiles) | [Everyday workflows](/cloud-platform/cli/everyday-workflows/#pull-a-database-or-files) |
| Run Drush remotely or open a shell | [`remote:drush`](#remotedrush), [`remote:ssh`](#remotessh) | [Everyday workflows](/cloud-platform/cli/everyday-workflows/#run-drush-remotely-or-open-a-shell) |
| Deploy code as a build artifact | [`push:artifact`](#pushartifact) | [Everyday workflows](/cloud-platform/cli/everyday-workflows/#deploy-code-as-an-artifact) |
| See which branch or tag each environment has deployed | [`app:vcs:info`](#applications-and-projects) | [Code-workflow quickstart](/cloud-platform/code-workflow/quickstart/) |
| Switch an environment's code, or roll production back | [`api:environments:code-switch`](#the-cloud-platform-api) | [Code-workflow guide](/cloud-platform/code-workflow/guide/#roll-back-a-release) |
| Back up or restore an environment's database | [`api:environments:database-backup-create`](#the-cloud-platform-api), [`api:environments:database-backup-restore`](#the-cloud-platform-api) | [Code-workflow guide](/cloud-platform/code-workflow/guide/#roll-back-a-release) |
| Create scheduled jobs, or copy them between environments | [`api:environments:cron-create`](#the-cloud-platform-api), [`env:cron-copy`](#manage-environments) | [Run scheduled jobs](/cloud-platform/configure/cron/) |
| Create or delete a temporary environment | [`env:create`](#envcreate), [`env:delete`](#envdelete), [`app:task-wait`](#apptask-wait) | [Everyday workflows](/cloud-platform/cli/everyday-workflows/#temporary-environments) |
| Authenticate in scripts and CI | [`auth:login`](#authlogin) with [environment variables](#environment-variables) | [Everyday workflows](/cloud-platform/cli/everyday-workflows/#non-interactive-authentication) |
| Wrap a command with extra build steps | [Composer hook points](#composer-hook-points) | [Everyday workflows](/cloud-platform/cli/everyday-workflows/#hook-scripts-around-any-acli-command) |
| Set up [Code Studio](/start-here/glossary/#code-studio) | [`codestudio:wizard`](#codestudiowizard) | [Code Studio](/cloud-platform/ci-cd/) |
| Create a [Cloud IDE](/start-here/glossary/#cloud-ide) | [`ide:create`](#cloud-ides) | [Acquia's Cloud IDE documentation](https://docs.acquia.com/acquia-cloud-platform/add-ons/cloud-ide/overview) |
| Decide between acli, drush, and the other CLIs | — | [Which CLI do I use?](/cloud-platform/cli/#which-cli-do-i-use) |

## Global flags

Every command accepts these flags in addition to its own; an entry below with no flag table of its own takes only these. All flags are boolean toggles, default off, taking no value:

| Flag | Description |
| --- | --- |
| `-h`, `--help` | Display help for the given command. When no command is given, display help for the `list` command |
| `-q`, `--quiet` | Do not output any message |
| `-V`, `--version` | Display the application version |
| `--ansi` / `--no-ansi` | Force (or disable) ANSI output |
| `-n`, `--no-interaction` | Do not ask any interactive question |
| `-v`, `-vv`, `-vvv`, `--verbose` | Increase the verbosity of messages: 1 for normal output, 2 for more verbose output, 3 for debug |

`--verbose` is the first tool for troubleshooting: most `acli` error messages become diagnosable when the command is re-run with it.

## Exit codes

`acli` follows console conventions: **0** on success, **1** on any failure (API errors, invalid arguments, aborted operations). The exceptions are the two ways of waiting on a platform task: [`app:task-wait`](#apptask-wait), and any `api:*` command run with [`--task-wait`](#waiting-for-a-task-to-finish). Both report the awaited task's outcome rather than whether the request itself was accepted.

## Authenticate

The `auth` namespace registers and removes API credentials.

| Command | What it does |
| --- | --- |
| `auth:acsf-login` | Register Site Factory API credentials; prompts for any omitted value |
| `auth:acsf-logout` | Remove Site Factory API credentials |
| `auth:logout` (alias `logout`) | Remove Cloud Platform API credentials |

### auth:login

Register Cloud Platform API credentials. `acli` can store multiple credential sets; only one is active at a time, and this command activates a new or existing set (see [Credentials file](#credentials-file)). Alias: `login`.

```bash
acli auth:login [-k <key>] [-s <secret>]
```

| Flag | Type | Default | Description |
| --- | --- | --- | --- |
| `-k`, `--key` | string | — | Your Cloud Platform API key. Prompts when omitted |
| `-s`, `--secret` | string | — | Your Cloud Platform API secret. Prompts when omitted |

The first run on a machine also asks a one-time telemetry question:

```text
$ acli auth:login
No Cloud Platform API key is active
You will need a Cloud Platform API token from https://cloud.acquia.com/a/profile/tokens

 Do you want to open this page to generate a token now? (yes/no) [yes]:
 >
[INFO] Opening https://cloud.acquia.com/a/profile/tokens
```

The non-interactive form `acli auth:login --key=<key> --secret=<secret>` saves and activates the credentials directly, confirming with `The following Cloud Platform API key is active: <account email>` (captured).

Used in: [CLI quickstart](/cloud-platform/cli/quickstart/), [non-interactive auth](/cloud-platform/cli/everyday-workflows/#non-interactive-authentication).

## Applications and projects

The `app` and `archive` namespaces: link your working directory to a Cloud Platform application, inspect it, scaffold new projects, and export the whole thing.

| Command | What it does |
| --- | --- |
| `app:new:from:drupal7` (aliases `from:d7`, `ama`) | Generate a Drupal 9+ project from a Drupal 7 application using the default Acquia Migrate Accelerate recommendations |
| `app:new:local` (alias `new`) | Create a new Drupal or Next.js project from a template |
| `app:open` (aliases `open`, `o`) | Open the application in the Cloud Platform user interface |
| `app:vcs:info` | List the application's branches and tags with their deployment status; `--deployed` narrows it to the ones an environment is running (used in the [code-workflow quickstart](/cloud-platform/code-workflow/quickstart/)) |
| `archive:export` | Export an archive of the Drupal application including code, files, and database |

### app:link

Associate your project with a Cloud Platform application: writes `cloud_app_uuid` to `.acquia-cli.yml` (see [Project link file](#project-link-file)). Alias: `link`.

```bash
acli app:link [<applicationUuid>]
```

`applicationUuid` (optional): the application UUID or alias (an application name optionally prefixed with the realm, the hosting cluster identifier shown alongside the application name in `acli api:applications:find` output, e.g. `myapp` or `prod:myapp`). Prompts interactively when omitted.

Example (captured 2026-07-06, identifiers redacted):

```text
$ acli app:link myapp
 [OK] The Cloud application myapp has been linked to this repository by writing to /path/to/project/.acquia-cli.yml
```

Used in: [Everyday workflows](/cloud-platform/cli/everyday-workflows/#know-what-youre-pointed-at).

### app:log:tail

Tail the logs from your environments. Prompts for which logs to stream, then streams until interrupted. Aliases: `tail`, `log:tail`.

```bash
acli app:log:tail [<environmentId>]
```

`environmentId` (optional): the environment ID or alias (`myapp.dev`, `prod:myapp.dev`, or a UUID). Prompts interactively when omitted.

Each line is the log record as the platform wrote it, unprefixed and in that log type's own format; the types you pick at the prompt decide which records appear. Nothing is printed between requests, so a quiet environment shows the header and then waits.

Example (captured 2026-08-03, two of the streamed lines, identifiers and addresses redacted):

```text
$ acli app:log:tail myapp.dev
Streaming has started and new logs will appear below. Use Ctrl+C to exit.
127.0.0.1 - - [03/Aug/2026:10:07:46 +0000] "GET /?docs-capture=1 HTTP/1.1" 200 1001 "-" "curl/8.14.1" status=200 bytes=1001 http_host=myappdev.prod.acquia-sites.com affinity="-" upstream_addr="<ip>:443" hosting_site=myappdev request_time=0.017 forwarded_for="<client-ip>" upstream_status="200" request_id="v-<uuid>" ssl_protocol="-" ssl_cipher="-"
127.0.0.1 - - [03/Aug/2026:10:07:50 +0000] "GET /?docs-capture=2 HTTP/1.1" 200 1001 "-" "curl/8.14.1" status=200 bytes=1001 http_host=myappdev.prod.acquia-sites.com affinity="-" upstream_addr="<ip>:443" hosting_site=myappdev request_time=0.011 forwarded_for="<client-ip>" upstream_status="200" request_id="v-<uuid>" ssl_protocol="-" ssl_cipher="-"
```

Used in: [Everyday workflows](/cloud-platform/cli/everyday-workflows/#tail-logs-from-an-environment).

### app:task-wait

Wait for a task to complete.

```bash
acli app:task-wait <notification-uuid>
```

`notification-uuid` (required): a task notification UUID, or a Cloud Platform API JSON response containing a linked notification (the JSON must contain the `_links->notification->href` property).

Exit codes: **0** if the awaited task completes successfully, **1** if the task fails; this is the one command whose exit code reports more than command success.

The command prints the task's final record after the wait: progress, completion time, task type, and how long it took.

Example (captured 2026-08-03, UUIDs redacted):

```text
$ acli app:task-wait "$(acli api:environments:database-backup-create myapp.dev my_db)"
    ✔ Waiting for task <uuid> to complete

 [OK] The task with notification uuid <uuid> completed

Progress: 100
Completed: Mon Aug 3 13:21:47 EEST 2026
Task type: Database backup created
Duration: 30 seconds
```

Used in: [Everyday workflows](/cloud-platform/cli/everyday-workflows/#temporary-environments).

### app:unlink

Remove the local association between your project and a Cloud Platform application; operates on the current directory's `.acquia-cli.yml`. Alias: `unlink`.

```bash
acli app:unlink
```

Example (captured 2026-07-06, identifiers redacted):

```text
$ acli app:unlink
Unlinked /path/to/project from Cloud application myapp
```

Used in: [Everyday workflows](/cloud-platform/cli/everyday-workflows/#know-what-youre-pointed-at).

## Pull from an environment

All `pull:*` commands accept an optional `environmentId` argument (ID or alias such as `myapp.dev`; prompts when omitted) and a `--siteInstanceId` flag (string, the Site Instance ID in the form `SITEID.EnvironmentID`). All of them except `pull:code` also accept an optional `site` argument: for a multisite application, the directory name of the site.

| Command | What it does |
| --- | --- |
| `pull:code` | Copy code from a Cloud Platform environment |
| `pull:run-scripts` | Execute post-pull scripts |

### pull:all

Copy code, database, and files from a Cloud Platform environment. Aliases: `refresh`, `pull`.

```bash
acli pull:all [<environmentId>] [<site>] [options]
```

| Flag | Type | Default | Description |
| --- | --- | --- | --- |
| `--dir` | string | — | The directory containing the Drupal project to be refreshed |
| `--no-code` | boolean | `false` | Skip copying code |
| `--no-files` | boolean | `false` | Skip copying files |
| `--no-databases` | boolean | `false` | Skip copying databases |
| `--no-scripts` | boolean | `false` | Do not run additional scripts after code and database are copied (e.g. `composer install`, `drush cache-rebuild`) |

The code step is a `git fetch --all` followed by `git checkout <the environment's branch>` in the local repository, so it aborts on uncommitted changes rather than overwriting them. When the database step prints its backup-age notice, `acli` redraws over the completed code line, so the finished run shows the file, database, and script steps but not the code step it already ran.

Example (captured 2026-08-03, identifiers redacted):

```text
$ acli pull myapp.dev default
    ✔ Copying Drupal's public files from the Cloud Platform
        Connecting to database db

 [INFO] Using a database backup that is 4 hours old. Backup #355275600 was created at Mon Aug 3 9:16:09 EEST 2026.

        You can view your backups here: https://cloud.acquia.com/a/environments/<environment-id>/databases

        To generate a new backup, re-run this command with the --on-demand option.

    ✔ Downloading my_db database copy from the Cloud Platform
    ✔ Importing my_db database download
 ! [NOTE] Composer dependencies already installed. Skipping composer install.
```

Used in: [Everyday workflows](/cloud-platform/cli/everyday-workflows/#pull-a-database-or-files).

### pull:database

Import a database backup from a Cloud Platform environment. Uses the latest available database backup, which may be up to 24 hours old; if no backup exists, one is created. Requires an active local database connection: set `ACLI_DB_HOST`, `ACLI_DB_NAME`, `ACLI_DB_USER`, `ACLI_DB_PASSWORD` (see [environment variables](#environment-variables)). Alias: `pull:db`.

```bash
acli pull:database [<environmentId>] [<site>] [options]
```

| Flag | Type | Default | Description |
| --- | --- | --- | --- |
| `--no-scripts` | boolean | `false` | Do not run additional scripts after the database is pulled (e.g. `drush cache-rebuild`, `drush sql-sanitize`) |
| `--on-demand` | boolean | `false` | Force creation of an on-demand backup (much slower than using an existing backup) |
| `--no-import` | boolean | `false` | Download the backup but do not import it (implies `--no-scripts`) |
| `--multiple-dbs` | boolean | `false` | Download multiple databases |

The backup's age is reported before the download, with the console link to the environment's backup list and the reminder that `--on-demand` forces a fresh one. Import drops the local database's tables first, so the local database is replaced rather than merged. `acli pull:db myapp.prod --no-import` stops after the download.

Example (captured 2026-08-03, identifiers redacted):

```text
$ acli pull:database myapp.dev --no-scripts

 [INFO] Using a database backup that is 4 hours old. Backup #355275600 was created at Mon Aug 3 9:16:09 EEST 2026.

        You can view your backups here: https://cloud.acquia.com/a/environments/<environment-id>/databases

        To generate a new backup, re-run this command with the --on-demand option.

    ✔ Downloading my_db database copy from the Cloud Platform
    ✔ Importing my_db database download
```

Used in: [Everyday workflows](/cloud-platform/cli/everyday-workflows/#pull-a-database-or-files).

### pull:files

Copy Drupal public files from a Cloud Platform environment to your local environment.

```bash
acli pull:files [<environmentId>] [<site>]
```

The transfer is an `rsync` over SSH into `docroot/sites/<site>/files`, so it is incremental: a second run copies only what changed.

Example (captured 2026-08-03, identifiers redacted):

```text
$ acli pull:files myapp.dev default
    ✔ Copying Drupal's public files from the Cloud Platform
```

Used in: [Everyday workflows](/cloud-platform/cli/everyday-workflows/#pull-a-database-or-files).

## Push to an environment

Every `push:*` command accepts the same `--siteInstanceId` flag as its `pull:*` counterpart (string, `SITEID.EnvironmentID`).

There is no working `push:code` command; code deployment through `acli` is artifact-based via [`push:artifact`](#pushartifact). (A hidden `push:code` stub is unhidden inside a Cloud IDE or a Lando environment. It only prints `Use git to push code changes upstream.` and exits 0.)

### push:artifact

Build and push a code artifact to a Cloud Platform environment. Builds a sanitized deploy artifact by running `composer install`, removing sensitive files, and committing vendor directories and scaffold files, even if they are ignored in the source repository. Designed for the two-branch scenario: a source branch without vendor files committed and an artifact branch with them; if both are the same branch, use plain `git push` instead. To run additional build or sanitization steps (e.g. `npm install`), add a `post-install-cmd` script to `composer.json`. Aborts if the local repository has uncommitted changes (`Pushing code was aborted because your local Git repository has uncommitted changes. Either commit, reset, or stash your changes via git.`).

```bash
acli push:artifact [<environmentId>] [options]
```

| Flag | Type | Default | Description |
| --- | --- | --- | --- |
| `--dir` | string | — | The directory containing the Drupal project to be pushed |
| `--no-sanitize` | boolean | `false` | Do not sanitize the build artifact |
| `--no-push` | boolean | `false` | Do not push changes to Acquia Cloud |
| `--no-commit` | boolean | `false` | Do not commit changes (implies `--no-push`) |
| `--no-clone` | boolean | `false` | Do not clone the repository (implies `--no-commit` and `--no-push`) |
| `-u`, `--destination-git-urls` | array of string | — | The git URL(s) to push the artifact branch to (repeatable) |
| `-b`, `--destination-git-branch` | string | — | The destination branch |
| `-t`, `--destination-git-tag` | string | — | The destination tag (requires `--destination-git-branch`) |
| `--siteInstanceId` | string | — | The Site Instance ID (`SITEID.EnvironmentID`) |

`--dry-run` and `-s`, `--source-git-tag` are deprecated. Defaults may also come from the `ACLI_PUSH_ARTIFACT_*` [environment variables](#environment-variables).

The run opens with a note listing exactly what it is about to do, including the git remote it will push to, so the destination is visible before anything is written. When `--destination-git-branch` names a branch that does not exist upstream yet, the fetch for it fails and `acli` creates the branch locally instead, then pushes it as a new branch. Passing `--destination-git-branch` also makes the `environmentId` argument unnecessary: the argument is only read to work out the destination branch from the environment's deployed VCS path.

Example (captured 2026-08-03, identifiers redacted):

```text
$ acli push:artifact --destination-git-branch=docs-capture-build

 ! [NOTE] Acquia CLI will:
 !
 !        - git clone docs-capture-build from
 !        myapp@svn-<id>.prod.hosting.acquia.com:myapp.git
 !
 !        - Compile the contents of /path/to/project into an artifact in a
 !        temporary directory
 !
 !        - Copy the artifact files into the checked out copy of
 !        docs-capture-build
 !
 !        - Commit changes and push the docs-capture-build branch to the
 !        following git remote(s):
 !
 !          myapp@svn-<id>.prod.hosting.acquia.com:myapp.git

    ✔ Preparing artifact directory
    ✔ Generating build artifact
    ✔ Sanitizing build artifact
    ✔ Committing changes (commit hash: 654564fd504bc60851694ef31995c21126fd4cb8)
    ✔ Pushing changes to docs-capture-build branch.
```

Used in: [Everyday workflows](/cloud-platform/cli/everyday-workflows/#deploy-code-as-an-artifact).

### push:database

Push a database from your local environment to a Cloud Platform environment. Destructive on the target: run the [pre-flight check](/cloud-platform/cli/everyday-workflows/#know-what-youre-pointed-at) first. Alias: `push:db`.

```bash
acli push:database [<environmentId>] [<site>]
```

The confirmation names the target database and environment before anything is written, and defaults to yes, so an unattended run overwrites. The three steps are a local `mysqldump`, an `rsync` of the compressed dump to the environment, and an import over SSH; the local connection comes from the `ACLI_DB_*` [environment variables](#environment-variables).

Example (captured 2026-08-03, identifiers redacted):

```text
$ acli push:database myapp.dev

 Overwrite the my_db database on dev with a copy of the database from the current machine? (yes/no) [yes]:
 > yes

    ✔ Creating local database dump
    ✔ Uploading database dump to remote machine
    ✔ Importing database dump into MySQL on remote machine
```

Used in: [Migrate an existing site](/cloud-platform/code-workflow/migrate-to-cloud-platform/#import-the-database).

### push:files

Copy Drupal public files from your local environment to a Cloud Platform environment, overwriting the target's files.

```bash
acli push:files [<environmentId>] [<site>]
```

Like its `pull:` counterpart the transfer is an `rsync`, so it adds and updates rather than mirroring: files that exist only on the environment stay. Omit the `site` argument and the command prompts for the site directory.

Example (captured 2026-08-03, identifiers redacted):

```text
$ acli push:files myapp.dev default

 Overwrite the public files directory on dev with a copy of the files from the current machine? (yes/no) [yes]:
 > yes

    ✔ Pushing public files directory to remote machine
```

Used in: [Migrate an existing site](/cloud-platform/code-workflow/migrate-to-cloud-platform/#import-the-files).

## Manage environments

The `env` namespace creates, deletes, and reshapes environments.

| Command | What it does |
| --- | --- |
| `env:certificate-create` | Install an SSL certificate |
| `env:cron-copy` | Copy all cron tasks from one environment to another (used in [scheduled jobs](/cloud-platform/configure/cron/)) |

### env:create

Create a new Continuous Delivery Environment (CDE).

```bash
acli env:create <label> [<branch>] [<applicationUuid>]
```

`label` (required): the label of the new environment; `branch` (optional): the VCS path (git branch name) to deploy to the new environment; `applicationUuid` (optional).

The branch must already exist on the remote VCS: the command rejects a name it cannot find, rather than creating it.

The label is a display name, not an address. The environment's alias is `myapp.ode<n>`, numbered in creation order across the application's lifetime, and the domain is that same pair with the dot removed. The `pr-123` environment below is `myapp.ode2`, reachable at `myappode2.prod.acquia-sites.com`. Take the alias from the command's own URL line or from [`remote:aliases:list`](#remotealiaseslist), never from the label.

Example (captured 2026-08-03, identifiers redacted):

```text
$ acli env:create pr-123 master
    ✔ Checking to see that label is unique
    ✔ Determining default database
    ✔ Initiating environment creation
    ✔ Waiting for the environment to be ready. This usually takes 2 - 15 minutes.

Your CDE URL: myappode2.prod.acquia-sites.com
```

A subscription's CDE allowance is finite. When it is used up the command fails at the third step, on the Cloud Platform API's own error rather than a local check, so the first two steps still report success:

```text
$ acli env:create docs2 master
    ✔ Checking to see that label is unique
    ✔ Determining default database
    ⌛ Initiating environment creation...

In ExceptionListener.php line 120:

  Cloud Platform API returned an error: This application already has the maxi
  mum number of CD environments.
```

Delete an existing CDE with [`env:delete`](#envdelete) and retry.

Used in: [Everyday workflows](/cloud-platform/cli/everyday-workflows/#temporary-environments).

### env:delete

Delete a Continuous Delivery Environment (CDE).

```bash
acli env:delete [<environmentId>]
```

`environmentId` (optional): environment ID or alias. Omit it and the command lists the application's CDEs by label and prompts; that list is the reliable way to find a CDE's alias, because the alias is `myapp.ode<n>` and not the label passed to [`env:create`](#envcreate).

The command returns as soon as the platform accepts the request: the environment is deleted in the background, so the confirmation is phrased as "is being deleted" rather than "deleted".

Example (captured 2026-08-03, identifiers redacted):

```text
$ acli env:delete myapp.ode2

 [OK] The pr-123 environment is being deleted
```

Used in: [Everyday workflows](/cloud-platform/cli/everyday-workflows/#temporary-environments).

### env:mirror

Makes one environment identical to another in terms of code, database, files, and configuration. Destructive on the destination: run the [pre-flight check](/cloud-platform/cli/everyday-workflows/#know-what-youre-pointed-at) first.

```bash
acli env:mirror <source-environment> <destination-environment> [options]
```

`source-environment`, `destination-environment` (required): environment IDs or aliases.

| Flag | Type | Default | Description |
| --- | --- | --- | --- |
| `-c`, `--no-code` | boolean | `false` | Skip mirroring code |
| `-d`, `--no-databases` | boolean | `false` | Skip mirroring databases |
| `-f`, `--no-files` | boolean | `false` | Skip mirroring files |
| `-p`, `--no-config` | boolean | `false` | Skip mirroring configuration |

All four copies are started first and awaited afterwards, so they run concurrently on the platform and the command's wall-clock time is the slowest of them rather than their sum. Each one is a platform task, reported the same way [`app:task-wait`](#apptask-wait) reports one. The code step is a branch switch to the source environment's deployed branch, not a code copy, so mirroring between two environments already on the same branch leaves the code untouched. The confirmation defaults to yes.

Example (captured 2026-08-03, identifiers and UUIDs redacted):

```text
$ acli env:mirror myapp.test myapp.dev
    ✔ Fetching information about source environment
    ✔ Fetching information about destination environment

 Are you sure that you want to overwrite everything on Dev (dev) and replace it with source data from Stage (test) (yes/no) [yes]:
    ✔ Initiating code switch
    ✔ Initiating database copy
    ✔ Initiating files copy
    ✔ Initiating config copy
    ✔ Waiting for code copy to complete

 [OK] The task with notification uuid <uuid> completed

Progress: 100
Completed: Mon Aug 3 13:25:47 EEST 2026
Task type: Code switched
Duration: 16 seconds
    ✔ Waiting for database copy to complete

 [OK] The task with notification uuid <uuid> completed

Progress: 100
Completed: Mon Aug 3 13:28:03 EEST 2026
Task type: Database copied
Duration: 147 seconds
    ✔ Waiting for files copy to complete

 [OK] The task with notification uuid <uuid> completed

Progress: 100
Completed: Mon Aug 3 13:26:37 EEST 2026
Task type: Files copied
Duration: 55 seconds
    ✔ Waiting for config copy to complete

 [OK] The task with notification uuid <uuid> completed

Progress: 100
Completed: Mon Aug 3 13:27:54 EEST 2026
Task type: Environment configuration updated
Duration: 126 seconds

 [OK] Done! Dev now matches Stage

      You can visit it here:

      https://myappdev.prod.acquia-sites.com
```

## SSH, remote Drush, and aliases

The `remote` namespace runs things on your environments over SSH and manages the Drush aliases that address them.

### remote:aliases:download

Download Drush aliases for the Cloud Platform.

```bash
acli remote:aliases:download [<applicationUuid>] [options]
```

| Flag | Type | Default | Description |
| --- | --- | --- | --- |
| `--destination-dir` | string | — | The directory to which aliases will be downloaded |
| `--all` | boolean | `false` | Download the aliases for all applications you have access to, not just the current one |

Example (captured 2026-07-06, identifiers redacted):

```text
$ acli remote:aliases:download myapp --destination-dir=/path/to/aliases
Drush changed how aliases are defined in Drush 9. Drush 8 aliases are PHP-based and stored in your home directory, while Drush 9+ aliases are YAML-based and stored with your project.
Cloud Platform Drush aliases installed into /path/to/aliases
```

Used in: [code workflow section](/cloud-platform/code-workflow/).

### remote:aliases:list

List all aliases for the Cloud Platform environments. Prompts for the application when the UUID is omitted. Aliases: `aliases`, `sa`.

The suffix in an alias is the environment's name, not the label on its environment card. The environment labeled **Stage** is named `test`, so its alias is `myapp.test`. `acli` matches the suffix against those names exactly, so `myapp.stage` resolves nothing and every command that takes an alias fails on it.

```bash
acli remote:aliases:list [<applicationUuid>]
```

Example (hostnames redacted):

```text
$ acli remote:aliases:list myapp
+------------+---------------------------------------------+--------------------------------+
| Alias      | UUID                                        | SSH URL                        |
+------------+---------------------------------------------+--------------------------------+
| myapp.dev  | 146125-04f18e5e-3e19-4698-ac58-c162df025345 | myapp.dev@…ssh.prod.acquia-sites.com  |
| myapp.prod | 146123-04f18e5e-3e19-4698-ac58-c162df025345 | myapp.prod@…ssh.prod.acquia-sites.com |
| myapp.test | 146124-04f18e5e-3e19-4698-ac58-c162df025345 | myapp.test@…ssh.prod.acquia-sites.com |
+------------+---------------------------------------------+--------------------------------+
Run acli api:environments:find <alias> to get more information about a specific environment.
```

Used in: [Everyday workflows](/cloud-platform/cli/everyday-workflows/#know-what-youre-pointed-at).

### remote:drush

Run a [Drush](/start-here/glossary/#drush) command (Drupal's own application-level CLI; see [Which CLI do I use?](/cloud-platform/cli/#which-cli-do-i-use)) remotely on a Cloud Platform environment. Note the `--` separating the `acli` arguments from the Drush command and its options; it is required. Aliases: `drush`, `dr`.

```bash
acli remote:drush [<environmentId>] -- <drush_command>
```

`environmentId` (optional); `drush_command`: the Drush command, after `--`.

The Drush that runs is the environment's own, resolved from the deployed codebase, and its output comes back unaltered: `acli` adds nothing to it. Everything the report names (database host, PHP binary, Drupal root) is the environment's, which is what makes `status` the fastest way to confirm a deploy landed.

Example (captured 2026-08-03, credentials and identifiers redacted):

```text
$ acli remote:drush myapp.dev -- status
Drupal version   : 11.2.5
Site URI         : http://myappdev.prod.acquia-sites.com
DB driver        : mysql
DB hostname      : db-<id>.cdb.database.services.acquia.io
DB port          : 3306
DB username      : <db-user>
DB name          : <db-name>
Database         : Connected
Drupal bootstrap : Successful
Default theme    : olivero
Admin theme      : claro
PHP binary       : /usr/local/php8.3/bin/php
PHP config       : /usr/local/php8.3/etc/cli/php.ini
PHP OS           : Linux
PHP version      : 8.3.31
Drush script     : /var/www/html/vendor/bin/drush.php
Drush version    : 13.6.2.0
Drush temp       : /tmp
Drush configs    : /etc/drush/drush.yml
                   /var/www/html/vendor/drush/drush/drush.yml
Install profile  : standard
Drupal root      : /var/www/html/docroot
Site path        : sites/default
Files, Public    : sites/default/files
Files, Private   : /mnt/files/myapp.dev/sites/default/files-private
Files, Temp      : /tmp
Drupal config    : ../config/default
```

Used in: [Everyday workflows](/cloud-platform/cli/everyday-workflows/#run-drush-remotely-or-open-a-shell), [Which CLI do I use?](/cloud-platform/cli/#which-cli-do-i-use).

### remote:ssh

Use SSH to open a shell or run a command in a Cloud Platform environment. Requires an SSH key registered with the platform ([`ssh-key:create-upload`](#ssh-keycreate-upload)). Alias: `ssh`.

```bash
acli remote:ssh <alias> [-- <ssh_command>]
```

`alias` (required): application and environment in the format `app-name.env`; `ssh_command` (optional): command to run via SSH; opens a shell in the site directory when omitted.

Exit codes: 0 success, 1 failure, or the remote command's own exit code.

The shell opens in the environment's site directory: the repository checkout under `docroot/`, the `acquia-files` symlink into the environment's network filesystem, and two symlinks named after the environment that point back at the same directory. Most of it is read-only to the SSH user, which is why file changes go through [`push:files`](#pushfiles) rather than an interactive session.

Example (captured 2026-08-03, identifiers redacted):

```text
$ acli remote:ssh myapp.dev -- ls -al
total 580
dr-xr-sr-x.  1 myapp.dev myapp   4096 Aug  3 10:29 .
drwxrwxrwx.  4 root      root    4096 Aug  3 10:29 ..
-r--r--r--.  1 myapp.dev myapp     53 Aug  3 10:28 .acquia-cli.yml
lrwxrwxrwx.  1 root      myapp     22 Aug  3 10:29 acquia-files -> /mnt/gfs/myappdev
-r--r--r--.  1 myapp.dev myapp   4404 Aug  3 10:28 composer.json
-r--r--r--.  1 myapp.dev myapp 489333 Aug  3 10:28 composer.lock
dr-xr-sr-x.  3 myapp.dev myapp   4096 Aug  3 10:28 config
dr-xr-s---.  1 myapp.dev myapp   4096 Aug  3 10:29 docroot
lrwxrwxrwx.  1 root      myapp     13 Aug  3 10:29 myapp.dev -> /var/www/html
lrwxrwxrwx.  1 root      myapp     13 Aug  3 10:29 myappdev -> /var/www/html
dr-xr-sr-x.  3 myapp.dev myapp   4096 Aug  3 10:28 files-private
-r--r--r--.  1 myapp.dev myapp   1726 Aug  3 10:28 .gitignore
-r--r--r--.  1 myapp.dev myapp  18092 Aug  3 10:28 LICENSE
-r--r--r--.  1 myapp.dev myapp    835 Aug  3 10:28 phpcs.xml.dist
-r--r--r--.  1 myapp.dev myapp    159 Aug  3 10:28 phpstan.neon.dist
-r--r--r--.  1 myapp.dev myapp    658 Aug  3 10:28 phpunit.xml.dist
-r--r--r--.  1 myapp.dev myapp   2949 Aug  3 10:28 README.md
dr-xr-sr-x.  2 myapp.dev myapp   4096 Aug  3 10:28 recipes
-r--r--r--.  1 myapp.dev myapp     56 Aug  3 10:28 salt.txt
-r--r--r--.  1 myapp.dev myapp    460 Aug  3 10:28 SECURITY.md
dr-xr-sr-x.  3 myapp.dev myapp   4096 Aug  3 10:28 tests
dr-xr-sr-x. 39 myapp.dev myapp   4096 Aug  3 10:28 vendor
```

Used in: [Everyday workflows](/cloud-platform/cli/everyday-workflows/#run-drush-remotely-or-open-a-shell).

## SSH keys

The `ssh-key` namespace manages the keys that authorize SSH access to your environments.

| Command | What it does |
| --- | --- |
| `ssh-key:create` | Create an SSH key on your local machine |
| `ssh-key:delete` | Delete an SSH key |
| `ssh-key:info` | Print information about an SSH key |
| `ssh-key:list` | List your local and Cloud Platform SSH keys, matched by fingerprint |
| `ssh-key:upload` | Upload a local public SSH key to the Cloud Platform |

### ssh-key:create-upload

Create an SSH key on your local machine and upload it to the Cloud Platform. Prompts for anything omitted.

```bash
acli ssh-key:create-upload [options]
```

| Flag | Type | Default | Description |
| --- | --- | --- | --- |
| `--filename` | string | — | The filename of the SSH key |
| `--password` | string | — | The password for the SSH key |
| `--label` | string | — | The SSH key label to be used with the Cloud Platform |
| `--no-wait` | boolean | `false` | Don't wait for the SSH key to be uploaded to the Cloud Platform |

Uploading is instant; installing the key across the application's servers is not. Unless `--no-wait` is passed, the command polls three groups of hosts (git, non-production, production) by trying to connect, and returns when all three answer. The warning quotes an hour as the worst case; the run below finished in under two minutes. The key is added to the local SSH agent along the way, so no `ssh-add` follows.

Example (captured 2026-08-03, identifiers redacted):

```text
$ acli ssh-key:create-upload --filename=id_rsa_acli --password=<password> --label=laptop

 ! [NOTE] It may take an hour or more before the SSH key is installed on all of your application's servers. Create a
 !        Support ticket for further assistance.

 Would you like to wait until your key is installed on all of your application's servers? (yes/no) [yes]:
    ✔ Waiting for the key to become available in Cloud Platform git environments
    ✔ Waiting for the key to become available in Cloud Platform nonprod environments
    ✔ Waiting for the key to become available in Cloud Platform prod environments

Your SSH key is ready for use!

 [OK] Uploaded id_rsa_acli to the Cloud Platform with label laptop
```

While the polling runs, the connection attempts that have not yet succeeded print `Permission denied (publickey)` for each host. Those lines are the wait working, not a failure.

Used in: [Everyday workflows](/cloud-platform/cli/everyday-workflows/#run-drush-remotely-or-open-a-shell).

## Cloud IDEs

The `ide` namespace manages [Cloud IDEs](/start-here/glossary/#cloud-ide). Commands marked **IDE-only** exist only when run inside a Cloud IDE: hidden from `acli list` outside an IDE in 4.0.0, but still invocable and documented by `--help`. Adding a Cloud IDE to a subscription, creating one, and its resource limits are on [Acquia's Cloud IDE documentation](https://docs.acquia.com/acquia-cloud-platform/add-ons/cloud-ide/overview).

| Command | What it does |
| --- | --- |
| `ide:create` | Create a Cloud IDE |
| `ide:delete` | Delete a Cloud IDE |
| `ide:info` | Print information about a Cloud IDE |
| `ide:list:app` (alias `ide:list`) | List the Cloud IDEs belonging to an application |
| `ide:list:mine` | List the Cloud IDEs belonging to you |
| `ide:open` | Open a Cloud IDE in your browser |
| `ide:php-version` | Change the PHP version in the current IDE (**IDE-only**) |
| `ide:service-restart` | Restart `php`, `apache`, or `mysql` (**IDE-only**) |
| `ide:service-start` | Start `php`, `apache`, or `mysql` (**IDE-only**) |
| `ide:service-stop` | Stop `php`, `apache`, or `mysql` (**IDE-only**) |
| `ide:share` | Get the share URL for a Cloud IDE (**IDE-only**) |
| `ide:wizard:ssh-key:create-upload` (alias `ide:wizard`) | Wizard for first-time setup tasks within an IDE (**IDE-only**) |
| `ide:wizard:ssh-key:delete` | Wizard to delete the IDE's SSH key from Cloud (**IDE-only**) |
| `ide:xdebug-toggle` (alias `xdebug`) | Toggle Xdebug on or off in the current IDE (**IDE-only**) |

## Code Studio

The `codestudio` namespace configures [Code Studio](/start-here/glossary/#code-studio) projects.

| Command | What it does |
| --- | --- |
| `codestudio:php-version` | Change the PHP version in Code Studio |

### codestudio:wizard

Create and/or configure a new Code Studio project for a given Cloud Platform application. Prompts for anything omitted. Alias: `cs:wizard`.

```bash
acli codestudio:wizard [<applicationUuid>] [<codebaseId>] [options]
```

`applicationUuid` (optional); `codebaseId` (optional): the Cloud Platform codebase ID.

| Flag | Type | Default | Description |
| --- | --- | --- | --- |
| `--key` | string | — | The Cloud Platform API token that Code Studio will use |
| `--secret` | string | — | The Cloud Platform API secret that Code Studio will use |
| `--gitlab-token` | string | — | The GitLab personal access token used to communicate with the GitLab instance |
| `--gitlab-project-id` | integer | — | The project ID of the GitLab project to configure |
| `--gitlab-host-name` | string | — | The GitLab hostname |

Prerequisite: the [GitLab CLI](https://gitlab.com/gitlab-org/cli#installation) (`glab`) must be on your `PATH`, because the wizard reads the GitLab host and token out of `glab`'s own configuration. Each lookup has an opt-out (`--gitlab-host-name` for the host, `--gitlab-token` for the token), so passing both is what lets the command run on a machine without `glab`. Passing neither stops the run at the host lookup, before the Cloud Platform is contacted at all.

Example (captured 2026-08-03, on a machine without `glab`):

```text
$ acli cs:wizard

In CodeStudioCommandTrait.php line 79:

  Install glab to continue: https://gitlab.com/gitlab-org/cli#installation

codestudio:wizard [--key KEY] [--secret SECRET] [--gitlab-token GITLAB-TOKEN] [--gitlab-project-id GITLAB-PROJECT-ID] [--gitlab-host-name GITLAB-HOST-NAME] [--]
 [<applicationUuid> [<codebaseId>]]

 [help] You can find Acquia CLI documentation at https://docs.acquia.com/acquia-cli/

        You can submit a support ticket at https://support-acquia.force.com/s/contactsupport
        Re-run the command with the -vvv flag and include the full command output in your support ticket.
```

Used in: [CI/CD section](/cloud-platform/ci-cd/), [Which CLI do I use?](/cloud-platform/cli/#which-cli-do-i-use)

### codestudio:pipelines-migrate

Migrate an `.acquia-pipeline.yml` file to a `.gitlab-ci.yml` file for a given Acquia Cloud application. **IDE-only** (hidden outside Cloud IDEs; excluded from the official generated command docs). Alias: `cs:pipelines-migrate`.

```bash
acli codestudio:pipelines-migrate [<applicationUuid>] [options]
```

| Flag | Type | Default | Description |
| --- | --- | --- | --- |
| `--key` | string | — | The Cloud Platform API token that Code Studio will use |
| `--secret` | string | — | The Cloud Platform API secret that Code Studio will use |
| `--gitlab-token` | string | — | The GitLab personal access token used to communicate with the GitLab instance |
| `--gitlab-project-id` | integer | — | The project ID of the GitLab project to configure |

It shares [`codestudio:wizard`](#codestudiowizard)'s `glab` prerequisite but carries no `--gitlab-host-name` flag to opt out of the host lookup, so `glab` is required here even when `--gitlab-token` is supplied.

Example (captured 2026-08-03, on a machine without `glab`):

```text
$ acli cs:pipelines-migrate

In CodeStudioCommandTrait.php line 79:

  Install glab to continue: https://gitlab.com/gitlab-org/cli#installation

codestudio:pipelines-migrate [--key KEY] [--secret SECRET] [--gitlab-token GITLAB-TOKEN] [--gitlab-project-id GITLAB-PROJECT-ID] [--] [<applicationUuid>]

 [help] You can find Acquia CLI documentation at https://docs.acquia.com/acquia-cli/

        You can submit a support ticket at https://support-acquia.force.com/s/contactsupport
        Re-run the command with the -vvv flag and include the full command output in your support ticket.
```

Used in: [Which CLI do I use?](/cloud-platform/cli/#which-cli-do-i-use)

## Site Factory

The `acsf` namespace works like [the Cloud Platform API namespace](#the-cloud-platform-api): 107 generated commands (at 4.0.0, unchanged since 2.61.3) matching the bundled Site Factory API spec, hidden from `acli list`, each named `acsf:<resource>:<action>` and documented by its own `--help`. Authenticate first with [`auth:acsf-login`](#authenticate).

| Command | What it does |
| --- | --- |
| `acsf:list` (alias `acsf`) | List all Site Factory commands |
| `acsf:<resource>` | Each resource is also its own lister command: `acli acsf:sites` lists every sites command |

## The Cloud Platform API

`acli api:*` commands match the Cloud Platform API, endpoint for endpoint, following the API specifications bundled with each release: `assets/acquia-spec.json` for the v2 API, and, new in 4.0.0, `assets/acquia-v3-spec.json` for the v3 API, whose commands sit under `api:v3:*`. Each API endpoint has a command named `api:<resource>:<action>` (v3: `api:v3:<resource>:<action>`); its **arguments** are the endpoint's path parameters and its **flags** are the endpoint's request parameters. Output is always the endpoint's machine-readable JSON response: pipe it to `jq` to filter (see [orientation](/cloud-platform/cli/everyday-workflows/#know-what-youre-pointed-at)).

These 477 commands (at 4.0.0: 345 matching the v2 API, unchanged from 3.0.1, plus 132 matching v3) span every Cloud Platform API resource, from accounts and applications to environments, codebases, and subscriptions. They are hidden from `acli list`: discover them with `acli api:list` (after authenticating with [`auth:login`](#authlogin)) and inspect any one of them with `--help`. For per-command documentation, the tool itself is the source of truth (`acli api:<command> --help`), alongside the per-command pages published from the same source under [Acquia CLI commands on docs.acquia.com](https://docs.acquia.com/acquia-cloud-platform/add-ons/acquia-cli/commands).

| Command | What it does |
| --- | --- |
| `api:list` (alias `api`) | List all API commands |
| `api:<resource>` | Each resource is also its own lister command: `acli api:environments` lists every environments command |
| `list api:v3` | List every `api:v3:*` command. `acli api:list` shows the v3 surface as one row, `api:v3:v3`, and that command only prints the v3 namespaces, so `acli list api:v3` (or `acli list api:v3:<resource>`) is the listing that works |

Most `api:v3:*` commands carry a stability tag at the end of their description (`[development]`, for example); running one whose stability is not production also prints a warning that the command may change without notice.

A generated command with real output:

```bash
acli api:applications:environment-list myapp | jq '.[].name'
```

```text
"dev"
"prod"
"test"
```

Applications with Remote Administration or AMA entitlements list additional environments (`ra`, `ama`) here.

The unfiltered response is the Cloud Platform API's JSON, field names unchanged; the [glossary](/start-here/glossary/) uses those same names.

### Waiting for a task to finish

Many platform operations are asynchronous: the endpoint accepts the request, returns `202` with a linked notification, and the work happens in the background. Every generated command whose endpoint can answer `202` carries one extra flag, 151 commands in 4.0.0 (the same 93 v2 commands as in 3.0.1, plus 58 under `api:v3:*`):

| Flag | Type | Default | Description |
| --- | --- | --- | --- |
| `--task-wait` | boolean | `false` | Wait for this task to complete |

Without it, the command prints the JSON response and exits as soon as the request is accepted. With it, the command reads the notification out of that response, blocks until the task settles, and exits **0** only if the task succeeded (**1** if it failed), which is the same contract as [`app:task-wait`](#apptask-wait). Reach for `--task-wait` when the operation is a single step in a script, and for `app:task-wait` when you need to keep the JSON response or wait on a task started elsewhere.

`acli api:<command> --help` tells you whether a given command has the flag; the read-only ones (`api:applications:list`, `api:environments:find`) don't.

Used in: [CLI quickstart](/cloud-platform/cli/quickstart/) (`api:applications:list`), [everyday workflows](/cloud-platform/cli/everyday-workflows/#know-what-youre-pointed-at) (`api:applications:environment-list`), its [temporary environments](/cloud-platform/cli/everyday-workflows/#temporary-environments) job (`api:environments:database-backup-create`), [stale content](/cloud-platform/caching/stale-content/) (`api:environments:clear-caches` with `--task-wait`), the [code-workflow quickstart](/cloud-platform/code-workflow/quickstart/) (`api:environments:find` for the repository URL), the [code-workflow guide's rollback runbook](/cloud-platform/code-workflow/guide/#roll-back-a-release) (`api:environments:code-switch`, `api:environments:database-backup-list`, `api:environments:database-backup-restore`), [scheduled jobs](/cloud-platform/configure/cron/) (`api:environments:cron-create`, `api:environments:cron-job-list`), [per-environment settings](/cloud-platform/configure/settings/) (`api:environments:update`, `api:environments:variable-create`), and [what the platform logs](/cloud-platform/observability/logs/) (`api:environments:log-list`, `api:environments:log-download`).

## Maintain acli itself

The top-level commands and the `self` namespace: help, discovery, updates, caches, and telemetry.

| Command | What it does |
| --- | --- |
| `docs` | Open Acquia product documentation in the browser |
| `help` | Display help for a command (same as `<command> --help`) |
| `list` (alias `self:list`) | List commands, optionally for one namespace |
| `completion` | Dump the shell completion script for your shell |
| `self:clear-caches` (aliases `cc`, `cr`) | Clear local Acquia CLI caches |
| `self:info` | Print version, build date, config paths, and telemetry status |
| `self:telemetry:disable` (alias `telemetry:disable`) | Disable anonymous sharing of usage and performance data |
| `self:telemetry:enable` (alias `telemetry:enable`) | Enable anonymous sharing of usage and performance data |
| `self:telemetry:toggle` (alias `telemetry`) | Toggle anonymous sharing of usage and performance data |

If `acli` itself fails to boot because of a stale kernel cache, the pseudo-command `acli clear-kernel-cache` (`ckc`) clears it before the application starts. Telemetry can also be disabled with the `ACLI_NO_TELEMETRY=true` [environment variable](#environment-variables).

### self-update

Update `acli` to the latest release. The canonical name is `self:update`; `self-update` and `update` are its aliases.

```bash
acli self-update [--stable] [--preview] [--compatible] [<version_constraint>]
```

`version_constraint` (optional): a version constraint limiting which release is installed, for pinning an update to a range instead of taking whatever is newest.

| Flag | Type | Default | Description |
| --- | --- | --- | --- |
| `--stable` | boolean | `false` | Use stable releases. This is already what happens when no flag is passed |
| `--preview` | boolean | `false` | Preview unstable releases (alpha, beta, and so on) |
| `--compatible` | boolean | `false` | Stay on the current major version |

`--compatible` is the flag to reach for when a major release lands and you are not ready for it: it takes the newest release that shares your current major version. `version_constraint` does the same job more precisely.

When the installed binary is already the newest matching release, the command says so and exits 0:

```text
$ acli self-update
No update available
```

Otherwise the update writes a temp file next to the `acli` binary, so it fails when that directory isn't writable by your user:

```text
$ acli self-update
acli update failed: the "/usr/local/bin" directory used to download the temp file could not be written
```

Re-run with `sudo acli self-update`, or update through whatever originally installed `acli`.

Used in: [Everyday workflows](/cloud-platform/cli/everyday-workflows/#when-something-goes-wrong) (version mismatch fix).

## Configuration

### Credentials file

`acli auth:login` stores Cloud Platform API credentials in `cloud_api.conf` inside the `acli` config directory:

- `~/.acquia/` if that directory exists (the default on machines that have run `acli` or other Acquia tooling before),
- otherwise `$XDG_CONFIG_HOME/acquia/`,
- otherwise `~/.config/acquia/`.

Multiple credential sets can be stored; one is active at a time, switched with [`auth:login`](#authlogin).

### Project link file

[`app:link`](#applink) writes the linked [application](/start-here/glossary/#application-cloud-platform) UUID to `.acquia-cli.yml` (key: `cloud_app_uuid`) in the project root. Commands run inside that directory use the linked application when no `applicationUuid` argument is given.

### Environment variables

| Variable | Effect |
| --- | --- |
| `ACLI_ACCESS_TOKEN` | Cloud Platform API access token. Highest-priority credential source |
| `ACLI_ACCESS_TOKEN_EXPIRY` | Expiry timestamp for `ACLI_ACCESS_TOKEN`; required alongside it |
| `ACLI_ACCESS_TOKEN_FILE` / `ACLI_ACCESS_TOKEN_EXPIRY_FILE` | Read the token/expiry from a file instead of the variable |
| `ACLI_KEY` / `ACLI_SECRET` | Cloud Platform API key and secret. Second-priority credential source, after the access token and before `cloud_api.conf` |
| `ACLI_DB_HOST`, `ACLI_DB_NAME`, `ACLI_DB_USER`, `ACLI_DB_PASSWORD` | Local database connection used by `pull:*`/`push:*` database commands. Preset by recommended local stacks such as Lando |
| `ACLI_PUSH_ARTIFACT_DESTINATION_GIT_URLS` | Default destination git URLs for [`push:artifact`](#pushartifact) |
| `ACLI_PUSH_ARTIFACT_DESTINATION_GIT_BRANCH` | Default destination branch for [`push:artifact`](#pushartifact) |
| `ACLI_PUSH_ARTIFACT_DESTINATION_GIT_TAG` / `ACLI_PUSH_ARTIFACT_SOURCE_GIT_TAG` | Default destination/source tags for [`push:artifact`](#pushartifact) |
| `ACLI_PUSH_ARTIFACT_COMMIT_MSG` | Commit message used for the artifact commit |
| `ACLI_NO_TELEMETRY` | Set to `true` to disable telemetry |
| `ACLI_CLOUD_API_BASE_URI` / `ACLI_CLOUD_API_V3_BASE_URI` / `ACLI_CLOUD_API_ACCOUNTS_URI` | Override the Cloud Platform API v2, API v3 (default `https://api.acquia.com/v3`; acli 4.0.0+), and accounts endpoints |
| `ACLI_HOME` | Override the config/data directory |
| `AH_ORGANIZATION_UUID` | Workaround for federated-authentication failures; see the note below |

Credential precedence, highest first: `ACLI_ACCESS_TOKEN` (+ expiry) → `ACLI_KEY`/`ACLI_SECRET` → `cloud_api.conf`. [Non-interactive auth](/cloud-platform/cli/everyday-workflows/#non-interactive-authentication) shows this in use.

Federated authentication: if a command fails with `This resource requires additional authentication`, set `AH_ORGANIZATION_UUID` to your organization UUID (from the URL at `https://cloud.acquia.com/a/organizations/<organization-UUID>`), then re-run `acli auth:login`. Requires acli 2.14.0+.

### Composer hook points

Any command can be wrapped with Composer scripts named `pre-acli-<command>` / `post-acli-<command>`, where `<command>` is the command name with dashes instead of colons (`pre-acli-push-db`, `post-acli-pull-files`). See [hook scripts](/cloud-platform/cli/everyday-workflows/#hook-scripts-around-any-acli-command).

## Used in

- [CLI quickstart](/cloud-platform/cli/quickstart/): install, authenticate, and run a first command.
- [Everyday CLI workflows](/cloud-platform/cli/everyday-workflows/): the task-shaped recipes each command entry backs.
- [Which CLI do I use?](/cloud-platform/cli/#which-cli-do-i-use): where `acli` stops and `pipelines`, `drush`, `gh`, and `glab` start.
- [Code workflow guide](/cloud-platform/code-workflow/guide/): deploys, database copies, and backup restores.
- [Set up a codebase](/cloud-platform/code-workflow/set-up-a-codebase/): `app:link` and the Acquia git remote.
- [Migrate an existing codebase](/cloud-platform/code-workflow/migrate-to-cloud-platform/): alias downloads and the `ACLI_DB_*` variables.
- [Scheduled jobs](/cloud-platform/configure/cron/): the generated `api:*` commands and `--task-wait`.
