Skip to main content

The akter CLI

Responsibility: document the akter command-line tool: its commands, flags, output, and exit statuses.
Authority: normative CLI interface.
Owner role: API/SDK.
Change policy: a changed command, flag, or exit status updates this page, the runbooks, and the guides that use it.
akter is the apps/cli bin, named durable before ADR 0085. It parses its arguments with Effect’s effect/cli module: one root akter command whose subcommands are the groups below, each flag typed and described, so akter --help and akter <command> --help print the same reference as this page. Flags take their value as --flag value or --flag=value, and -- ends flag parsing.

Exit statuses

Global flags

Every command takes --help (-h), --version (-v), --completions <bash|zsh|fish|sh>, which prints a shell completion script, --log-level <level>, and --wizard, which builds a command interactively.

akter --help

Operator commands

defects list, inspect, export, receipts show, dead-letters, and subscriptions call a runner’s Operators.serve routes. Each reads its bearer token from DURABLE_OPERATOR_TOKEN, or from the environment variable --token-env names. --url repeats; defects list reads every runner named, and the single-actor commands use the first. See ADR 0050 for the grants each command needs and the runbooks for when to use them.

Akter Cloud commands

login, logout, whoami and deploy talk to a control plane (apps/api) through its CloudApi client (ADR 0085). login signs in through Better Auth’s device authorization grant and stores the session in credentials.json in the CLI’s configuration directory: AKTER_CONFIG_DIR when set, else ~/Library/Application Support/akter on macOS, %APPDATA%\akter on Windows and $XDG_CONFIG_HOME/akter (default ~/.config/akter) elsewhere. The file is 0600 in a 0700 directory, written under a random temporary name that must not already exist and renamed into place, and a file the group or others can read is refused until it is fixed or replaced by another login. The other commands send the stored session as a bearer token to the control plane it came from, which must be https, or http only on a loopback host (localhost, *.localhost, 127.0.0.0/8, [::1]); login --api-url refuses any other URL with exit 2, and stored credentials naming one are refused as unreadable. A session acts in every organization its user belongs to, like gh or vercel; the control plane checks membership on every request.

Commands

akter login

Sign in to Akter Cloud through the browser and store the session for deploy
It prints the console’s /device page and a code written XXXX-XXXX (never a link that carries the code), then polls at the interval the control plane names, five seconds slower after each slow_down, until the code is approved, denied or past its own expiry. Approving the code saves the session, which starts in the approver’s active organization, and prints who it signs in as; a denied or expired code exits 1 and saves nothing. If the control plane will not say who the new session belongs to, login signs the session out again and saves nothing.

akter logout

Sign out of Akter Cloud and delete the stored session
It revokes the session at its control plane, then deletes the stored credentials even when the control plane could not be reached, and says so. A credentials file other users could read is still revoked, since its token may have leaked.

akter whoami

Show who the stored Akter Cloud session signs in as
It prints the email address and control plane, then one line per organization: its slug, the role and its id. An expired or revoked session exits 1 and asks for akter login.

akter deploy

Upload the build context, build and roll it out on Akter Cloud, and follow it until it is live
It packs the context as docker build would send it (<Dockerfile>.dockerignore, else .dockerignore; the Dockerfile always included): symbolic links are sent as links and never followed, files keep their permission bits, and owners and times are zeroed so the same files give the same digest. --dockerfile is cleaned (./a//Dockerfile is a/Dockerfile), and a path starting at / or containing .. is refused with exit 2 before anything is read. It uploads it to POST /api/projects/:projectId/sources, creates the deployment from the returned digest, and prints each rollout step as it starts and ends. It exits 0 once the deployment is live, and 1 when it fails, naming the failed step and, for a failed build, printing the build’s last 20 lines. Outside a git repository the deployment is labeled with the archive digest’s first 40 hex digits; a dirty working tree marks the message (with uncommitted changes). A control plane without a builder refuses the upload with NotImplemented, and one past 64 MiB is refused with PayloadTooLarge.

akter billing setup

Create or reconcile products, meters and prices using the configured provisional pricing. Every provider creation has a stable identity; repeating setup does not duplicate catalog objects.
Local mode is the default and uses only the SQL-backed Stripe implementation. Stripe mode reads STRIPE_API_KEY from the environment; it is not a command-line argument. API, edge and setup consume the same optional BILLING_PRICING_CONFIG JSON configuration. Setup does not publish the planning prices or establish live tax/provider support.

akter dev

Run the entry’s app locally with a read-only inspector at /_durable/inspector

akter workflows check

Compare the entry’s workflows with every open execution, read-only; exit 1 when a deploy would be refused

akter payloads check

Check that every stored event and job payload version still decodes, read-only; exit 1 when a deploy would be refused

akter payloads clear

Mark superseded event versions past their retention horizon cleared; exit 1 when one stays uncleared

akter adopt plan

Plan adopting the entry’s existing tables, with the SQL each needs; exit 1 while a table has a problem

akter adopt observe

Record which writers still write an adopted table, or report them with —report

akter adopt backfill

Fill routing_key on an observed table’s rows, in batches

akter adopt enforce

Enforce an adopted table: only the runtime’s writer role and —allow roles may write it

akter adopt status

Show each adopted table’s mode and the rows left to backfill

akter adopt release

Return an enforced table to observing

akter fleet setup

Give the entry’s fleet view sources full replica identity, publish them, and create the logical slot; needs wal_level=logical

akter fleet rebuild

Rebuild a fleet view from its source, clearing its error; exit 1 when no runtime registered it

akter defects list

List recent defects from each runner named; each keeps only its own recent defect spans

akter inspect

Read one actor’s state, newest receipts, and dead letters through the first runner named

akter export

Write one actor’s state and pending intents and jobs to a new seed file, through the first runner named

akter receipts show

Print one receipt’s stored outcome as JSON; the runner never runs the command to answer

akter dead-letters retry

Run a dead-lettered job again

akter dead-letters discard

Settle a dead-lettered job without running it

akter subscriptions list

List subscription rows whose deliveries keep failing, with their lag and last error

akter subscriptions skip

Skip a stuck subscription row’s events through a cursor; the runner audits the skip

akter tenants create

Record a new tenant’s home region in the control plane’s directory, attributed to —operator