Install & authenticate
Install the SDK/CLI, sign in, and resolve your API key and base URL so every step of the flow can reach the platform.
Every step that follows — porting your agent, registering it, running checks — talks to the platform through the dystopic and odyssey command-line tools shipped by dystopic. This page gets those tools installed, authenticates you once, and explains exactly how the CLI resolves your API key and base URL so you never have to guess where a command is pointed.
The CLI and SDK target the API at https://api.pipelines.tech — the default base URL every command uses and where your API key authenticates. The dashboard, review pages, and app install live at https://platform.pipelines.tech, and the deep links the API returns (trace and review URLs) point there.
Install
Install dystopic with the odyssey extra. The base package is httpx-only; the odyssey extra pulls in the agent-hosting toolkit (pydantic, python-dotenv, fastapi) that every command in this flow needs.
pip install 'dystopic[odyssey]'Requires Python 3.10 or newer. If you run a dystopic odyssey … command without the extra installed, the CLI stops and prints exactly this hint: The dystopic odyssey commands require the odyssey extra: pip install 'dystopic[odyssey]'.
Installing gives you two console scripts:
dystopic— the platform CLI (auth,config,whoami,health, …).odyssey— the agent lifecycle CLI (odyssey init,odyssey push,odyssey ci review, …). Equivalent todystopic odyssey ….
Confirm the install:
dystopic --versionAuthenticate
Sign in once. The CLI persists your credentials so later steps run non-interactively.
Run dystopic auth login
dystopic auth loginWith no --api-key, this starts a browser sign-in. The CLI opens https://platform.pipelines.tech (or prints the verification URL if it can't open a browser), you approve the session, enter the verification code shown in your terminal, and the CLI polls until the platform mints a fresh API key.
Prefer to paste an existing key instead? Pass it directly:
dystopic auth login --api-key pk_live_...Other flags:
--no-browser— don't open a browser; print the verification URL and poll (headless machines, SSH sessions).--force— mint a new key even if a valid saved key already exists. By default,loginreuses your existing key and printsAlready logged in as you@example.com. Reusing your existing API key (use --force to mint a new one).
Confirm you're signed in
dystopic auth statusThis calls the API with the resolved key and reports who you are. dystopic whoami and dystopic health are quick companions — the first prints the user behind the current key, the second checks API reachability.
On success, login saves your base_url, api_key, org_id, and email to the config file and prints Login complete. Saved Dystopic API key for future CLI/SDK calls.
Where credentials are stored
The CLI never leaves your key in plaintext if it can help it. On save, it tries the OS keychain first (the dystopic service, keyed by base URL). If the keychain write succeeds and reads back, the plaintext copy is dropped from the config file. If no keychain is usable, it falls back to the config file with mode 0600 and warns on stderr:
warning: OS keychain unavailable; storing API key in /Users/you/.config/dystopic/config.json (mode 0600).The config file lives at ~/.config/dystopic/config.json (override with DYSTOPIC_CONFIG_FILE). Inspect it any time:
dystopic config show # api_key is masked, tagged (OS keychain) or (plaintext file)
dystopic config path # print the resolved config file pathCredential resolution
Every command resolves your API key from the first source that supplies one, in this exact order:
--api-keyflag — highest priority, per-command override.DYSTOPIC_API_KEYenvironment variable.- OS keychain — the key saved by
dystopic auth login. - Plaintext
config.json(mode0600) — the fallback when no keychain was available. - No key found — the command exits
2with:Missing DYSTOPIC_API_KEY. Set it as an environment variable, CLI flag, or run dystopic auth login.
The keychain and config are keyed by base URL. A saved plaintext key is migrated into the keychain automatically the next time you run a command against the same host — but only after the keychain write is verified by reading it back.
Base-URL resolution
The base URL points the CLI at a host. It resolves independently of the key, again first-match-wins:
--base-urlflag — a per-command override that wins outright.DYSTOPIC_BASE_URLenvironment variable.DYSTOPIC_INTERNAL_BASE_URLenvironment variable.base_urlin your config — persisted atdystopic auth login.https://api.pipelines.tech— the production default.
A URL is the only way to retarget the CLI; there is no named-environment alias. To point at a local backend for one command:
dystopic auth status --base-url http://localhost:8000--base-url is position-independent — dystopic auth login --base-url URL is normalized to log into that host rather than silently saving production credentials.
Keyring in CI and headless environments
The OS keychain is deliberately disabled — reads and writes become no-ops and the CLI falls back to the plaintext 0600 config file — whenever any of these hold:
CI=trueis set (the standard CI marker),DYSTOPIC_DISABLE_KEYRINGis set (explicit opt-out),- you're on Linux with no
DBUS_SESSION_BUS_ADDRESS(a headless box with no keyring daemon).
In CI you almost always want to skip the config file entirely and supply the key by environment variable. Set DYSTOPIC_API_KEY as a secret; it sits at priority 2, above the keychain and config, so no dystopic auth login is needed in the pipeline.
.env autoload
Before a command parses its arguments, the CLI looks for a .env file in the current working directory and loads it. This is handy for keeping DYSTOPIC_API_KEY / DYSTOPIC_BASE_URL out of your shell history during local development.
# .env in your repo root
DYSTOPIC_API_KEY=pk_live_...
DYSTOPIC_BASE_URL=https://api.pipelines.techTwo rules keep this predictable:
- Your shell environment always wins.
.envis loaded withoverride=False, so any variable already exported in the shell takes precedence over the file. The effective precedence is: flags → shell env →.env→ config file → defaults. - Opt out with
--no-dotenvon any command to skip the file entirely.
.env loading depends on python-dotenv, which ships with the [odyssey] extra you installed above; without it, autoload is a silent no-op.
Managing and clearing credentials
dystopic config set base_url https://api.pipelines.tech # set a single key
dystopic config unset base_url # remove one key
dystopic config clear # delete the config file
dystopic logout # remove the saved key (keychain + config)dystopic logout --keep-base-url clears only the API key, leaving base_url, org_id, and email in place.
Next
You're authenticated and every command knows where to point. Continue to 1 · Port your agent to wrap your agent so the platform can dispatch to it.
For the full command surface, flags, and this precedence table in one place, see the CLI reference.
Core concepts
The five load-bearing nouns — agent, world, suite, check, finding — and how they compose into a regression review.
1 · Port your agent
Wrap your existing agent as a sandbox/code agent, route its tool calls through the Odyssey proxy, and run it locally before you register it on the platform.