CLI
The SaaS Custom Domains CLI lets you add your customers' domains, get the DNS records they need, check why a domain isn't live yet, and manage upstreams, redirects, rules and analytics from your terminal, scripts and coding agents. It's open source: github.com/saas-custom-domains/cli.
Install
The CLI needs Node.js 20 or newer. Run any command without installing it:
Terminal
npx @saas-custom-domains/cli domains list
Or install it, which adds the scd and saascustomdomains commands:
Terminal
npm install -g @saas-custom-domains/cli
Sign in
Terminal
scd auth login
Your browser opens. Sign in to SaaS Custom Domains (with two-factor authentication if you use it) and click Continue. The CLI saves an API token named "CLI: <your computer's name>" in ~/.config/saascustomdomains/config.json, readable only by you. The token is listed under Settings » API; delete it there to sign the CLI out everywhere.
To use an API token instead, which is the usual choice for CI and agents, set SCD_API_TOKEN, or save a token with scd auth login --with-token (it reads the token from stdin).
scd auth status shows who you're signed in as. scd auth logout removes the saved token.
Quick start
Commands take hostnames rather than UUIDs:
Terminal
scd upstreams create app.yourapp.com # the app your custom domains forward to (once)
scd domains add app.customer.com # add a customer's domain and get its DNS records
scd domains get app.customer.com # DNS and certificate status, and the records it needs
scd domains verify app.customer.com # check the DNS records now
scd domains list --status dns_records_not_found --all # who still hasn't set up DNS
If you have more than one account, pass --account <name or UUID> or set SCD_ACCOUNT.
Commands
| Command | What it does |
|---|---|
scd auth login, logout, status | Sign in with the browser or an API token, sign out, show the current user |
scd accounts list | List your accounts |
scd upstreams list, get, create, delete | Manage upstreams. get shows the auth token your app should check |
scd domains list, get, add, delete | Manage custom domains. add takes --upstream, --redirect-to-www, --challenge-type, --instructions-recipient and --prepend-path |
scd domains verify, dns-records, purge-cache | Check DNS now, show the DNS records a domain needs, purge its HTTP cache |
scd redirects list, get, create, update, delete | Manage redirects |
scd rules list, create, delete | Manage rules on a domain (--domain) or an upstream (--upstream) |
scd certificates list, delete | Manage certificates uploaded in the dashboard |
scd analytics <host> | Requests, data transfer and response codes; --web for visitors, pageviews and top pages. Needs the Domain Analytics add-on |
scd api <method> <path> | Call any API endpoint, with the path relative to /api/v1, and print the JSON response |
scd skills install | Install the agent skill for your coding agent |
scd commands --json | Every command, argument and option, for agents |
Run scd <command> --help for all options.
scd upstreams delete refuses an upstream that still has custom domains, because deleting it would delete them too.
Scripts, CI and agents
- Add
--jsonto any command for JSON on stdout. Messages go to stderr. With--json, errors are printed to stderr as{"error": {"status": 404, "message": "..."}}. - Deleting asks for confirmation in a terminal. Without one, or with
--no-input, it fails unless you pass--yes. - The API rate limits apply. On a
429, the CLI says when to retry.
| Exit code | Meaning |
|---|---|
| 0 | Success |
| 1 | Error |
| 2 | Bad usage, or input needed (for example --yes) |
| 4 | Not signed in, invalid token, or no access |
| 5 | Not found |
| 6 | Rate limited |
For example, in CI:
Terminal
SCD_API_TOKEN=$SCD_API_TOKEN npx @saas-custom-domains/cli domains add "$CUSTOMER_DOMAIN" --upstream app.yourapp.com --json
Test locally with scd-mock
scd-mock runs the API and proxy locally, so you can try the CLI without an account:
Terminal
export SCD_API_URL=http://localhost:4010/api/v1 SCD_API_TOKEN=scd_test_token SCD_ACCOUNT=acc_local
scd domains add acme.localhost --upstream localhost
CLI, MCP server or API?
- CLI: your terminal, shell scripts, CI, and coding agents that run commands.
- MCP server: chat assistants and agents that connect to tools, such as claude.ai, ChatGPT and Cursor.
- REST API: your app's own code, for example adding a domain when a customer saves it in their settings.
All three use the same API token and the same permissions.