CLI Reference
The kodo CLI lets you manage sites, domains, backups, cron, and SSH access from your terminal. Everything available in the API is available through the CLI.
Installation
Download the latest binary for your platform from the releases page, or build from source:
$ go install github.com/koddrio/kodo@latest
Configuration
The CLI reads configuration from three sources, in order of precedence:
- Command-line flags (
--secret) - Environment variables (
KODO_SECRET) - Config file at
~/.kodo.yaml
# ~/.kodo.yaml
secret: your-api-token
org: org_7mRk2
Authentication
The recommended way to authenticate is through the login command, which opens a browser flow and saves your token to ~/.kodo.yaml:
$ kodo auth login
Opening browser for authentication...
✓ Logged in as [email protected]
$ kodo auth whoami
[email protected] (acme)
For automation and CI, you can also authenticate via environment variables or CLI flags:
# Environment variable
$ export KODO_SECRET=your-api-token
# Or CLI flag (overrides everything else)
$ kodo --secret your-api-token org list
Precedence: CLI flag > environment variable > ~/.kodo.yaml
kodo org list
List organizations you belong to. The active org is marked with a checkmark.
$ kodo org list
ID NAME
———————————————
org_7mRk2 acme ✓
org_9xPq4 widgets
kodo org use <name>
Switch the active organization. New sites will be created in this org.
$ kodo org use widgets
✓ Active org: widgets
kodo site create
Create a new WordPress site. Optionally provision from a YAML blueprint.
$ kodo site create --region lhr
Site ID site_4kR9x2mNpQw
URL https://happy-panda-042.koddrio.site
Admin user [email protected]
Admin password kX9mR2pL4qNw
! Save the admin password — it won't be shown again.
Provisioning...
- Creating containers
- Installing WordPress
✓ Site is ready.
With a blueprint:
$ kodo site create --from blueprint.yml --region dca
Flags: --region (default: dca), --from (path to YAML blueprint)
kodo site list
List all sites in the active organization.
$ kodo site list
ID STATUS
———————————————————
site_4kR9x2mNpQw active
site_8nQp3wXy2Rs active
kodo site get <site> [key]
Get site details, a config section, or a specific value. Sites can be addressed by ID, internal domain, or custom domain.
# Full site details
$ kodo site get site_4kR9x2mNpQw
# A config section
$ kodo site get mysite.com php
php.version 8.4
php.workers 4
php.memory 256
# A single value
$ kodo site get mysite.com php.workers
4
# Full config as YAML
$ kodo site get mysite.com --yaml
kodo site set <site> <key> <value>
Update a single config value. Changes that affect containers will trigger an update job.
$ kodo site set mysite.com php.workers 8
✓ php.workers = 8
Applying...
✓ Done.
kodo site default <site> <key>
Reset a config value to its default.
$ kodo site default mysite.com php.workers
✓ php.workers = 4 (default)
kodo site edit <site>
Open the site config in your $EDITOR as YAML. Save and close to apply changes. You can also edit domains and cron entries inline.
$ kodo site edit mysite.com
# Opens $EDITOR with:
php:
version: "8.4"
workers: 8
memory: 256
cache:
driver: redis
memory: 128
domains:
- name: mysite.com
primary: true
- name: www.mysite.com
cron:
- schedule: "*/5 * * * *"
command: wp cron event run --due-now
Internal keys (purge_key, cache.salt, etc.) are hidden. Cron entry IDs are stripped. Adding/removing domains triggers DNS verification.
kodo site apply <site> -f <file>
Apply a YAML config file to a site. Only changed values are sent to the API.
$ kodo site apply mysite.com -f config.yaml
✓ php.workers = 8
✓ php.memory = 512
Applying...
✓ Done.
kodo site destroy <site>
Destroy a site and all its data. Prompts for confirmation unless --yes is passed.
$ kodo site destroy mysite.com --yes
Destroying...
✓ Site destroyed.
kodo domain list <site>
List all domains attached to a site.
$ kodo domain list mysite.com
STATUS PRIMARY NAME
————————————————————
active ✓ mysite.com
active www.mysite.com
kodo domain add <site> <domain>
Add a custom domain. The CLI waits for DNS and TLS verification to complete.
$ kodo domain add mysite.com shop.example.com --primary
Name shop.example.com
Status pending
Waiting for DNS and TLS verification...
- pending-dns
- pending-tls
- active
✓ Domain is active.
✓ Domain set as primary.
Flags: --primary (make this the primary domain after activation)
kodo domain set-primary <site> <domain>
Change the primary domain for a site. The domain must be active.
$ kodo domain set-primary mysite.com shop.example.com
✓ Done.
kodo domain remove <site> <domain>
Remove a custom domain. Internal domains cannot be removed.
$ kodo domain remove mysite.com www.mysite.com --yes
✓ Domain removal queued.
kodo backup list <site>
List backups for a site, sorted by date.
$ kodo backup list mysite.com
ID STATUS SIZE DATE
——————————————————————
bkp_3xRm8 finished 245M 2026-04-06 08:00
bkp_2wQn7 finished 244M 2026-04-05 08:00
kodo backup create <site>
Create a new backup. Waits for the backup job to complete.
$ kodo backup create mysite.com
Backup ID bkp_4yTp9
Creating...
✓ Backup created.
kodo backup restore <site> <backup>
Restore from a backup. Use latest or a specific backup ID. Choose what to restore with --type.
# Restore everything
$ kodo backup restore mysite.com latest --type full
# Restore database only
$ kodo backup restore mysite.com latest --type database
# Restore files only
$ kodo backup restore mysite.com bkp_3xRm8 --type files
Types: full (default), database, files
kodo backup export <site> <backup>
Export a backup as a downloadable archive. Returns a signed URL.
$ kodo backup export mysite.com latest --type full
Exporting...
✓ Download URL:
https://backups.koddrio.com/...
kodo cron list <site>
List cron jobs for a site.
$ kodo cron list mysite.com
ID SCHEDULE COMMAND
—————————————————————————————
cron_8xRm3 */5 * * * * wp cron event run --due-now
cron_2wQn7 0 0 * * * wp cache flush
kodo cron add <site> <schedule> <command>
Add a cron job. Accepts standard cron syntax or named schedules: hourly, daily, weekly.
$ kodo cron add mysite.com daily "wp cache flush"
✓ Cron added: 0 0 * * * — wp cache flush
Applying...
✓ Done.
$ kodo cron add mysite.com "*/10 * * * *" "wp option get home"
kodo cron remove <site> <cron_id>
Remove a cron job by ID.
$ kodo cron remove mysite.com cron_2wQn7
Applying...
✓ Done.
Sending email
Every site can send email out of the box. WordPress wp_mail() — and everything built on it, like password resets, notifications, and WooCommerce receipts — is wired to a managed relay with no setup required. By default, mail is sent from noreply@<your-site>.koddrio.site.
$ kodo wp mysite.com eval 'wp_mail("[email protected]", "test", "it works");'
Custom SMTP relay
To send from your own domain — through SendGrid, Mailgun, Amazon SES, Google Workspace, or any SMTP provider — set the mail.* config. Set mail.mode to relay last: it requires the host, username, from address, and password to already be set.
$ kodo site set mysite.com mail.host smtp.sendgrid.net
$ kodo site set mysite.com mail.port 587
$ kodo site set mysite.com mail.username apikey
$ kodo site set mysite.com mail.password 'SG.xxxxxxxx'
$ kodo site set mysite.com mail.from [email protected]
$ kodo site set mysite.com mail.mode relay
The password is write-only — it is stored encrypted and never shown by kodo site get. Relays connect over STARTTLS on port 587 or 25; implicit-TLS port 465 is not supported. Make sure your from address is an authorized sending identity with your provider, or the provider will reject the message.
Revert to the built-in relay at any time:
$ kodo site set mysite.com mail.mode builtin
Delivery is asynchronous: wp_mail() returns once the message is queued, so a provider rejection surfaces as a bounce rather than a failed call. Check your provider's activity log if a test message doesn't arrive.
kodo ssh <site> [command]
Open an SSH shell to a site, or run a single command. Requires an SSH key added to your account.
# Interactive shell
$ kodo ssh mysite.com
neo@mysite:~$
# Run a command
$ kodo ssh mysite.com ls
logs public_html
# Print the SSH command (useful for scripts)
$ kodo ssh mysite.com --print
ssh -p 22 [email protected]
kodo wp <site> [args]
Run WP-CLI commands on a site. Shorthand for kodo ssh <site> wp [args].
$ kodo wp mysite.com plugin list
$ kodo wp mysite.com option get home
$ kodo wp mysite.com cache flush
kodo db <site> [query]
Open an interactive MySQL session or run a query.
# Interactive
$ kodo db mysite.com
# Run a query
$ kodo db mysite.com "SELECT count(*) FROM wp_posts"
kodo ssh-key list
List your SSH keys.
$ kodo ssh-key list
ID LABEL
————————————————
sshk_3xRm8 macbook-pro
sshk_2wQn7 ci-server
kodo ssh-key add <key>
Add an SSH public key. Accepts a key string or a path to a .pub file. The label is auto-extracted from the key comment.
# From file
$ kodo ssh-key add ~/.ssh/id_ed25519.pub
# With custom label
$ kodo ssh-key add --label "deploy key" ~/.ssh/id_ed25519.pub
The CLI rejects private keys and duplicate keys with clear error messages.
kodo ssh-key remove <key_id>
Remove an SSH key. Access is revoked immediately.
$ kodo ssh-key remove sshk_3xRm8
✓ Key removed.
kodo site ssh-key list <site>
List SSH keys attached to a single site. Site-attached keys grant shell access to that one site only — useful for giving a collaborator (a customer's developer, a freelance agency, a CI runner) access to one site without adding them to your organization.
$ kodo site ssh-key list mysite.com
ID LABEL
————————————————
sshk_8Yp4q alice@agency
sshk_5Lm2r ci-deploy
kodo site ssh-key add <site> <key>
Attach an SSH public key to a site. Accepts a key string or a path to a .pub file. The holder of the matching private key can SSH into this site only; they get no access to other sites in your organization and no organization membership.
# From file
$ kodo site ssh-key add mysite.com ~/alice.pub --label "alice@agency"
kodo site ssh-key remove <site> <key_id>
Remove a site-attached key. Access is revoked immediately.
$ kodo site ssh-key remove mysite.com sshk_8Yp4q
✓ SSH key removed.
kodo logs <site> [file]
View site logs. Defaults to the last 50 lines of all log files.
# All logs
$ kodo logs mysite.com
# Follow in real-time
$ kodo logs mysite.com -f
# Specific log file
$ kodo logs mysite.com access.log
$ kodo logs mysite.com php-errors.log
$ kodo logs mysite.com cron.log
# Last 100 lines, follow
$ kodo logs mysite.com access.log -f -n 100
Flags: -f (follow), -n (number of lines)
Log files: access.log (nginx), error.log (nginx errors), php-errors.log, cron.log
Blueprints
Blueprints are YAML files that define a site's configuration and setup commands. Use them with kodo site create --from to provision preconfigured sites.
# agency-woo-blueprint.yml
php:
version: "8.4"
workers: 8
memory: 256
cache:
driver: redis
memory: 128
environment:
WP_ENVIRONMENT_TYPE: production
backups:
frequency: hourly
retention: 30
run:
- wp plugin install woocommerce --activate
- wp plugin install wp-redis --activate
- wp theme install your-agency-theme --activate
The run section executes commands in order after WordPress is installed. If a command fails, execution stops.
Nested YAML config is flattened to dot-notation: php.version, cache.driver, etc.
Config keys
Available config keys for site set, site edit, and blueprints:
| Key | Default | Values |
|---|---|---|
| php.version | 8.3 | 8.2, 8.3, 8.4 |
| php.workers | 4 | 2 to 32 |
| php.memory | 256 | 64, 128, 256, 512, 1024 (MB) |
| php.max_execution_time | 30 | 1 to 90 (seconds) |
| php.upload_max_filesize | 64 | 2 to 1024 (MB) |
| php.post_max_size | 64 | 2 to 1024 (MB) |
| database.memory | 512 | 128, 256, 512, 1024, 2048, 4096, 8192 (MB) |
| cache.driver | none | none, redis |
| cache.memory | 128 | 64, 128, 256, 512, 1024 (MB) |
| storage.size | 10 | 10 to 400 (GB) |
| backups.frequency | daily | hourly, daily, weekly, disabled |
| backups.retention | 30 | 1 to 365 (days) |
| mail.mode | builtin | builtin, relay |
| mail.host | SMTP relay hostname (relay mode) | |
| mail.port | 587 | 1 to 65535 |
| mail.username | SMTP username (relay mode) | |
| mail.from | From address (relay mode) | |
| mail.password | SMTP password (write-only, encrypted) | |
| environment.* | Custom environment variables |
Memory values accept M and G suffixes: kodo site set mysite.com php.memory 512M
Missing something? Let us know or check the API reference for the full list of endpoints.