Skip to content
Odinex Cloud
CLI (odx)

odx CLI

Manage Odinex Cloud from your terminal and scripts.

odx is the command-line client for Odinex Cloud. If you know Hetzner's hcloud, you will feel at home: named contexts hold project API tokens, every resource has list, describe, create, update and delete, and long-running operations wait for their action and show progress.

Install

odx is written in Go. With Go 1.25 or newer:

go install odinex.cloud/odx@latest

Shell completion:

source <(odx completion bash)                 # bash
odx completion zsh > "${fpath[1]}/_odx"      # zsh
odx completion fish | source                  # fish

Authenticate with a context

odx uses a project API token (odx_…). Create one in the console under Projects → your project → API tokens, then create a context; the token is read from a hidden prompt:

$ odx context create my-project
Token: ********
Context my-project created and activated

$ odx context list
ACTIVE   NAME         ENDPOINT
*        my-project   https://api.odinex.cloud/v1

$ odx context use staging        # switch
$ odx context active             # print the active context
$ odx context delete staging

Contexts are stored in ~/.config/odx/config.toml with file mode 0600.

Settings are taken from these sources, highest precedence first:

SettingSources
context--context, ODX_CONTEXT, the active context
tokenODX_TOKEN, the context's token
endpoint--endpoint, ODX_ENDPOINT, the context's endpoint, https://api.odinex.cloud/v1
config file--config, ODX_CONFIG, ~/.config/odx/config.toml

So ODX_TOKEN=odx_… odx server list works without any configuration file, which is handy in CI.

Examples

# Catalog
odx location list
odx server-type list
odx image list --type system

# SSH key and server
odx ssh-key create --name laptop --public-key-from-file ~/.ssh/id_ed25519.pub
odx server create --name web-1 --type t1 --image ubuntu-24.04 --location fra1 \
    --ssh-key laptop --label role=web --user-data-from-file cloud-init.yaml
odx server list -l role=web
odx server describe web-1
odx server ssh web-1                      # runs: ssh -l root <ipv4>
odx server metrics --type cpu web-1       # min/avg/max/last of the last hour
odx server poweroff web-1 && odx server change-type --type t2 --upgrade-disk web-1
odx server create-image --description "before upgrade" web-1
odx server set-rdns --hostname web-1.example.com web-1

# Volume attached to the server
odx volume create --name data --size 10 --server web-1
odx volume resize --size 20 data

# Firewall applied by label
cat > rules.json <<'JSON'
[{"direction": "in", "protocol": "tcp", "port": "22", "source_ips": ["0.0.0.0/0", "::/0"]}]
JSON
odx firewall create --name web --rules-file rules.json
odx firewall add-rule --direction in --protocol tcp --port 443 --source-ips 0.0.0.0/0,::/0 web
odx firewall apply-to-resource --type label_selector --label-selector role=web web

# Floating IP
odx floating-ip create --type ipv4 --name ip-1 --location fra1
odx floating-ip assign ip-1 web-1

# Load balancer with a label target
odx load-balancer create --name lb-1 --type lb11 --location fra1
odx load-balancer add-service --protocol http --listen-port 80 --destination-port 8080 lb-1
odx load-balancer add-target --label-selector role=web lb-1

# Clean up
odx load-balancer delete lb-1
odx floating-ip delete ip-1
odx volume detach data && odx volume delete data
odx server delete web-1

Resources can be referred to by name or ID. Every command is listed in the command reference.

Output

List commands print a table. Change the format with the repeatable -o flag:

odx server list -o columns=id,name,ipv4,labels     # pick columns (see odx server list --help)
odx server list -o noheader -o columns=id          # for scripts
odx server list -o json                            # API objects as JSON
odx server describe web-1 -o yaml

-l / --selector filters by labels: env=prod, env!=prod, env, !env; commas mean AND.

Actions and waiting

Commands that start an action (create, power, attach, …) poll GET /actions/{id} and show a progress line on stderr until it finishes. --no-wait returns right after the request; odx action list and odx action describe <id> show the state later. A failed action exits with code 1 and prints the action's error code and message.

Errors and exit codes

Errors are printed as error: <message> (<code>) on stderr. The codes are those of the API.

Exit codeMeaning
0Success
1API error, failed action, network or file error
2Usage error: unknown command or flag, bad argument, missing token

--debug prints every HTTP request and response, including the rate limit headers, to stderr. When the API answers 429, odx waits for Retry-After (at most 60 seconds) and retries up to 3 times.

On this page