Skip to Content
CLIAgent commands
Raw

Aetherfy agent commands

Agents are the default noun in the Aetherfy CLI

A bare verb is an agent verb. afy list lists your Aetherfy agents, afy status <name> describes one, and afy stop <name> pauses one. Only the other kinds of object keep a group of their own: afy secrets, afy workspaces, afy github, and the vector groups afy collections, afy index and afy points.

Each of these commands is spelled exactly one way. There is no afy agents group and no alias for one.

SubcommandPurpose
afy listList every agent in the account
afy create <name>Create an agent record
afy delete <name>Delete an agent permanently
afy stop <name>Pause an agent
afy start <name>Resume a paused agent
afy archive <name>Free the plan quota slot, keeping configuration and code
afy restore <name>Re-provision an archived agent
afy cancel <name>Cancel a pending deployment
afy status <name>Show detailed agent status
afy rename <current> <new>Rename an agent
afy update <name>Change workspace assignment or description
afy pull <name>Export the agent’s configuration as aetherfy.yaml
afy diffCompare local aetherfy.yaml against deployed state
afy run <name>Run an agent once, immediately
afy runs <name>Show run history
afy schedule pause <name>Pause the agent’s scheduled task
afy schedule resume <name>Resume the agent’s scheduled task

Two things do not exist in the Aetherfy CLI and are commonly assumed:

  • There is no afy schedule set. A schedule is declared with the schedule: key in aetherfy.yaml and applied by afy deploy. See /agents/scheduled-tasks.
  • There is no afy pause or afy resume. The pause and resume verbs for an agent are afy stop and afy start.

Listing Aetherfy agents

afy list prints every agent in the account. It takes no arguments and no flags of its own.

afy list afy list -o json

The default columns are:

ColumnMeaning
NameThe agent name
TypeSERVICE or JOB
StatusCurrent lifecycle status
RegionsThe regions the agent is deployed in
IDThe Aetherfy agent ID

When at least one agent in the account has a scheduled task, the table grows to eight columns: Name, Type, Status, Regions, Schedule, Next Run, Last Run, ID.

ColumnRendering
ScheduleThe declared schedule expression
Next RunA UTC timestamp, or (paused) when the schedule is paused
Last RunThe most recent run’s outcome and how long ago it started, such as failed, 2m ago, or never. When the schedule’s last tick did not start a run, a second line says so: tick skipped (5m ago) or tick missed (5m ago). A tick that fired adds nothing — its run is the first line. The reason a run failed is printed by afy status

A status of usage_paused renders as paused (usage limit) — the agent was paused by the Aetherfy usage meter, not by afy stop.

Creating an Aetherfy agent

afy create <name> creates the agent record. It takes exactly one positional argument, the name.

FlagShortTypeDefaultDescription
--description-dstringemptyAgent description
--type-tstringSERVICEAgent type: SERVICE or JOB
--runtime-rstringpython3.11Runtime: python3.11, python3.12, python3.13, node20, node22, node20-ts, node22-ts, bun, dockerfile
--spawn-enabledboolfalseEnable spawning for this agent

--type accepts only SERVICE or JOB; anything else is rejected.

afy create scraper \ --type JOB \ --runtime python3.12 \ --description "Nightly catalogue scrape"

afy create has no --workspace flag. To put a new Aetherfy agent in a workspace, either run afy update <name> --workspace <ws> afterwards, or declare the workspace: key in aetherfy.yaml before deploying.

This is not the only way to create an agent. afy deploy will also create the agent it targets — from the type and runtime in aetherfy.yaml, and only with explicit consent — so a first deploy need not be preceded by this command. See /cli/deploy.

Deleting an Aetherfy agent

afy delete <name> permanently deletes the agent.

FlagShortTypeDefaultDescription
--force-fboolfalseSkip confirmation prompt

Without --force the Aetherfy CLI asks for confirmation and requires you to type the agent name exactly before it proceeds.

afy delete scraper afy delete scraper --force

If your goal is to free a plan quota slot rather than lose the agent, use afy archive instead — it preserves the configuration and the stored code bundle.

Pausing and resuming an Aetherfy agent with stop and start

afy stop <name> pauses an Aetherfy agent. It stops every machine and prevents the proxy from re-waking the agent on incoming traffic. The pause is reversible.

afy start <name> resumes an agent that was paused with stop.

afy stop api-gateway afy start api-gateway

afy start returns once every machine has booted. For a service agent it also waits, up to a bound, for your code to answer its health check, and says what it found:

readinessWhat afy start tells you
servingThe agent resumed and is serving requests
startingThe agent resumed; your code is still starting, and requests sent now are held until it is listening
load_failedThe agent resumed, but your code failed to load, so its requests will fail — afy logs <name> has the error
unconfirmedThe agent resumed and its machines started, but your code did not answer in the time allowed — afy logs <name> shows where it is
slow_startThe agent resumed, but starting its machines took longer than it should, so your code was not checked — the delay was on Aetherfy’s side
nullA job agent, which serves no requests: it says only that the agent resumed

The agent is resumed in every case, and the command exits 0 — these describe your code, not the resume. The same field is in the API response, described in Stopping and starting.

Neither command takes flags. A stopped Aetherfy agent still bills at the base rate — stopping suspends execution, not billing. To stop billing for an agent you are not using, archive it.

Archiving and restoring an Aetherfy agent

afy archive <name> destroys the underlying application to free the plan quota slot while preserving the agent’s configuration and its stored code bundle. It is reversible.

afy restore <name> re-provisions an archived Aetherfy agent from the preserved bundle.

afy archive old-worker afy restore old-worker

Restoring consumes a plan quota slot, and the quota is re-checked at restore time. If you are already at your plan limit the restore is rejected until you free a slot or upgrade. Plan quotas are documented at /platform/limits.

Cancelling a pending Aetherfy deployment

afy cancel <name> cancels a pending deployment for the agent. It takes no flags.

afy cancel scraper

Only deployments in the QUEUED state are cancellable. A deployment whose build is already in flight returns HTTP 409 from the Aetherfy API and cannot be cancelled; wait for it to finish, then roll back with afy rollback if the result is wrong.

Inspecting an Aetherfy agent with status

afy status <name> prints the detailed state of a single Aetherfy agent. It takes no flags of its own and honours -o json.

afy status scraper afy status scraper -o json

The text output covers:

FieldNotes
IDThe Aetherfy agent ID
NameThe agent name
TypeSERVICE or JOB
StatusCurrent lifecycle status, with health or degraded detail when present
RegionsThe regions the agent is deployed in
Spawn EnabledWhether this agent may start child agents
WorkspaceThe workspace the agent belongs to, if any
ScheduleThe schedule expression, labelled UTC
Next runNext scheduled fire time, or (paused)
Last tickWhat the schedule last did when it did not start a run — skipped or missed — with the reason Aetherfy recorded. Absent when the last tick fired
Last runThe most recent scheduled or manual run: its outcome, the reason when it failed, and how long ago it started, as in “failed (run exited with code 1), 2m ago”. never for a scheduled agent that has not run
CreatedCreation timestamp
UpdatedLast-modified timestamp
DescriptionThe agent description
Spawn relationshipsParent and child agents
Repo, Branch, Directory, Webhook idThe agent’s GitHub link, when it has one

An agent linked to a GitHub repository with afy github link also gets its link printed: the repository, the branch that is watched, the directory inside it — repository root when the link has none — and the webhook id. An agent with no link prints none of this.

Two states leave that link intact and stop deploying anything, and afy status is where the terminal can learn about either:

What status saysWhat happenedWhat fixes it
GitHub disconnected — pushes are not deployingThe Aetherfy account is no longer connected to GitHubafy github connect. The link is kept, so deploys resume on reconnect
Branch deleted — pushes are not deployingThe branch the link watches was deleted, and status names which and whenRecreate the branch and push. Relinking would succeed and change nothing

Neither state is reported on GitHub. Aetherfy announces a skipped push as a commit status, which needs the installation token a disconnect removes, and a deleted branch has no commit to attach one to at all.

A tick that fired has started a run, and says nothing about how that run went: the Last run line does. Read afy runs <name> for the runs before it.

afy status <name> -o json carries the last run under a last_run key — id, trigger_source, state, created_at, error_message and release_version — and the link state under a github key, with the API’s own field names — linked, repo, branch, root_dir, webhook_id, account_connected and branch_deleted_at. The link is part of the agent record afy status reads rather than a separate request, so a status that printed has no second read that could have failed.

Renaming an Aetherfy agent

afy rename <current-name> <new-name> changes the agent’s name. It takes exactly two positional arguments, which must differ.

FlagShortTypeDefaultDescription
--force-fboolfalseSkip confirmation prompt
afy rename scraper catalogue-scraper --force

An Aetherfy agent’s URL is fixed when the agent is FIRST DEPLOYED, and a rename does not move it. Existing integrations, links, and webhooks keep working across a rename; only the name changes.

The practical rule: rename before your first deploy and the URL follows the new name, rename after and it stays as it was.

The rename also updates your local aetherfy.yaml. afy deploy finds its target through the name: key in that file, so a rename that stopped at the Aetherfy server would leave the file naming an agent that no longer exists — and the next deploy from that directory would report the agent as not found, then offer to create one under the old name.

afy rename closes that gap and tells you which branch it took:

What is in the current directoryWhat happens
An aetherfy.yaml whose name: is the OLD nameThat one key is rewritten. Comments, key order, quoting and line endings are left alone
An aetherfy.yaml naming a different agentNothing is touched. That file belongs to another project, and rewriting it would retarget its deploys
No aetherfy.yaml, or one with no name: keyNothing is touched

In the last two cases the command names the file you still have to update. Set name: to the new name in whichever aetherfy.yaml you deploy this agent from, or that deploy will not find it.

The dashboard has no rename button, and that is the reason: a browser cannot reach the file on your machine, so it cannot finish the job.

Updating an Aetherfy agent’s workspace or description

afy update <name> changes the mutable metadata of an Aetherfy agent.

FlagShortTypeDefaultDescription
--workspacestringemptyAssign the agent to this workspace
--no-workspaceboolfalseClear the agent’s workspace (make it workspaceless)
--description-dstringemptySet the agent’s description

Rules enforced by the Aetherfy CLI:

  • At least one flag is required; with none, the command errors.
  • --workspace and --no-workspace are mutually exclusive.
  • --workspace "" is rejected. Use --no-workspace to clear the assignment.
afy update scraper --workspace research afy update scraper --no-workspace afy update scraper -d "Nightly catalogue scrape"

This is also the supported way to move an existing Aetherfy agent into a workspace, because afy create has no --workspace flag.

Exporting an Aetherfy agent’s configuration with pull

afy pull <agent-name> exports the agent’s current configuration in aetherfy.yaml form. By default it writes to stdout so it can be redirected.

FlagShortTypeDefaultDescription
--output-ostringemptyWrite the YAML to this file instead of stdout

Warning: on afy pull alone, -o means an output file path, not the global Aetherfy output format. afy pull scraper -o json writes a file named json. This subcommand shadows the global --output flag.

# To stdout afy pull scraper # Redirect afy pull scraper > aetherfy.yaml # Or write directly afy pull scraper -o aetherfy.yaml

The emitted YAML is the declarative subset only — fields the Aetherfy server derives are excluded. Re-deploying the pulled file is therefore a no-op against the agent it came from.

Diffing local aetherfy.yaml against deployed Aetherfy state

afy diff compares the local aetherfy.yaml against the agent’s current state on Aetherfy and prints what a deploy would change under merge-patch semantics. It takes no positional arguments — the agent is identified from the manifest.

FlagShortTypeDefaultDescription
--path-pstring.Project directory containing aetherfy.yaml
afy diff afy diff --path ./services/scraper

The output legend:

MarkerMeaning
~ field: old → newThe deploy would change this field
+ field: valueThe deploy would set this field
- fieldThe deploy would clear this field
= field: valueNo-op — local and deployed values match
field: valuePreserved — not present locally, left untouched

A runtime change is annotated (immutable — deploy will reject), because the Aetherfy runtime cannot be changed on an existing agent.

afy diff exits non-zero when there are changes, which makes it a drift gate in CI:

afy diff --path ./services/scraper if [ $? -ne 0 ]; then echo "Deployed Aetherfy state has drifted from aetherfy.yaml" exit 1 fi

Running an Aetherfy task agent on demand

afy run <name> runs an agent once, immediately, outside its schedule. A type: job agent runs its entrypoint; a type: service agent is sent one request to its POST /aetherfy/run route — see /agents/task-contract.

FlagShortTypeDefaultDescription
--payload-pstringemptyJSON payload to pass to the run
--payload-file-fstringemptyRead the JSON payload from a file
--waitboolfalseWait for the run to finish (exit 1 if it fails)

--payload and --payload-file are mutually exclusive, and the payload must be a JSON object.

# Fire and forget afy run scraper # With an inline payload afy run scraper --payload '{"since":"2026-08-01","full":true}' # With a payload file afy run scraper --payload-file ./payload.json # Block until the run finishes; non-zero exit if it fails afy run scraper --wait

Without --wait, the Aetherfy CLI prints the Run ID and suggests afy logs <name> --run <id>. With --wait, it polls for up to 30 minutes; a failed run exits 1, and on timeout the run keeps going on Aetherfy — only the waiting stops.

Error hints the Aetherfy CLI prints:

Error codeMeaning and fix
AGENT_NOT_DEPLOYEDThe agent exists but has no deployment. Deploy it first: afy deploy.

Listing Aetherfy run history

afy runs <name> shows the run history for an agent, newest first.

FlagShortTypeDefaultDescription
--limitint20Maximum number of runs to show (max 100)
afy runs scraper afy runs scraper --limit 100 afy runs scraper -o json

Columns:

ColumnMeaning
WhenWhen the run was started, in UTC and labelled so — the same instant -o json gives as created_at
TriggerWhat started it — cron for a scheduled fire, or a manual trigger
StateRun outcome
ReleaseThe release the run executed, as afy deployments numbers it (v3). A dash when none was recorded: a service run that was never dispatched, or a run older than the field
DurationWall-clock run time
Run IDPass to afy logs <name> --run <id>

Only scheduled and manual runs appear here. Runs started by a parent agent through afy spawn belong to the parent’s history and are deliberately excluded from the child’s list — see /cli/spawn.

Pausing and resuming an Aetherfy scheduled task

afy schedule pause <name> pauses the agent’s scheduled task. No scheduled runs fire until it is resumed. Manual runs via afy run are unaffected. The command is idempotent — pausing an already-paused schedule succeeds.

afy schedule resume <name> resumes a paused scheduled task, and is likewise idempotent.

afy schedule pause scraper afy schedule resume scraper

Both subcommands require the agent to have a schedule. Against one that does not, Aetherfy answers 422 AGENT_SCHEDULE_NOT_SET and the CLI prints the fix: add a schedule: key to aetherfy.yaml and deploy.

On resume the next run time is recomputed from now. Occurrences that elapsed while the schedule was paused are skipped, never backfilled — Aetherfy does not replay a missed window.

Both subcommands print whether anything actually changed, the resulting paused flag, and the next run time (or (paused)). Both honour -o json.

Neither command edits aetherfy.yaml. The schedule expression itself is declared there and applied by afy deploy; see /agents/scheduled-tasks and /agents/aetherfy-yaml.

Last updated on