Envio Cloud CLI
The envio-cloud CLI is a command-line tool for interacting with Envio Cloud. It enables you to deploy, manage, and monitor your blockchain indexers directly from the terminal - making it particularly useful for CI/CD pipelines, scripting, and agentic workflows.
For feature requests, please reach out to us on Discord.
Installation
npm install -g envio-cloud
Or run directly without installation:
npx envio-cloud <command>
Shell Completion
The envio-cloud CLI ships with shell completion scripts for bash, zsh, fish, and powershell. Completion includes dynamic suggestions for indexer names and commit hashes, so you can tab-complete them directly from the terminal.
Run the one-liner for your shell to install completions:
| Shell | One-liner |
|---|---|
zsh | echo 'source <(envio-cloud completion zsh)' >> ~/.zshrc |
bash | envio-cloud completion bash > ~/.local/share/bash-completion/completions/envio-cloud |
fish | envio-cloud completion fish > ~/.config/fish/completions/envio-cloud.fish |
powershell | envio-cloud completion powershell >> $PROFILE |
Restart your shell (or source your profile) for the completions to take effect. Run envio-cloud completion --help for further options.
Authentication
You sign in with GitHub. Your GitHub account must already have an Envio account, so sign in at envio.dev once before you use the CLI.
Log In
envio-cloud login
envio-cloud login uses the first credential it finds:
- The
--tokenflag - The
ENVIO_GITHUB_TOKENenvironment variable - The token of a signed-in GitHub CLI (
gh auth token) - Browser-based authentication via envio.dev
The session lasts 30 days. Credentials are stored at ~/.envio-cloud/auth.json. When the session expires, commands fail with session expired, and plain envio-cloud login still reports you as logged in. Run envio-cloud logout and then envio-cloud login, or log in again with --token, ENVIO_GITHUB_TOKEN or a signed-in GitHub CLI.
Token-Based Login (CI/CD)
envio-cloud login --token ghp_YOUR_TOKEN
Or using an environment variable:
export ENVIO_GITHUB_TOKEN=ghp_YOUR_TOKEN
envio-cloud login
Required GitHub token scopes: read:org, read:user, user:email.
envio-cloud login and envio-cloud token exit with code 0 even when the token is rejected or you are logged out. To check the session from a script, run a command that needs it, such as envio-cloud indexer list -o json, which exits with 1 when you are not logged in.
Session Management
envio-cloud token # Check current session
envio-cloud logout # Remove credentials
Context Management
Like kubectl namespaces, envio-cloud lets you store default values for organisation and indexer so you don't have to pass them on every command. Flags (--org, --indexer) always override stored context.
# Set defaults
envio-cloud config set-org myorg
envio-cloud config set-indexer myindexer
# View current context
envio-cloud config get-context
# Commands now use defaults automatically
envio-cloud deployment status abc1234 # org and indexer from context
envio-cloud indexer settings get # both from context
# Flags override context
envio-cloud deployment status abc1234 --org other-org
# Clear stored context
envio-cloud config clear
Context is stored at ~/.envio-cloud/context.json. Resolution priority:
- Explicit positional arguments
--org/--indexerflags- Stored context
- GitHub login (organisation only)
| Command | Description |
|---|---|
config set-org <org> | Set default organisation |
config set-indexer <indexer> | Set default indexer |
config get-context | Show current defaults and where they come from |
config clear | Remove all stored defaults |
Deploy From an Agent or CI
Envio Cloud builds from GitHub, so a script or AI agent deploys by pushing a commit and then watching it with the CLI. Two steps need a person in a browser, once: sign in at envio.dev with GitHub, and install the Envio Deployments GitHub App on the repository (see Deploying Your Indexer). After that, the whole loop runs from the terminal:
envio-cloud login # --token, ENVIO_GITHUB_TOKEN, or a signed-in gh CLI
envio-cloud repos -o json # the repository must be listed here
envio-cloud indexer add --name my-indexer --repo my-repo --branch main --yes
envio-cloud indexer get my-indexer -o json | jq -e .data # add can exit 0 on failure, so check
git push origin main # with auto-deploy on, a push starts a deployment
COMMIT=$(git rev-parse HEAD | cut -c1-7)
envio-cloud indexer commits my-indexer -o json # status of the pushed commit
envio-cloud deployment logs my-indexer $COMMIT --build # build logs
envio-cloud deployment status my-indexer $COMMIT --watch-till-synced # waits until synced
envio-cloud deployment endpoint my-indexer $COMMIT # GraphQL URL, once the commit is active
- Find the commit in
indexer commitsand read itsstatus.pendinganddeploymean wait,activemeans it deployed, and any other value explains what to fix. See List Recent Commits. deployment status --watch-till-syncedexits0once every chain is ready. It has no time limit, so wrap it intimeout. See Deployment Status.- Ask for the endpoint after the commit is
active. Before the deployment is scheduled,deployment endpointhas no URL to print and exits with code2. - Pass
--yesto every command that asks for confirmation. See Confirmation Prompts. - Check the exit code before you parse the JSON. See Exit Codes.
Commands
Indexer Commands
List Indexers
Lists indexers across every organisation you are a member of. Use --org to
scope to a single organisation. Requires authentication.
envio-cloud indexer list
envio-cloud indexer list --org myorg
envio-cloud indexer list --limit 10
envio-cloud indexer list -o json
| Flag | Description |
|---|---|
--org | Scope to a single organisation you belong to |
--limit | Limit number of results (default: 1000) |
-o, --output | Output format (json) |
indexer ls is an alias.
Get Indexer Details
envio-cloud indexer get <name> [organisation]
envio-cloud indexer get myindexer myorg -o json
envio-cloud indexer get myindexer --org myorg
Organisation can be omitted if set via context. Requires authentication - you
can only view indexers in organisations you are a member of. The output lists the indexer's deployments, each with its commit hash, tier and GraphQL endpoint. With -o json, an indexer that doesn't exist returns {"ok": true} with no data field.
Add an Indexer
envio-cloud indexer add --name my-indexer --repo my-repo --branch main --yes
envio-cloud indexer add --name my-indexer --repo my-repo --branch main --tier development --yes
envio-cloud indexer add --name my-indexer --repo my-repo --dry-run
The repository must already be connected to your organisation through the Envio Deployments GitHub App. envio-cloud repos lists the connected repositories. The indexer is added to the organisation from --org, then the stored context, then your GitHub login.
indexer add asks for confirmation. Pass --yes in scripts and agent sessions: without an answer it prints "Operation cancelled." and exits with code 0 without adding the indexer. The default branch is envio, so set --branch to the branch you push to.
| Flag | Description | Default |
|---|---|---|
-n, --name | Indexer name (required) | - |
-r, --repo | Repository name (required) | - |
-b, --branch | Deployment branch | envio |
-d, --root-dir | Root directory | ./ |
-c, --config-file | Config file path | config.yaml |
--description | Indexer description | the indexer name |
-t, --tier | Pricing tier (development, production) | development |
-a, --access-type | Access type (public, private) | public |
-e, --env-file | Environment file | - |
--auto-deploy | Enable auto-deploy | true |
--skip-repo-check | Skip the check that the repository is connected | - |
--dry-run | Preview without creating | - |
-y, --yes | Skip confirmation prompts | - |
-o, --output | Print the indexer configuration as JSON before adding it | - |
--env-file prints the variable values in its output. To keep them out of logs, add the indexer without it, then run envio-cloud indexer env import (see Manage Environment Variables), which masks them.
Delete an Indexer
Permanently delete an indexer and all of its deployments. Requires typing the indexer name to confirm.
envio-cloud indexer delete myindexer myorg
envio-cloud indexer delete myindexer --org myorg
envio-cloud indexer delete myindexer myorg --yes # skip confirmation for CI/CD
This action cannot be undone. All deployments, data, and configuration for the indexer will be permanently removed.
View and Modify Settings
# View current settings
envio-cloud indexer settings get myindexer myorg
# Modify settings (only specified flags are changed)
envio-cloud indexer settings set myindexer myorg --branch main
envio-cloud indexer settings set myindexer myorg --auto-deploy=false
envio-cloud indexer settings set myindexer myorg --config-file config.yaml --branch develop
| Flag (set) | Description |
|---|---|
--branch | Git branch for deployments |
--config-file | Path to config file |
--root-dir | Root directory within the repository |
--auto-deploy | Enable or disable auto-deploy on push |
--description | Indexer description |
--access-type | public or private |
List Recent Commits
Show recent commits pushed to the indexer's repository, along with their processing status. Commits with status inactive can be deployed manually with envio-cloud deployment deploy.
envio-cloud indexer commits myindexer myorg
envio-cloud indexer commits myindexer --org myorg --limit 20
envio-cloud indexer commits myindexer myorg -o json
| Flag | Description |
|---|---|
--limit | Maximum number of commits to show (default: 10) |
-o, --output | Output format (json) |
With -o json, each commit has commit_hash, commit_message, branch, created_time, status, envio_version and repository_id. The status is how you find out whether a push deployed, and why not:
| Status | Dashboard label | Meaning |
|---|---|---|
pending | Processing | The commit is still being processed |
deploy | Deploying | A deployment of this commit is starting |
active | Active | The commit has a deployment |
inactive | - | Not deployed, for example because auto-deploy is off or the indexer has reached its plan's deployment or indexing-hour limit. Deploy it with deployment deploy |
deletingDeploymemt | Deleting | The commit's deployment is being deleted. The value is spelled this way |
configFileMissing | Missing config | The config file was not found. Check the root directory and config file settings |
packageJsonMissing | Missing package.json | package.json was not found. Check the root directory setting |
failedToDownload | Failed to download | Envio Cloud could not download the commit from GitHub |
versionNotSupported | Invalid version | The envio version is not supported. See the requirements |
clickhouseConfigMismatch | ClickHouse mismatch | storage.clickhouse in the config doesn't match the indexer's setup |
clickhouseVersionNotSupported | ClickHouse version | ClickHouse needs envio 3.0.2 or newer |
Manage Environment Variables
Environment variables can be managed from the CLI. All keys must be prefixed with ENVIO_. Changes take effect on the next deployment.
# List variables (values masked by default)
envio-cloud indexer env list myindexer myorg
envio-cloud indexer env list myindexer myorg --show-values
# Set one or more variables
envio-cloud indexer env set myindexer myorg ENVIO_API_KEY=abc123 ENVIO_DEBUG=true
# Remove a variable
envio-cloud indexer env delete myindexer myorg ENVIO_DEBUG
# Bulk import from a .env file
envio-cloud indexer env import myindexer myorg --file .env
The .env file format is one KEY=VALUE per line. Lines starting with # are ignored.
env list, env set and env import mask values in their normal output. With -o json, env list and env set print the full values, so keep that output out of shared logs.
View the Security Configuration
Both access controls for an indexer - API key authentication and the IP whitelist - are shown by a single command:
envio-cloud indexer security get myindexer myorg
envio-cloud indexer security get myindexer myorg -o json
API keys are never printed here. Use api-key list --show-tokens to reveal them.
Configure API Key Authentication
Require clients to send an Authorization: Bearer <token> header on every request to your indexer's GraphQL endpoints.
# Turn it on: an initial key is provisioned automatically
envio-cloud indexer security api-key enable myindexer myorg
# Check whether it is on, and which keys exist (never prints tokens)
envio-cloud indexer security api-key status myindexer myorg
# List keys, then reveal the tokens
envio-cloud indexer security api-key list myindexer myorg
envio-cloud indexer security api-key list myindexer myorg --show-tokens
# Turn it off: the endpoints stop requiring a token
envio-cloud indexer security api-key disable myindexer myorg
Tokens are only requested from the API when --show-tokens is passed, so a plain listing never puts a secret on the wire.
Query an endpoint with a key. Read the URL from deployment endpoint rather than hardcoding a host - it differs per deployment:
curl -X POST "$(envio-cloud deployment endpoint myindexer abc1234 myorg)" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ENVIO_API_KEY" \
-d '{"query":"{ __typename }"}'
Rotating Keys
An indexer can hold several named keys at once, which is how you rotate without downtime: add a new key, migrate your clients onto it, then revoke the old one.
envio-cloud indexer security api-key add myindexer myorg production-2026-08
# ...migrate clients to the new key...
envio-cloud indexer security api-key remove myindexer myorg production-2026-07
Key names may contain letters, digits, -, . and _, must start with a letter or digit, and must be 63 characters or fewer.
Removing a key revokes it immediately - any client still using it loses access. A newly added key shows as provisioning for a few seconds before its token is available. The last remaining key cannot be removed; disable API key authentication instead.
API key authentication requires a Production tier plan or above.
Configure IP Whitelisting
Restrict access to your indexer's GraphQL endpoint by IP address. Supports IPv4 addresses and CIDR notation.
# View the current configuration
envio-cloud indexer security get myindexer myorg
# Add IPs to the whitelist
envio-cloud indexer security add-ip myindexer myorg 203.0.113.50
envio-cloud indexer security add-ip myindexer myorg 10.0.0.0/8
# Enable IP whitelisting (make sure to add IPs first)
envio-cloud indexer security enable myindexer myorg
# Disable IP whitelisting
envio-cloud indexer security disable myindexer myorg
# Restrict whitelisting to production deployments only
envio-cloud indexer security set-prod-only myindexer myorg true
# Remove an IP
envio-cloud indexer security remove-ip myindexer myorg 203.0.113.50
Add your IP addresses before enabling whitelisting - otherwise you may lock yourself out. The CLI will warn you if you try to enable whitelisting with no IPs configured.
Deployment Commands
All deployment commands accept arguments as <indexer> <commit> [organisation]. Organisation and indexer can be omitted if set via envio-cloud config. All of them require authentication, and you can only see deployments in organisations you are a member of.
The commit is the first 7 characters of the commit hash, as envio-cloud indexer commits shows it. In a script, use git rev-parse HEAD | cut -c1-7.
Deployment Status
envio-cloud deployment status <indexer> <commit> [organisation]
envio-cloud deployment status myindexer abc1234 myorg --watch-till-synced
envio-cloud deployment status myindexer abc1234 myorg -o json
Shows how far your deployment has synced on each chain: the chain's latest block, the last block your indexer has processed, the number of events, and whether the chain is ready, plus an overall percentage. A chain is ready once your indexer has caught up with it, or has reached its end block if you set one. deployment metrics and deployment m do the same thing.
| Flag | Description |
|---|---|
--watch-till-synced | Keep checking until every chain is ready, then exit with code 0 |
-o, --output | Output format (json) |
--watch-till-synced waits while the deployment starts up and stops on errors that waiting can't fix. It has no time limit, so in a script wrap it in timeout. With -o json the command prints the current status once. data has one entry per chain:
{
"ok": true,
"data": [
{
"chain_id": 1,
"block_height": 23000000,
"latest_processed_block": 22999990,
"num_events_processed": 120000,
"is_ready": true
}
]
}
The example shows the fields you'll usually need; each entry has a few more. An empty data list means the deployment hasn't started syncing yet.
If your indexer uses an older version of envio, the command fails and asks you to upgrade envio to the latest version.
Deployment Info
envio-cloud deployment info <indexer> <commit> [organisation]
envio-cloud deployment info myindexer abc1234 myorg -o json
Shows whether caching is enabled and whether the database is directly exposed. With -o json, data is {"cacheEnabled": <bool>, "dbExposed": "<string>"}.
Get Query Endpoint
Returns the GraphQL query endpoint URL for a deployment. The URL is read from the deployment record, so it always matches where the deployment runs. Output is a bare URL, so it composes cleanly with shell scripting. A deployment that hasn't been scheduled yet has no endpoint, and the command fails with exit code 2.
envio-cloud deployment endpoint <indexer> <commit> [organisation]
envio-cloud deployment endpoint myindexer abc1234 myorg
envio-cloud deployment endpoint myindexer abc1234 myorg -o json
With -o json, data has query_endpoint, indexer_id, commit_hash and organisation_id.
Use the URL directly in a curl query. If the indexer has API key authentication on, add the Authorization header shown in Configure API Key Authentication:
curl "$(envio-cloud deployment endpoint myindexer abc1234 myorg)" \
-H "Content-Type: application/json" \
-d '{"query": "{ _meta { chainId isReady } }"}'
| Flag | Description |
|---|---|
-o, --output | Output format (json) |
The ep alias is also available: envio-cloud deployment ep <indexer> <commit>.
Manually Deploy a Commit
Trigger a deployment of a specific commit - the CLI equivalent of the Deploy button in the Envio Cloud dashboard. Combined with disabling auto-deploy, this gives you full manual control over what gets deployed and when.
# Turn off automatic deploys on push
envio-cloud indexer settings set myindexer myorg --auto-deploy=false
# See recent commits and their statuses ('inactive' commits can be deployed)
envio-cloud indexer commits myindexer myorg
# Deploy a specific commit
envio-cloud deployment deploy myindexer abc1234 myorg
Only commits with status inactive can be deployed. If a commit cannot be deployed (already active, still processing, missing config file, unsupported Envio version, etc.), the CLI explains why and exits with code 1. See the commit statuses. Requires confirmation (y/N); skip with --yes for CI/CD.
Promote a Deployment
Promote a deployment to the production endpoint. This is also how you roll back: promote an older deployment. Requires confirmation (y/N).
envio-cloud deployment promote <indexer> <commit> [organisation]
envio-cloud deployment promote myindexer abc1234 myorg --yes
Delete a Deployment
Permanently delete a deployment. Requires typing the indexer name to confirm.
envio-cloud deployment delete <indexer> <commit> [organisation]
envio-cloud deployment delete myindexer abc1234 myorg --yes
This action cannot be undone. The deployment and its data will be permanently removed.
Restart a Deployment
Restart a running deployment. There is a 10-minute cooldown between restarts.
envio-cloud deployment restart <indexer> <commit> [organisation]
envio-cloud deployment restart myindexer abc1234 myorg --yes
Deployment Logs
Show build or runtime logs for a deployment.
envio-cloud deployment logs <indexer> <commit> [organisation]
envio-cloud deployment logs myindexer abc1234 myorg --build
envio-cloud deployment logs myindexer abc1234 myorg --level error,warn
envio-cloud deployment logs myindexer abc1234 myorg --since 24h
envio-cloud deployment logs myindexer abc1234 myorg --follow
envio-cloud deployment logs myindexer abc1234 myorg -o json
| Flag | Description |
|---|---|
--build | Show build logs instead of runtime logs |
--level | Filter by log level, comma-separated: trace, debug, info, warn, error |
--limit | Max number of log lines (default and maximum: 100) |
--since | How far back to look, such as 30m, 1h or 7d. Runtime logs default to the last 30 minutes, up to 7 days. Build logs have no window unless you pass one, up to 30 days |
--follow | Poll for new logs every 10 seconds |
-o, --output | Output format (json): data is a list of log entries, oldest first |
--follow only works without -o json. If deployment logs finds no deployment for a commit, read the commit's status with indexer commits. A failed check, such as configFileMissing, shows there.
Manage Deployment Tags
Organize deployments with custom key/value tags (see Production Features for how tags appear in the dashboard).
# List tags on a deployment
envio-cloud deployment tags list <indexer> <commit> [organisation]
# Set one or more tags (existing keys are overwritten, other tags preserved)
envio-cloud deployment tags set <indexer> <commit> [organisation] KEY=VALUE [KEY=VALUE ...]
envio-cloud deployment tags set myindexer abc1234 myorg env=staging team=backend
# Remove a tag by key
envio-cloud deployment tags remove <indexer> <commit> [organisation] KEY
envio-cloud deployment tags remove myindexer abc1234 myorg env
Tag rules:
- Deployments support up to 5 custom tags
- Keys and values are limited to 20 characters; values are automatically lowercased
- Keys starting with
envioare reserved for system tags and are hidden from output - The special
nametag is displayed directly on the deployment list in the dashboard
Repository Commands
List Repositories
envio-cloud repos
envio-cloud repos -o json
Lists the repositories connected to your organisation and the indexers in each. Requires authentication.
Confirmation Prompts
Dangerous commands require confirmation before executing:
| Command | Confirmation type |
|---|---|
indexer add | y/N prompt |
indexer delete | Type the indexer name |
deployment delete | Type the indexer name |
deployment deploy | y/N prompt |
deployment promote | y/N prompt |
deployment restart | y/N prompt |
indexer security api-key enable, disable, remove | y/N prompt |
indexer security enable | y/N prompt, only when no IPs are whitelisted |
Skip a prompt with the --yes / -y flag for CI/CD usage. Two prompts have no --yes: security enable asks only when the whitelist is empty, so add IPs with security add-ip first, and indexer add asks when it can't check the repository, which --skip-repo-check skips. Without an answer, a prompt cancels the command. indexer add then exits with code 0, the others with code 1.
Global Flags
| Flag | Description |
|---|---|
--org | Override default organisation |
--indexer | Override default indexer |
-q, --quiet | Suppress informational messages |
--config | Specify config file path (default: $HOME/.envio-cloud.yaml) |
-h, --help | Display command help |
-v, --version | Show CLI version (envio-cloud --version) |
-o, --output is set per command, not globally. See JSON Output.
JSON Output
Most commands support JSON output via the -o json flag, making the CLI easy to integrate into scripts and automation pipelines. Informational messages go to stderr, so stdout holds only the JSON.
Success response:
{"ok": true, "data": [ ... ]}
Error response:
{"ok": false, "error": "error message"}
Exceptions:
login,logout,token,config,completion, the IP whitelist commands (security enable,disable,add-ip,remove-ip,set-prod-only) andsecurity api-key enable,disableandremovehave no-oflag.repos -o jsonprints a bare list of repositories, with nook/dataenvelope, and a plain-text message when there are none.indexer add -o jsonprints the configuration it is about to send, with no envelope, and then adds the indexer. Add--dry-runto stop there.- Some argument errors, such as deploying a commit that isn't
inactive, print only to stderr. Check the exit code first, then parse stdout.
Example with jq:
# Get event count for a deployment
envio-cloud deployment status myindexer abc1234 myorg -o json | jq '.data[].num_events_processed'
# List all indexer IDs in an org
envio-cloud indexer list --org myorg -o json | jq -r '.data[].indexer_id'
Exit Codes
| Code | Meaning |
|---|---|
0 | Success |
1 | User error (invalid arguments, authentication required, a cancelled prompt) |
2 | API or server error |
login, token and indexer add print some errors but still exit with code 0. After indexer add, confirm the indexer exists with envio-cloud indexer get <name> -o json.
Related Documentation
- Envio Cloud Overview - Introduction to Envio Cloud
- Deploying Your Indexer - Step-by-step deployment guide via the dashboard
- Production Features - Tags, IP whitelisting, caching, and alerts
- Monitoring - Dashboard monitoring and alerts
- Envio CLI - Local development CLI reference
- npm package - Latest version and changelog