CLI
The `routess` command-line interface.
routess is the official CLI. It wraps the same REST API the web app uses and is the entry point for agents and CI to read and edit routes without a browser.
Install
npm install -g routessThe binary is routess. It requires Node 20+ (the published bundle is ESM).
Authenticate
The CLI talks to the API with a Personal Access Token (PAT). Mint one in the web app under Settings -> API Tokens, then either log in once or pass the token via env var.
# Interactive: persists the token to ~/.config/routess/auth.json (mode 0600).
routess auth login --token routess_pat_...
# Stateless: skip local storage. Useful for CI and ephemeral containers.
export ROUTESS_TOKEN=routess_pat_...ROUTESS_TOKEN takes precedence over the on-disk file. Token storage follows the XDG convention: $XDG_CONFIG_HOME/routess/auth.json when set, otherwise ~/.config/routess/auth.json.
Point at a different API with ROUTESS_API_URL or the --api-url flag at login time. The default is https://api.routess.com.
routess auth whoami # confirm you're signed in
routess auth logout # delete the on-disk tokenCommands
Add --json to any command for machine-readable output. Errors in --json mode emit a DomainErrorPayload on stderr that mirrors the API's error shape, so agents can branch on code directly.
Routes
routess routes list --limit 20 --offset 0 # your routes, newest first
routess routes public # indexable public routes (no auth needed)
routess routes get <id>
routess routes gpx <ref> -o ride.gpx # download GPX; <ref> is an id or a 32-hex share token
routess routes create --from route.json # CreateRoute JSON payload; "-" reads stdin
routess routes import ride.gpx --name "Sunday loop" --activity cycling
routess routes update <id> --name "New name" --description "..." --tags gravel,hilly
routess routes update <id> --visibility public --confirm
routess routes favourite <id> # and unfavourite
routess routes delete <id> --confirmlist and public print showing X of Y from the X-Total-Count header and accept --limit / --offset. import takes the same --activity ids as the API (cycling, running, hiking, ...) and defaults to a private route; an empty --description or --tags value clears the field.
Collections
routess collections list
routess collections get <ref>
routess collections create --name "Alps 2026" --visibility unlisted
routess collections update <id> --name "New name"
routess collections set-routes <id> --routes id1,id2,id3
routess collections delete <id> --confirmset-routes replaces the full ordered membership (an empty value empties the collection). Deleting a collection keeps the routes inside it.
Loop generation
routess generate --start 50.8467,4.3525 --activity cycling --distance 40
routess generate ... --heading n --surface gravel --gpx-dir ./candidates
routess generate ... --save 2 --name "Generated loop"Generation needs no auth (with a token it counts against your account's daily generation allowance instead of the per-IP one) and prints up to three scored candidates with bearing, distance, duration, overlap, and surface mix. --gpx-dir writes each candidate as candidate-<n>.gpx; --save [n] stores candidate n (default 1) as a private route in the library, which needs a write token. --exclude-bearings regenerates fresh shapes, mirroring the web app's "Show different loops".
Tokens and account export
routess tokens list # metadata only, plaintext is never shown
routess tokens revoke <id>
routess export -o my-data.zip # routess-export.json plus one GPX per routeRevoking the token the CLI is currently authenticated with locks you out, so it requires --confirm.
Confirm gates
Destructive or outward-facing operations require an explicit --confirm: deleting routes or collections, setting any visibility to public, and revoking the active token. Without it the CLI exits with code 9 (precondition required).
Exit codes
The CLI uses a stable exit-code taxonomy aligned with the API's domain error codes. Agents branch on these the same way regardless of whether the failure happened locally or came back from the server.
| Code | Meaning |
|---|---|
| 0 | OK |
| 1 | Generic / unknown error |
| 2 | Usage error |
| 3 | Validation failed |
| 4 | Not found |
| 5 | Unauthorized (no token, or token rejected) |
| 6 | Forbidden (token lacks the required scope) |
| 7 | Conflict |
| 8 | Rate limited |
| 9 | Precondition required |
| 10 | Network error |
| 11 | Internal server error |
Scopes
PATs carry one of two scopes: read (GET endpoints, including the account export) or write (mutating endpoints: POST, PATCH, DELETE). The CLI surfaces a FORBIDDEN (exit code 6) when you try to mutate a route with a read-only PAT; mint a write-scoped token in the web app and re-authenticate.
Public surfaces work without any token: routes public, routes gpx / collections get on public or share-token refs, and generate (without --save).
See the API reference for the full endpoint list and per-endpoint scope requirements.