afy agents
The afy agents command group in the Aetherfy CLI
afy agents manages the lifecycle of Aetherfy agents. The group has two
aliases, agent and a, so afy a list and afy agents list are the same
command.
| Subcommand | Purpose |
|---|---|
afy agents list | List every agent in the account |
afy agents create <name> | Create an agent record |
afy agents delete <name> | Delete an agent permanently |
afy agents stop <name> | Pause an agent |
afy agents start <name> | Resume a paused agent |
afy agents archive <name> | Free the plan quota slot, keeping configuration and code |
afy agents restore <name> | Re-provision an archived agent |
afy agents cancel <name> | Cancel a pending deployment |
afy agents status <name> | Show detailed agent status |
afy agents rename <current> <new> | Rename an agent |
afy agents update <name> | Change workspace assignment or description |
afy agents pull <name> | Export the agent’s configuration as aetherfy.yaml |
afy agents diff | Compare local aetherfy.yaml against deployed state |
afy agents run <name> | Run a task agent once, immediately |
afy agents runs <name> | Show run history |
afy agents schedule pause <name> | Pause the agent’s scheduled task |
afy agents 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 agents schedule set. A schedule is declared with theschedule:key inaetherfy.yamland applied byafy deploy. See /agents/scheduled-tasks. - There is no
afy agents pauseorafy agents resume. The pause and resume verbs for an agent areafy agents stopandafy agents start.
Listing Aetherfy agents
afy agents list prints every agent in the account. It takes no arguments and
no flags of its own.
afy agents list
afy agents list -o jsonThe default columns are:
| Column | Meaning |
|---|---|
| Name | The agent name |
| Type | SERVICE or JOB |
| Status | Current lifecycle status |
| Region | Deployed region |
| ID | The Aetherfy agent ID |
When at least one agent in the account has a scheduled task, the table grows to eight columns: Name, Type, Status, Region, Schedule, Next Run, Last Run, ID.
| Column | Rendering |
|---|---|
| Schedule | The declared schedule expression |
| Next Run | A UTC timestamp, or (paused) when the schedule is paused |
| Last Run | A fired / skipped / missed badge plus a relative time, or never |
A status of usage_paused renders as paused (usage limit) — the agent was
paused by the Aetherfy usage meter, not by afy agents stop.
Creating an Aetherfy agent
afy agents create <name> creates the agent record. It takes exactly one
positional argument, the name.
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--description | -d | string | empty | Agent description |
--type | -t | string | SERVICE | Agent type: SERVICE or JOB |
--runtime | -r | string | python3.11 | Runtime: python3.11, python3.12, python3.13, node20, node22, node20-ts, node22-ts, bun, dockerfile |
--spawn-enabled | bool | false | Enable spawning for this agent |
--type accepts only SERVICE or JOB; anything else is rejected.
afy agents create scraper \
--type JOB \
--runtime python3.12 \
--description "Nightly catalogue scrape"afy agents create has no --workspace flag. To put a new Aetherfy agent in
a workspace, either run afy agents update <name> --workspace <ws> afterwards,
or declare the workspace: key in aetherfy.yaml before deploying.
Deleting an Aetherfy agent
afy agents delete <name> permanently deletes the agent.
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--force | -f | bool | false | Skip confirmation prompt |
Without --force the Aetherfy CLI asks for confirmation and requires you to type
the agent name exactly before it proceeds.
afy agents delete scraper
afy agents delete scraper --forceIf your goal is to free a plan quota slot rather than lose the agent, use
afy agents archive instead — it preserves the configuration and the stored code
bundle.
Pausing and resuming an Aetherfy agent with stop and start
afy agents 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 agents start <name> resumes an agent that was paused with stop.
afy agents stop api-gateway
afy agents start api-gatewayNeither 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 agents 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 agents restore <name> re-provisions an archived Aetherfy agent from the
preserved bundle.
afy agents archive old-worker
afy agents restore old-workerRestoring 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 agents cancel <name> cancels a pending deployment for the agent. It takes
no flags.
afy agents cancel scraperOnly 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 agents status <name> prints the detailed state of a single Aetherfy agent.
It takes no flags of its own and honours -o json.
afy agents status scraper
afy agents status scraper -o jsonThe text output covers:
| Field | Notes |
|---|---|
| ID | The Aetherfy agent ID |
| Name | The agent name |
| Type | SERVICE or JOB |
| Status | Current lifecycle status, with health or degraded detail when present |
| Region | Deployed region |
| Spawn Enabled | Whether this agent may start child agents |
| Workspace | The workspace the agent belongs to, if any |
| Schedule | The schedule expression, labelled UTC |
| Next run | Next scheduled fire time, or (paused) |
| Last run | Outcome and time of the most recent run |
| Created | Creation timestamp |
| Updated | Last-modified timestamp |
| Description | The agent description |
| Spawn relationships | Parent and child agents |
Renaming an Aetherfy agent
afy agents rename <current-name> <new-name> changes the agent’s name. It takes
exactly two positional arguments, which must differ.
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--force | -f | bool | false | Skip confirmation prompt |
afy agents rename scraper catalogue-scraper --forceThe Aetherfy agent URL is not derived from the name and does not change, so existing integrations, links, and webhooks keep working across a rename. Only the name changes.
Updating an Aetherfy agent’s workspace or description
afy agents update <name> changes the mutable metadata of an Aetherfy agent.
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--workspace | string | empty | Assign the agent to this workspace | |
--no-workspace | bool | false | Clear the agent’s workspace (make it workspaceless) | |
--description | -d | string | empty | Set the agent’s description |
Rules enforced by the Aetherfy CLI:
- At least one flag is required; with none, the command errors.
--workspaceand--no-workspaceare mutually exclusive.--workspace ""is rejected. Use--no-workspaceto clear the assignment.
afy agents update scraper --workspace research
afy agents update scraper --no-workspace
afy agents update scraper -d "Nightly catalogue scrape"This is also the supported way to move an existing Aetherfy agent into a
workspace, because afy agents create has no --workspace flag.
Exporting an Aetherfy agent’s configuration with pull
afy agents pull <agent-name> exports the agent’s current configuration in
aetherfy.yaml form. By default it writes to stdout so it can be redirected.
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--output | -o | string | empty | Write the YAML to this file instead of stdout |
Warning: on afy agents pull alone, -o means an output file path, not
the global Aetherfy output format. afy agents pull scraper -o json writes a
file named json. This subcommand shadows the global --output flag.
# To stdout
afy agents pull scraper
# Redirect
afy agents pull scraper > aetherfy.yaml
# Or write directly
afy agents pull scraper -o aetherfy.yamlThe 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 agents 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.
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--path | -p | string | . | Project directory containing aetherfy.yaml |
afy agents diff
afy agents diff --path ./services/scraperThe output legend:
| Marker | Meaning |
|---|---|
~ field: old → new | The deploy would change this field |
+ field: value | The deploy would set this field |
- field | The deploy would clear this field |
= field: value | No-op — local and deployed values match |
field: value | Preserved — 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 agents diff exits non-zero when there are changes, which makes it a
drift gate in CI:
afy agents diff --path ./services/scraper
if [ $? -ne 0 ]; then
echo "Deployed Aetherfy state has drifted from aetherfy.yaml"
exit 1
fiRunning an Aetherfy task agent on demand
afy agents run <name> runs a task agent once, immediately, outside its
schedule. Only deployed agents declared as type: job can be run this way.
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--payload | -p | string | empty | JSON payload to pass to the run |
--payload-file | -f | string | empty | Read the JSON payload from a file |
--wait | bool | false | Wait 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 agents run scraper
# With an inline payload
afy agents run scraper --payload '{"since":"2026-08-01","full":true}'
# With a payload file
afy agents run scraper --payload-file ./payload.json
# Block until the run finishes; non-zero exit if it fails
afy agents run scraper --waitWithout --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 code | Meaning and fix |
|---|---|
AGENT_NOT_DEPLOYED | The agent exists but has no deployment. Deploy it first: afy deploy. |
AGENT_SCHEDULE_NOT_SET | Add a schedule: key to aetherfy.yaml and deploy. |
AGENT_RUN_REQUIRES_JOB_TYPE | Only type: job agents can be run on demand. |
Listing Aetherfy run history
afy agents runs <name> shows the run history for an agent, newest first.
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--limit | int | 20 | Maximum number of runs to show (max 100) |
afy agents runs scraper
afy agents runs scraper --limit 100
afy agents runs scraper -o jsonColumns:
| Column | Meaning |
|---|---|
| When | Time of the run |
| Trigger | What started it — cron for a scheduled fire, or a manual trigger |
| State | Run outcome |
| Duration | Wall-clock run time |
| Run ID | Pass 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 agents schedule pause <name> pauses the agent’s scheduled task. No
scheduled runs fire until it is resumed. Manual runs via afy agents run are
unaffected. The command is idempotent — pausing an already-paused schedule
succeeds.
afy agents schedule resume <name> resumes a paused scheduled task, and is
likewise idempotent.
afy agents schedule pause scraper
afy agents schedule resume scraperOn 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.