The dply-edge CLI drives the dply HTTP API from your terminal. Link a repository to an app, then deploy, roll back, promote previews, manage domains and environment variables, tail request logs, query D1 databases, and route notifications without opening the dashboard. Use it on your own machine and in CI.
The CLI calls the same endpoints as the HTTP API, so every command is limited by the abilities on your token and by your role in the organization.
Install
The CLI is served by dply itself, not by the npm registry. You need Node.js 18 or later and npm. The installer downloads the package from https://edge.dply.io/cli/dply-cli.tgz and installs it globally with npm install -g.
curl -fsSL https://edge.dply.io/cli/install.sh | bash -s -- --login
--login runs dply-edge login when the install finishes. The installer accepts these options:
| Option | Description |
|---|---|
--login |
Run dply-edge login after installing. |
--no-login |
Skip login (the default). |
--base-url <url> |
Download from, and sign in to, a different dply host. |
--method <method> |
tarball (default), npm, or auto. |
-h, --help |
Show help. |
Important
The installer rejects any option it does not recognize and exits with code 2. Don't pass dply-edge flags such as --no-shell to install.sh.
Check which version dply is serving, and which version you have:
curl -fsSL https://edge.dply.io/cli/version.json
dply-edge --version
Update
New commands ship with the platform, so updating means installing whatever build dply is serving right now:
dply-edge update # install the build dply is serving
dply-edge update --check # report only; exits 1 when your build differs
dply-edge update --json # {installed, serving, up_to_date, base_url}
dply-edge update --force # reinstall even when up to date
The check compares your build with the served build for equality, not "newer than". If the served build is rolled back, dply-edge update rolls your CLI back too. If the global install fails with a permission error, re-run with sudo or use the install script again.
Sign in
dply-edge login uses a device flow, the same pattern as the GitHub and Stripe CLIs. You approve the terminal in your browser. You never paste a password or token into the terminal.
dply-edge login
- The CLI asks dply for a code pair and prints a URL and an eight-character code in the form
ABCD-EFGH. It tries to open the URL in your browser. - In the browser, sign in if you need to. Confirm that the code matches the one in your terminal.
- Choose the organization the CLI should act in, then select the scopes (abilities) to grant.
- Choose Approve. The terminal saves the token and opens the interactive shell.
The code expires after 15 minutes. If you deny the request, or the code expires, the CLI exits with code 2 and you run dply-edge login again. Press Ctrl+C to cancel.
| Flag | Description |
|---|---|
--base-url <url>, -b |
The dply host to sign in to. Defaults to https://edge.dply.io. |
--token <token>, -t |
Skip the browser and save an existing API token (for CI). The CLI verifies it before saving. |
--no-open |
Print the approval URL without opening a browser. |
--no-shell |
Don't open the interactive shell after signing in. Use this in scripts. |
Scopes you can grant
The approval page only offers scopes your organization role allows. The server applies the same limit when it issues the token, so a modified request can't exceed it.
| Organization role | Scopes offered |
|---|---|
| Owner, Admin | Every ability in the catalog |
| Member | account.read, account.write, billing.read, edge.read, edge.env.read, sites.read, servers.read |
| Deployer | account.read, account.write, edge.read, edge.deploy, edge.env.read, sites.read, servers.read |
See Roles & permissions for what each role can do. The HTTP API page describes each ability.
Note
Members can't grant edge.deploy through the CLI, so a member's CLI token can read apps but can't deploy them. If you need to deploy from a terminal or CI, ask an admin to create an API token with edge.deploy for you.
Tokens issued through dply-edge login are named dply-edge CLI and don't expire. They stop working when someone revokes them, or when you leave the organization.
Add more scopes later
If a command fails with 403 Forbidden, your token doesn't carry the ability that command needs. Approve a new token with more scopes:
dply-edge auth refresh
dply-edge refresh and dply-edge account refresh do the same thing. The CLI shows the scopes that were added and removed, then revokes the previous CLI session. Pass --keep-old to keep the old session, --no-open to skip opening the browser, or --base-url to refresh against another host.
Sign in from CI
In CI, create an API token under Profile → API keys (see HTTP API) and pass it with --token:
dply-edge login --token "$DPLY_TOKEN" --base-url https://edge.dply.io --no-shell
dply-edge deploy --site "$DPLY_EDGE_SITE" --wait
A GitHub Actions workflow:
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: curl -fsSL https://edge.dply.io/cli/install.sh | bash
- run: dply-edge login --token "${{ secrets.DPLY_TOKEN }}" --base-url https://edge.dply.io --no-shell
- run: dply-edge deploy --wait --commit "${{ github.sha }}"
env:
DPLY_EDGE_SITE: ${{ vars.DPLY_EDGE_SITE }}
The token needs edge.read and edge.deploy. Either commit .dply/site.json or set DPLY_EDGE_SITE. --commit deploys the exact commit that triggered the workflow; leave it out to deploy the head of the app's branch. Profile → CLI in the dashboard shows the same workflow with your instance's URLs filled in.
Verify your setup
dply-edge whoami # user, organization, role, token abilities, linked site
dply-edge sites # apps this token can see
Link a folder to an app
Create the app in the dashboard first. The CLI can't create apps. Then, from your repository:
dply-edge link # pick from a list
dply-edge link <site-id> # or link by id
dply-edge link writes .dply/site.json in the current folder. Commands that act on one app look for that file in the current folder and its parents. The file also records which dply host the app lives on, so a linked repository keeps deploying to the right place after you switch hosts.
Every app-scoped command chooses its app in this order:
- The
--site <id>flag. - The
DPLY_EDGE_SITEenvironment variable. - The linked folder (
.dply/site.json).
Deploy
dply-edge deploy --wait
dply-edge deploy deploys the linked app, or the app that --site or DPLY_EDGE_SITE names. It's the same as dply-edge edge deploy. If the folder isn't linked, the command exits with code 2. If an older CLI linked the folder to a site type dply no longer hosts, dply-edge deploy asks you to re-link it.
| Flag | Description |
|---|---|
--commit <sha> |
Build this commit. |
--branch <name> |
Build this branch. |
--wait, --follow, -w |
Wait until the deployment is live, failed, or superseded. Exits 1 if it fails. |
--interval <ms>, -i |
How often --wait polls, in milliseconds. The default is 2000 and the minimum is 500. |
--prod |
After queueing, print the production URL. This flag doesn't change what gets deployed. |
--site <id> |
The app to deploy. |
Command reference
Run dply-edge help for a summary, dply-edge ls for a flat list of commands, or dply-edge edge --help for the app commands. Every two-word command also works in colon form: dply-edge edge:status is the same as dply-edge edge status.
Commands that print tables accept --json where noted.
Account
| Command | Description |
|---|---|
dply-edge whoami |
Same as dply-edge account show. Falls back to the saved local config if the API refuses the request. |
dply-edge account show [--json] |
Shows your user, current organization and role, the token's id, abilities, last use and expiry, and the linked folder. |
dply-edge account orgs [--json] |
Lists the organizations you belong to and your role in each. |
dply-edge account sessions [--json] |
Lists dply-edge CLI sessions in the organization. Admins see everyone's sessions. |
dply-edge account revoke <session-id> |
Revokes a CLI session. You can revoke your own sessions. Owners and admins can revoke anyone's. If you revoke the session you're using, the CLI removes its saved token. |
dply-edge account refresh |
Same as dply-edge auth refresh. |
dply-edge logout |
Removes the saved token for the active host from this machine. It doesn't revoke the token on the server. Also available as dply-edge account logout. |
Reading needs account.read and revoking needs account.write.
Hosts (dply-edge use)
A token works only on the dply host that issued it. The CLI stores a separate sign-in for each host and lets you switch between them:
| Command | Description |
|---|---|
dply-edge use |
Pick a saved host from a list. |
dply-edge use list |
List saved hosts. The active one is marked. |
dply-edge use <host> |
Switch to a saved host, for example dply-edge use edge.dply.io. |
dply-edge use <url> |
Sign in to a new host and keep the others saved. Outside a terminal, pass --login or run dply-edge login --base-url <url> instead. |
dply-edge use live |
Switch to https://edge.dply.io. cloud, prod, production, and hosted do the same. |
dply-edge use forget <host> |
Delete a saved host. dply-edge use rm <host> does the same. |
Hosts are keyed by hostname. dply-edge login --base-url <url> adds a host without removing the others.
Apps
| Command | Description |
|---|---|
dply-edge sites [name] [--json] |
Lists the apps this token can see, with id, name, status, URL, and runtime. A name filters the list. |
dply-edge link [site-id] |
Links the current folder to an app. |
dply-edge deploy |
Deploys the linked app. See Deploy. |
App commands (dply-edge edge)
Each of these accepts --site <id>.
| Command | Description | Ability |
|---|---|---|
dply-edge edge deploy |
Queues a deployment. Accepts the same flags as dply-edge deploy. |
edge.deploy |
dply-edge edge deployments [--limit N] |
Lists recent deployments with status, commit, branch, publish time, and alias count. The default limit is 20. |
edge.read |
dply-edge edge status [--wait] [--json] |
Shows the app and its latest deployment, including any failure reason. With --wait, blocks until an in-progress deployment finishes. |
edge.read |
dply-edge edge rollback <deployment-id> |
Points production at an earlier deployment. | edge.deploy |
dply-edge edge previews list |
Lists preview deployments. | edge.read |
dply-edge edge previews create [--commit <sha>] [--branch <name>] [--wait] |
Creates a preview. Without --commit, the CLI resolves the branch head through the public GitHub API, so private repositories need --commit. |
edge.deploy |
dply-edge edge previews rm <preview-id> |
Tears down a preview. destroy also works. |
edge.deploy |
dply-edge edge promote <preview-id> |
Promotes a preview to production. | edge.deploy |
dply-edge edge domains list |
Lists custom domains with DNS status and CNAME target. | edge.read |
dply-edge edge domains add <hostname> |
Attaches a domain and prints the DNS records to create. | edge.write |
dply-edge edge domains verify <hostname> |
Checks DNS and reports ready or the current status. |
edge.write |
dply-edge edge domains rm <hostname> |
Detaches a domain. | edge.write |
dply-edge edge container [show] |
Shows a container app's size, instance counts, sleep timer, Faster starts and the other Sleep-sheet switches, plus any settings waiting for a deploy. | edge.read |
dply-edge edge container set key=value … [--deploy] |
Changes them, e.g. size=basic max=2 min=0 sleep=5m faster_starts=on. Keys: instance_type (size), max_instances (max), min_instances (min), sleep_after (sleep), faster_starts, wake_copy, sticky_sessions, route_by_subdomain, dedicated_jobs, jobs_always_on, scheduler, migrate_on_boot, custom_vcpu, custom_memory_gib, custom_disk_gb. They apply on the next deploy; --deploy redeploys the live commit now. |
edge.write |
dply-edge edge aliases |
Lists the stable URL for each deployment. | edge.read |
dply-edge edge purge --tag <tag> |
Purges cached responses with a cache tag. --tag is required. |
edge.write |
dply-edge edge usage [--days N] |
Prints traffic and usage as JSON. The default is 30 days. |
edge.read |
dply-edge edge logs |
Tails request logs. See Tail logs. | edge.read |
dply-edge edge open [--dashboard] |
Opens the live URL, or the app's dashboard page with --dashboard. |
edge.read |
dply-edge edge lint [--path <file>] |
Validates dply.yaml, dply.yml, or dply.json with the same rules a build uses. Exits 1 if there are errors. |
edge.read |
dply-edge edge env list |
Lists environment variable keys and when each changed. The API never returns values. | edge.env.read |
dply-edge edge env pull |
Prints every key as KEY= with empty values. |
edge.env.read |
dply-edge edge env set KEY=value [KEY=value …] |
Creates or updates one or more variables. | edge.env.write |
dply-edge edge env rm KEY [KEY …] |
Deletes variables. remove and unset also work. |
edge.env.write |
dply-edge edge env push --file <path> |
Replaces the app's variables with the contents of a dotenv file. -f also works. |
edge.env.write |
Warning
dply-edge edge env push replaces the whole set of variables with the file's contents. Keys missing from the file are removed. To change a few keys, use dply-edge edge env set.
env push reads KEY=value lines. It supports double-quoted values (with \n and \t escapes), single-quoted literal values, export prefixes, and # comments. It skips keys that aren't uppercase letters, digits, and underscores.
Tail logs
dply-edge edge logs
Prints request logs as they arrive: time, method, status, duration, cache status, and path. Press Ctrl+C to stop.
| Flag | Description |
|---|---|
--once |
Print one batch and exit. |
--interval <ms> |
Poll interval, from 500 to 60000. The default is 1000. |
--window <s> |
How far back to start, from 1 to 3600 seconds. The default is 60. |
See Logs for what gets recorded.
An app's databases
These commands work on the linked app's Postgres, MySQL and MongoDB databases. <db> is the database's name or ID. See Databases.
| Command | Description | Ability |
|---|---|---|
dply-edge edge databases list [--json] |
Lists the app's databases: engine, the env it uses (DB_* for the primary, NAME_* for the others), size, disk and last backup. |
edge.read |
dply-edge edge databases show <db> [--json] |
Shows one database, with the progress of its last export and restore. | edge.read |
dply-edge edge databases query <db> "<sql>" [--json] |
Runs one read-only statement and prints up to 200 rows. | edge.write |
dply-edge edge databases query <db> <collection> ['<json filter>'] |
MongoDB: finds up to 200 documents. | edge.write |
dply-edge edge databases export <db> |
Starts an export. | edge.write |
dply-edge edge databases exports <db> [--json] |
Lists exports, newest first, each with a download link. | edge.read |
dply-edge edge databases import <db> <file> |
Uploads a local dump (the format an export makes) and loads it. For Postgres and MySQL, the tables in the file are replaced and the others are left alone. For MongoDB, everything is replaced. | edge.write |
dply-edge edge databases import <db> --export <file> |
Loads one of its exports back in. | edge.write |
dply-edge edge databases restore <db> "<time>" |
Restores the database to a moment in the last 7 days (UTC), for example "2026-09-28 14:30". |
edge.write |
dply-edge edge databases restore <db> "<time>" --as-new <name> |
Restores that moment into a new database named <name>, attached to the app, and leaves <db> as it is. |
edge.write |
The query is read-only, but it returns your app's data, so it needs edge.write. Creating, attaching, resizing and deleting a database stay in the dashboard.
Warning
A restore replaces the database's data with how it was at that moment. Postgres keeps the data from before the restore until the next restore. MySQL and MongoDB save it as a backup first.
Databases and queues
These commands work on the organization's D1 databases and queues. See Edge SQL (D1) and Queues.
| Command | Description | Ability |
|---|---|---|
dply-edge db list [--json] |
Lists databases. | edge.read |
dply-edge db query <database> "<sql>" [--json] |
Runs SQL and prints each statement's rows, or its change and row counts. | edge.write |
dply-edge queues list [--json] |
Lists queues. | edge.read |
dply-edge queues send <queue> '<json>' |
Sends one message. Text that isn't valid JSON is sent as a string. | edge.write |
dply-edge kv list [--json] |
Lists key-value stores. | edge.read |
dply-edge kv keys <store> [--prefix p] [--cursor c] [--json] |
Lists up to 1,000 keys, with each key's expiry and metadata. Prints the --cursor for the next page. |
edge.read |
dply-edge kv get <store> <key> [--json] |
Prints the value. | edge.read |
dply-edge kv put <store> <key> <value> [--ttl s | --expires-at unix] [--metadata json] |
Writes a key. | edge.write |
dply-edge kv delete <store> <key> |
Deletes a key. | edge.write |
Warning
dply-edge db query runs whatever SQL you give it, including writes and DROP. That's why it needs edge.write.
dply-edge kv shares the key-value API's limit of 60 calls a minute per organization. It's for seeding and inspecting keys, not for app traffic. Every dply-edge kv command except list also needs you to be an organization owner or admin.
Notifications
Routing links a channel, an event, and the app it fires for. See Notification channels.
| Command | Description | Ability |
|---|---|---|
dply-edge notifications [site] |
Shows which events are routed to which channels for an app. | notifications.read |
dply-edge notifications channels [--json] |
Lists the channels you can route to. | notifications.read |
dply-edge notifications events [--subject site] [--json] |
Lists the event catalog. | notifications.read |
dply-edge notifications subscribe <event…> --channel <id> |
Routes one or more events to a channel. This adds to the channel's current events and doesn't replace them. | notifications.write |
dply-edge notifications unsubscribe <event…> --channel <id> |
Stops routing those events. | notifications.write |
dply-edge notifications test <channel> |
Sends the channel a test message. | notifications.write |
dply-edge notify is an alias. --channel (or -c) accepts a channel id or part of its label. --site (or -s) accepts an app id or name. In a terminal, the CLI shows a picker when either is ambiguous.
Billing
Available to organization owners and admins, with billing.read.
| Command | Description |
|---|---|
dply-edge billing show [--json] |
Plan, monthly estimate, and subscription status. |
dply-edge billing breakdown [--json] |
Estimate by category and line item. |
dply-edge billing invoices [--json] |
Recent invoices. |
See Usage & metering and Invoices & taxes.
Interactive mode
Run dply-edge with no arguments in a terminal, or dply-edge shell, to open an interactive shell with tab completion. dply-edge menu (or dply-edge m) shows numbered menus, so you don't have to remember command names.
Shortcuts: me and who run whoami, orgs runs account orgs, bill runs billing show, and r runs refresh.
Configuration
| Path | Contents |
|---|---|
~/.dply/config.json |
Saved hosts, a token for each, and which host is active. |
.dply/site.json |
The linked app for a repository: app id, name, and host. You can commit it. |
Environment variables
| Variable | Effect |
|---|---|
DPLY_EDGE_SITE |
The app id for app-scoped commands, when --site isn't passed. |
DPLY_SITE |
Also sets the app for dply-edge notifications. |
DPLY_API_BASE_URL, DPLY_BASE_URL |
The dply host to sign in to or use when nothing else sets one. |
DPLY_TOKEN, DPLY_API_TOKEN |
A token for the account, billing, db, queues, and notifications commands that isn't read from the config file. The edge commands and dply-edge deploy don't read it, so in CI run dply-edge login --token first. |
DPLY_TLS_CA_FILE |
An extra CA certificate to trust, for self-hosted instances behind a private CA. |
NO_COLOR |
Turns off colored output. |
Exit codes
| Code | Meaning |
|---|---|
0 |
Success. |
1 |
An API or runtime error: a failed deployment, a failed lint, or dply-edge update --check finding a different build. |
2 |
Bad arguments, no linked app, not signed in, or a denied or expired login. |
Errors go to standard error, prefixed with dply:. On a 403, the CLI suggests dply-edge auth refresh.
Revoke CLI sessions
Each approved device appears as a session. To revoke one:
- From the terminal, run
dply-edge account sessions, thendply-edge account revoke <session-id>. - In the dashboard, open Profile → CLI. Under CLI authentications, choose Revoke next to the session. Only organization owners and admins can see this list.
Revoking a session invalidates its token right away. That machine must run dply-edge login again. Removing someone from the organization also stops every token they hold for it.