Authentication

district login stores one session per environment. Sessions for different environments coexist. A second login for the same environment replaces the stored session. Each session names one organization, and district org select changes it.

district login

district login [--production | --staging | --dev] [--api <origin>] [--no-browser] [--organization <id>]

Runs the device authorization grant (RFC 8628). The command prints a URL and a code, opens the URL in the browser, waits for the confirmation, selects an organization, and stores the session. It then records the environment as the current environment: every later command that takes no remote URL uses it when no environment flag is passed.

District creates an organization for every account shortly after sign-up. For an account created shortly before login, the organization list can be empty. The command then waits under the indicator Preparing the account: it reads the list again every 2 seconds for up to 60 seconds, and continues with the selection rules below as soon as the list contains an organization. After 60 seconds it prints This account has no organization yet. District creates one shortly after sign-up. Run district login again in a minute, or open the District dashboard once to finish setting up the account., stores no session, and exits 1.

Flags

FlagDescriptionDefault
--production | --staging | --devThe environment to sign in to. Pass one at most.production
--api <origin>A district-api origin for --staging or --dev: a preview deployment or a second local API. The value must be an http or https origin with no path.the environment's origin
--no-browserPrints the URL and opens nothing.false
--organization <id>The organization to act in, by id or by name. Without it, the selection rules below apply: one organization is selected without asking, and several prompt on a terminal and fail without one.-

Each environment has a default district-api origin:

EnvironmentOrigin
productionhttps://api.platform.district.net
staginghttps://api.platform.district-staging.net
devhttps://api.platform.district.net.test (placeholder: pass the checkout origin from slot/status with --api)

--api applies to --staging and --dev. The override is stored with the environment. A later login for the same environment without --api removes it. The command rejects --api with production, because that origin is constant.

Output

$ district login --staging
Open https://…/device and confirm the code XVGT-PBQF.
Logged in to staging as khoi@example.com in District Inc (org_01K2…)

The command prints Open the URL above in a browser. when the browser launcher exits non-zero. The first login also offers the companion choice once, and Enter skips it.

Exit codes

Exit codeMeaning
0The session is stored.
1The confirmation was refused or expired, the account has no organization after 60 seconds, several organizations are available and no terminal can select one, or WorkOS answered with a token that names another organization. No session is stored.

district org list

district org list [--production | --staging | --dev]

Prints one line per organization the session can act in, in ascending name order, with * on the organization the session is scoped to. The lines go to stdout. An account that belongs to no organization prints one sentence to stderr, so stdout stays empty when piped.

Flags

FlagDescription
--production | --staging | --devThe environment to act in. Pass one at most. Without a flag, the command uses the environment that the last district login recorded, or production.

Output

$ district org list
  Acme Supply (org_01K2…)
* District Inc (org_01K2…)

Exit codes

Exit codeMeaning
0The list was printed. An account with no organization also exits 0.
1The session is gone or was refused, or district-api did not answer.

district org select

district org select [<organization>] [--production | --staging | --dev]

Changes the organization the session acts in. The command exchanges the stored refresh token, so it needs no second browser confirmation. It prints Now acting in <name> (<id>) to stderr.

Arguments

ArgumentDescription
[<organization>]The organization to act in, by id or by name. Without it, the selection rules below apply.

Flags

FlagDescription
--production | --staging | --devThe environment to act in. Pass one at most. Without a flag, the command uses the environment that the last district login recorded, or production.

Output

$ district org select "Acme Supply"
Now acting in Acme Supply (org_01K2…)

Exit codes

Exit codeMeaning
0The session now names the organization.
1No organization was selected after three attempts, the argument names no organization or several, several organizations are available and no terminal can select one, or the session is gone or was refused.

district org create

district org create <name> [--production | --staging | --dev]

Creates another organization, in addition to the one District creates for every account at sign-up, makes the caller its Owner with a General workspace, and switches the session to it. The command needs a signed-in session for the environment; the organization that session names does not matter. The command prints the name and the org_ id on stdout, and Now acting in <name> (<id>) on stderr. A request that district-api answered 503 or did not answer is repeated with the same creation key, so a repeat cannot create a second organization.

Arguments

ArgumentDescription
<name>The organization name, 1 to 120 characters after trimming. Organization names are not unique.

Flags

FlagDescription
--production | --staging | --devThe environment to act in. Pass one at most. Without a flag, the command uses the environment that the last district login recorded, or production.

Output

$ district org create "Acme Supply"
created Acme Supply (org_01K2…)
Now acting in Acme Supply (org_01K2…)

Exit codes

Exit codeMeaning
0The organization exists and the session names it.
1district-api refused the name, did not finish the create after three attempts, or the session is gone or was refused.
2The command line names two environments.

Selecting an organization

district login and district org select apply these rules:

  • The command selects the one organization without a prompt.
  • The command prompts for an organization when stderr is a terminal and several organizations are available. The prompt asks for a number and accepts three attempts.
  • --organization <id> on district login, or the positional argument of district org select, selects one without a prompt. An id or a name is accepted.
  • Several organizations and no terminal is a failure. The message names the exact command that selects one, with the flag of the environment, such as district login --staging --organization <id>. This applies to every session with no terminal, including a CI job.
  • An account with no organization fails with This account has no organization yet. District creates one shortly after sign-up. Run district login again in a minute, or open the District dashboard once to finish setting up the account.. district login waits up to 60 seconds for the organization that sign-up creates first; district org select fails at once.

district whoami

district whoami [--production] [--staging] [--dev] [--offline]

Shows the values that the credential helper would use. For each environment it prints one block: the email of the stored session, the organization the session is scoped to, the access-token expiry, the district-api origin with (default) or (override from config), the WorkOS client id, and the answer of a live viewer query against district-api. An environment with no session prints one session: line with the district login hint for it. The header of the current environment ends with (current).

Flags

FlagDescriptionDefault
--production, --staging, --devThe environments to report. Any combination. Without a flag, the command reports every environment.-
--offlineSkips the district-api call and reports the stored state only.false

Output

$ district whoami --staging --offline
staging (current)
  session:      khoi@example.com
  organization: org_01K2…
  access token: expires 2026-08-29T18:40:00Z (in 54 min)
  api origin:   https://api.platform.district-staging.net (default)
  workos app:   client_01M0VXCE6XT24NPJZGAAEJ97N5

Exit codes

Exit codeMeaning
0Every block was printed. An environment with no session is not a failure.
1A live call failed for an environment that has a session. Every block is printed first.