dystopic docs is in beta — content is actively being added.
dystopic

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 to dystopic odyssey ….

Confirm the install:

dystopic --version

Authenticate

Sign in once. The CLI persists your credentials so later steps run non-interactively.

Run dystopic auth login

dystopic auth login

With 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, login reuses your existing key and prints Already 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 status

This 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 path

Credential resolution

Every command resolves your API key from the first source that supplies one, in this exact order:

  1. --api-key flag — highest priority, per-command override.
  2. DYSTOPIC_API_KEY environment variable.
  3. OS keychain — the key saved by dystopic auth login.
  4. Plaintext config.json (mode 0600) — the fallback when no keychain was available.
  5. No key found — the command exits 2 with: 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:

  1. --base-url flag — a per-command override that wins outright.
  2. DYSTOPIC_BASE_URL environment variable.
  3. DYSTOPIC_INTERNAL_BASE_URL environment variable.
  4. base_url in your config — persisted at dystopic auth login.
  5. 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=true is set (the standard CI marker),
  • DYSTOPIC_DISABLE_KEYRING is 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.tech

Two rules keep this predictable:

  • Your shell environment always wins. .env is loaded with override=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-dotenv on 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.