Source: https://docs.any.org/reference/cli.html
# CLI
`any` is one binary in two roles: `any run` starts the server, and every other subcommand is an HTTP call to it. The CLI never opens the SDK or touches storage, so anything you can do from the terminal you can do from `curl` — and vice versa.
## Global flags and exit codes
```
--addr # bind address for `run`; connect address otherwise — default: the address
# the running server recorded (/server.addr), else 127.0.0.1:7001
--control-token # managed server's control token; prefer ANY_CONTROL_TOKEN (a flag is visible in ps)
--timeout # request timeout, default 30s (does not apply to streams)
--verbose # log the HTTP request/response to stderr
```
| Exit code | Meaning |
| --- | --- |
| `0` | success |
| `1` | user error — bad arguments, or a 4xx from the server |
| `2` | server error — a 5xx |
| `3` | transport error — the server cannot be reached |
Output is pretty-printed JSON, always. The two deliberate exceptions are `any file download` (raw bytes to stdout) and streaming commands, which print one JSON object per SSE frame — `{"event": "", "data": }` — so they pipe cleanly into `jq`. When the server is not running the CLI exits 3 and prints `start it with any run in another terminal`; there is no auto-start.
Input conventions: JSON-valued flags (`--pipeline`, `--records`, `--draft`, `--body`, `--x-format`, …) accept `''`, `@FILE` or `-` for stdin; `--filter` is a Mongo-style filter object; windowed queries take `--projection 'any,'` or `'-_ver'`.
## Meta and auth
```
any init [--mnemonic "w1 … w12"] [--mnemonic-stdin] [--index N] [--new]
[--config PATH] [--data-dir PATH] [--account ID] [--wallet PATH] [--passkey-stdin]
any run [--config PATH] [--data-dir PATH] [--mode standalone|managed] [--account ID]
[--addr host:port] [--wallet PATH] [--passkey-stdin]
[--log-level debug|info|warn|error]
any auth login [--mnemonic …|--mnemonic-stdin|--account ID] [--index N] [--replace] # POST /v1/auth
any auth logout # DELETE /v1/auth (managed)
any auth status # GET /v1/auth
any status # GET /v1/health
any stop [--config PATH] [--data-dir PATH] [--account ID] # signal the server holding the account lock
any version # binary version, plus the server's when one runs
```
`--mode managed` starts a host-owned server: it never resolves an account from disk, the phrase arrives over `POST /v1/auth` on every launch, and it prints its control token as the second stdout line (`CONTROL_TOKEN `). `auth login --replace` (switch in place) and `auth logout` are managed-only and need that token (`ANY_CONTROL_TOKEN`). `any stop` sends no HTTP and takes no `--addr`: it finds the server by its held account lock and signals it — so it works against a wedged server and one on an ephemeral port; a standalone server refuses `POST /v1/shutdown`. Not available on Windows (no signal to send — stop the server with Ctrl-C).
`any init` creates the data dir and an account wallet, printing the BIP-39 mnemonic to stderr once. With `--mnemonic` / `--mnemonic-stdin` it restores an existing account (same phrase, same account id, a fresh device key) — prefer stdin so the phrase stays out of shell history. `--index` defaults to 1 (the any derivation index; 0 restores an anytype-derived account); `--new` forces an additional account. `any run` never creates wallets: with no resolvable account it starts unauthorized and waits for `any auth login`. See [Accounts](https://docs.any.org/auth/accounts.md.txt).
## Account, identities, devices
```
any account set-metadata [--name N] [--description D] [--icon-cid CID] # PUT /v1/account/metadata
any account redeem # POST /v1/account/access-code
any identities list | get | subscribe # alias: any contacts
any devices list # rows + active map + self
any devices register [--name N] [--app slug[=ver]]... [--remove-app slug]...
any devices activate
any devices remove --yes # permanent for that peer id
any devices query [--filter J] [--sort K] [--limit N] [--offset N] [--total] [--projection P]
any devices subscribe [same flags]
```
`GET /v1/account` has no subcommand — call it with `curl`.
## Spaces
```
any space get
any space update [--name N] [--description D] [--icon-cid CID] # unset flag = keep, --name='' = clear
any space settings [--set k=v]... [--set-bool k=true|false]... [--set-num k=N]... [--unset k]...
any space delete --yes
any space sync # force one head-sync round
any space derived # list well-known derived spaces
any space derived create # materialize one (idempotent)
any space query [--dataset spaces|profile] [--filter J] [--sort K] [--limit N] [--offset N] [--total] [--projection P]
any space subscribe [same flags] # live space list, one frame per line
any datasets [] # dataset schemas (JSON Schema + x-scope)
any search [--scopes basic,chat,props] [--limit N]
[--mode hybrid|fts|vector] [--require T]... [--exclude T]...
[--max-data N] [--passages N] [--filter J]
```
`any space settings` writes the account-private per-space settings object; push reads `notifyMode` from it: `any space settings $SP --set notifyMode=mentions`. `any search` defaults to `hybrid` and degrades to FTS when the server has no embedder — the reply's `mode` says which ran; `--limit` counts records, `--max-data` bounds each hit's text window (default 512 runes, `-1` = whole chunk), `--passages` adds up to 10 further matching chunks per record, `--filter` keeps hits whose host object matches an objects-query filter (inline JSON, `@FILE` or `-`).
Space create and list have no dedicated subcommand — use `curl` against `POST /v1/spaces` and `GET /v1/spaces`; join with `any join --token T` below.
## One-to-one spaces
```
any one-to-one start # aliases: any 1-1, any direct
any one-to-one accept
any one-to-one decline # sticky; a later start un-declines
any one-to-one register [--name N] [--description D] [--icon-cid CID]
any one-to-one pending # incoming requests
```
## Catalog and bundles
```
any catalog list # GET /v1/catalog
any catalog get
any catalog setup # adopt-or-install, dependencies first
any bundle ensure --body ''|@FILE|-
any bundle list
any bundle get
any bundle resolve
any bundle child --seed SEED --type T [--collection C]...
```
`catalog setup` prints every bundle it touched with its `typeId` or `collectionId` — whichever kind the bundle declares — and its xKey → propId `properties`, so the ids a client writes with come from the reply, never from minting a definition by xKey.
```bash
any catalog setup wiki $SP
```
## Reads and writes
```
any query-subscribe --dataset NAME [--filter J] [--sort K] [--limit N] [--offset N] [--total] [--projection P]
any query-subscribe --properties [same flags] # per-space objects storage collection
any aggregate --dataset NAME --pipeline ''|@FILE|-
any aggregate --properties --pipeline ''|@FILE|-
[--group-limit N] [--accum-limit N] [--memory-limit N] [--explain]
any upsert --dataset NAME --records ''|@FILE|- [--page-size N] [--trace-id T]...
any backlinks [--record R --dataset D | --prop P] [--kind K]... [--limit N]
any backlinks --target [--kind K]... [--limit N] # across every indexed space
any links [--record R] [--dataset D] [--prop P] [--kind K]... [--limit N]
```
`query-subscribe` prints the `ready` → `snapshot` → `changes` → `closed` frames as JSON lines; `--limit` is required when `--sort` is set. `--kind` takes `mention`, `link`, `card`, `embed` or `relation`.
```bash
any query-subscribe $SP $CHAT --dataset chat_messages --sort=-_ver.id --limit 50 \
| jq 'select(.event=="changes") | .data[]'
```
Snapshot query, modify and delete-records have no subcommand — call `POST /v1/spaces/:id/query`, `/modify`, `/delete-records` directly.
## Editor
```
any editor blocks create --type T [--text S] [--style JSON] [--parent ID] [--pos LEXID] [--collection NAME]
any editor blocks patch [--set JSON] [--unset PATH]... [--collection NAME]
any editor blocks delete [--collection NAME]
any editor edit --old TEXT --new TEXT [--all] [--collection NAME]
any editor edit --edits ''|@FILE|- [--collection NAME]
```
`--collection` names the editor collection (default `editor_blocks`; a namespaced `_` for a part with its own editor). `editor edit` is `PATCH …/editor/:collection/markdown`: each `oldText` must match the current rendering exactly (whole-line fuzzy fallback for unicode punctuation and trailing whitespace) and, without `--all`, exactly once. The example needs `- [ ] buy milk` in the document; once it applies, running it again answers `markdown.no_match`.
```bash
any editor edit $SP $DOC --old '- [ ] buy milk' --new '- [x] buy milk'
```
## Chat
```
any chat send --text S | --file FILE|- [--reply-to MSG]
[--agent-name N] [--agent-debug-link L] [--agent-done=false]
any chat edit --text S | --file FILE|-
any chat delete
any chat react # toggle
```
`` is the `rootId` of the space's chat — `any catalog setup general-chat ` installs or adopts it and prints the root. Text is markdown; `--file -` reads it from stdin. Edit and delete work on your own messages only. Reading is `any query-subscribe … --dataset chat_messages`.
## Objects
```
any object create --type T [--collection C]... [--properties ''|@FILE|-]
any object type set
any object collection attach
any object collection detach
```
`--type` is required (`page` is the plain document) and `object type set` replaces the previous one — there is no unset. `--collection` repeats; attach and detach are idempotent, and detaching is not a delete: that owner's values stay on the row as orphan data. `--properties` seeds values keyed owner → propId → value, the owner being the type or one of the collections.
`set` and `attach` pre-flight the id (`404 type.not_found` / `404 collection.not_found`, `400 type.not_a_type` / `400 collection.not_a_collection` when it names the other surface); `detach` pre-flights nothing, so it can repair a row that already carries a bogus id.
```bash
any object create $SP --type page --collection $WIKI
any object create $SP --type $PERSON --collection $CONTACT --properties '{"any":{"name":"Ada"}}'
any object collection attach $SP $OBJ bin # to the bin
any object collection detach $SP $OBJ bin # restore
```
## Types and properties
```
any type create --name N --xkey K [--description D] [--icon-cid CID]
[--layout ''] [--hidden] [--meta k=v]...
any type list [--include-hidden]
any type update [--name N] [--description D] [--icon CID]
[--layout ''|''] [--hidden[=false]] [--meta k=v]...
any type property list # alias: any type prop
any type property add --name N --kind string|number|boolean|array|object|datetime
[--xkey K] [--description D] [--scope synced|account|local] [--x-format ''|@FILE|-]
any type property patch --set '' [--unset PATH]...
any type property remove
any type property option set [--name N] [--color C] [--pos LEXID]
any type property option delete
any type part list
any type part add --draft ''|@FILE|-
any type part patch --set '' [--unset PATH]...
any type part remove
any type part dataset list # alias: any type part ds
any type part dataset add --draft ''|@FILE|-
any type part dataset patch --set '' [--unset PATH]...
any type part dataset remove
any type part dataset field add --field ''|@FILE|-
any type part dataset field patch --set '' [--unset PATH]...
any type part dataset field remove
```
```bash
any type property add $SP $T --name Stage --xkey stage --kind array --x-format '{"type":"choice"}'
any type property patch $SP $T $P --set '{"xFormat.options.high.name":"High","xFormat.options.high.color":"red"}'
any type property option set $SP $T $P high --name High --color red --pos a0 # same write, sugar
```
## Collections
```
any collection list [--include-hidden]
any collection get
any collection create --name N --xkey K [--description D] [--icon-cid CID]
[--hidden] [--meta k=v]...
any collection update [--name N] [--description D] [--icon CID]
[--hidden[=false]] [--meta k=v]...
any collection property list # alias: any collection prop
any collection property add --name N --kind string|number|boolean|array|object|datetime
[--xkey K] [--description D] [--scope synced|account|local] [--x-format ''|@FILE|-]
any collection property patch --set '' [--unset PATH]...
any collection property remove
```
A collection is what an object is filed under; a type is what it is. A collection takes a name, description, icon, `--xkey`, `--hidden`, `--meta` and property definitions — no parts, no layout. The property verbs are the type ones on a collection owner, same flags and same `{set, unset}` patch rules; the choice-option sugar is on the type group only, so patch the descriptor path directly here.
`--xkey` is required on create and unique across the space's types and collections together (`409 type.xkey_conflict`). `collection list` omits hidden collections (the built-in `miniapp` / `bin`, and any you marked hidden) without `--include-hidden`; `collection get` resolves them always. A registered built-in refuses a metadata write (`400 collection.registered`), and deleting a collection is `501 sdk.not_implemented`.
```bash
any collection create $SP --name Contacts --xkey contact
any collection property add $SP $C --name Company --xkey company --kind string
any collection update $SP $C --hidden=false --meta pinned=true
```
## Files
```
any file attach |- [--name N] [--mime M] [--variant V --variant-of FILE]
any file list [--object OBJ] [--limit N]
any file get
any file download [-o PATH] [--variant V] # raw bytes to stdout by default
any file status
any file stats
any file subscribe
any file pin | retry | offload
any file delete --yes
any file query [--filter J] [--sort K] [--limit N] [--offset N] [--total] [--projection P]
any file query-subscribe [same flags]
any file cache size | free | sweep
```
The attach receipt normally shows `durable: false` — backup is background work; `any file subscribe` shows the `inflight → durable` flip. `offload` exits 1 with `file.not_durable` while the local bytes are the only copy.
## Local store
```
any local meta # pipeline stages and accumulators
any local collections [--scope account|space] [--space ID]
any local ensure [--space ID] [--index 'a,-b']... [--unique-index 'k']...
any local drop --yes [--space ID]
any local insert | upsert --doc ''|@FILE|- [--space ID]
any local update --modifier '' [--upsert] [--space ID]
any local delete [...] [--filter J] --yes [--space ID]
any local get [--space ID]
any local query [--filter J] [--sort K] [--limit N] [--offset N] [--total] [--projection P] [--space ID]
any local aggregate --pipeline '' [--group-limit N] [--accum-limit N] [--memory-limit N] [--explain] [--space ID]
any local indexes [--ensure 'a,-b']... [--unique-ensure 'k']... [--drop NAME]... [--space ID]
any local export [--scope account|space] [--space ID] [--names a,b] --out FILE
any local import FILE # - reads stdin
```
Without `--space` a local storage collection is account-scoped; with it, bound to that space. `export` with neither scope nor names takes every local collection. Nothing here syncs.
```bash
any local ensure scratch --index k,-at
any local insert scratch --doc '[{"id":"a","k":1},{"k":2}]'
any local query scratch --filter '{"k":{"$gt":0}}' --sort -k --total
```
With that collection on an authorized server, export and re-import it:
```bash
any local export --scope account --names scratch --out scratch.anyenc.gz &&
any local import scratch.anyenc.gz
```
`--out -` writes the export to stdout; `any local import -` reads stdin. Without `--names`, export takes every collection in the selected scope; `--space ID` implies space scope. The file is a gzip-compressed anyenc stream carrying scope, space id, names, indexes and documents. Another authorized server imports it with `any --addr http://127.0.0.1:7002 local import scratch.anyenc.gz`; a space-scoped collection is readable there even when that server never had the space.
Import ensures indexes and upserts documents; documents whose ids are absent from the file stay. It commits in chunks, so a failed import can leave earlier chunks in place. It copies local collections only — no CRDT data, no file bytes. Responses and failure codes: [HTTP contract](https://docs.any.org/reference/http-api.md.txt#export-and-import-local-collections).
## Members, invites, ACL
```
any members list | me | requests
any members get
any members subscribe
any invite create | list | revoke-all
any invite get | revoke
any invite guest-key # public read-only token (owner)
any invite guest-key-revoke # rotate the read key
any invite pending # direct-add invites awaiting approval
any invite accept | decline
any join --token T [--name N] [--description D] [--icon-cid CID]
any acl accept --record R [--permission P] # R from `any members requests`; default writer
any acl decline --identity X
any acl grant
any acl remove ...
any acl add [,...] [--name N] [--description D]
any acl ownership --new-owner X [--old-owner-perm P] # default admin
any acl self-remove | cancel-join | stop-sharing
```
Permissions are `none`, `reader`, `guest`, `writer`, `admin`, `owner`. `any acl add` adds accounts by identity in one ACL record; each added account sees an `invite_pending` row and resolves it with `any invite accept` / `decline`. `--name` / `--description` apply to a single-identity add only.
## Sync status, events, processes, push, debug
```
any sync-status space
any sync-status object
any sync-status subscribe [ ] # account-wide without args
any events publish --type T [--scope device|account|space] [--space ID] [--target X] [--data J|@FILE|-]
any events subscribe [--scope S]... [--type T|x.*]... [--space ID]... [--target X]...
any process list
any process cancel ID [--identity X]
any push token set --platform ios|android --token TOKEN
any push token revoke | status
any push subscriptions
any debug space # per-peer headsync counters
any debug object # tree + sync snapshot (walks the tree)
any debug p2p # LAN discovery snapshot
```
```bash
any events publish --type ui.open_space --data '{"spaceId":"'$SP'"}'
any events subscribe --type 'ui.*'
```
> **Note.** `GET …/sync-status/peers` has no subcommand and returns `501` until the SDK exposes a stable per-space peer list; `any debug space` is the diagnostic equivalent. The push commands exit 1 with `push.disabled` unless the server has a push node configured.