> ## Documentation Index
> Fetch the complete documentation index at: https://docs.holydocs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# holydocs login

Authenticate the HolyDocs CLI using a browser-based device flow. Also covers logout, whoami, and the first-run onboarding wizard.

## Usage

```bash
holydocs login [options]
```

Authenticates the CLI by opening a browser, walking you through a one-time device authorization, and saving the issued API key to `~/.holydocs/config.json`. Once authenticated, commands like `deploy` and `status` work without additional credentials.

The default flow is **browser-based**. For CI and other headless environments, you can skip it with `--api-key` or by setting `HOLYDOCS_API_KEY`.

## How It Works

`holydocs login` uses a device authorization flow inspired by RFC 8628:

**Request a device code**

The CLI calls the API and receives a short user code (e.g. `8ZYW-NCPC`) plus a hidden device code used for polling.
  **Open the browser**

The CLI prints the user code and opens your default browser to `https://app.holydocs.com/device?code=8ZYW-NCPC` — the code is pre-filled in the URL so you don't need to type it.
  **Sign in and authorize**

If you're already signed into the dashboard, the page authorizes the CLI immediately. If not, you sign in once and the page bounces back to the authorization step automatically.
  **Receive the key**

The CLI is polling in the background. As soon as the dashboard authorizes, the CLI receives a write-scoped API key (90-day expiry) and saves it to `~/.holydocs/config.json`.

The user-code alphabet excludes visually ambiguous characters (`O`, `0`, `I`, `1`, `L`) so you can read the code over the phone or off a screenshot without errors.

## Options

| Option | Description | Default |
|---|---|---|
| `--api-key <key>` | Skip the browser flow — pass an API key directly. Best for CI, scripts, and headless environments. | — |
| `--no-browser` | Don't try to open a browser. The verification URL and code are still printed so you can open them manually (useful over SSH). | Browser opens |
| `--no-wizard` | Skip the first-run onboarding wizard after a successful login. | Wizard runs if you have zero projects |
| `--api <url>` | Override the API base URL (for staging/self-hosted). | `https://api.holydocs.com` |
| `-k, --key <key>` | _Deprecated alias for `--api-key`. Kept for backwards compatibility._ | — |

## Examples

### Default — browser flow

```bash
holydocs login
```

Output:

```
HolyDocs Authentication

Open this URL in your browser to authorize the CLI:

  https://app.holydocs.com/device?code=8ZYW-NCPC

Or visit https://app.holydocs.com/device and enter this code:

  8ZYW-NCPC

⠋ Waiting for browser authorization…
✓ Browser authorization complete.
✓ Authenticated as sean@example.com
```

The CLI keeps polling until you authorize in the browser or 15 minutes elapse.

### Headless / SSH / containers

```bash
holydocs login --no-browser
```

The CLI prints the URL and code but doesn't try to spawn a browser. Open the URL on any device that has access to the dashboard — phone, laptop, anything — and authorize there.

### CI / scripting

```bash
holydocs login --api-key hd_xxxxxxxxxxxxxxxxxxxx
```

Bypasses the device flow entirely. Use this in CI pipelines and scripts. Create API keys in the dashboard at [app.holydocs.com/settings/api-keys](https://app.holydocs.com/settings/api-keys).

If you do not want CI to write `~/.holydocs/config.json` at all, set environment variables instead and skip `login` entirely:

```bash
export HOLYDOCS_API_KEY=hd_xxxxxxxxxxxxxxxxxxxx
export HOLYDOCS_PROJECT=proj_abc123
holydocs deploy --no-watch
```

### Custom API endpoint

```bash
holydocs login --api https://api.staging.holydocs.com
```

The custom URL is persisted in your local config. Subsequent commands use it automatically.

## API Key Format

API keys issued by HolyDocs use the `hd_` prefix followed by a 32-character random suffix:

```
hd_a1b2c3d4e5f67890a1b2c3d4e5f67890
```

Keys issued by the device flow are write-scoped and expire after 90 days. Keys created manually in the dashboard can have any scope and any expiry (or none).

## What Gets Saved

After a successful login, the following fields are stored in `~/.holydocs/config.json`:

| Field | Source | Description |
|---|---|---|
| `apiKey` | API response (device flow) or `--api-key` flag | The API key for authentication |
| `email` | `/auth/me` response | Your account email |
| `orgId` | `/auth/me` response | Your organization ID |
| `apiUrl` | `--api` flag | Custom API URL (only if provided) |
| `projectId` | onboarding wizard | The project created during first-run setup, if applicable |

The CLI verifies the key by calling `/api/v1/auth/me` after saving. If the API is unreachable, the key is saved anyway for offline use and verified on the next command that contacts the API.

At runtime, `HOLYDOCS_API_KEY` and `HOLYDOCS_API_URL` override the saved config for API-backed commands.

## First-Run Onboarding Wizard

After a successful `holydocs login`, if your organization has **zero projects**, the CLI offers to create one for you:

```
Welcome to HolyDocs!
You don't have any projects yet. Let's set one up.
(Press Enter to accept defaults, or Ctrl+C to skip.)

Create a project now? (Y/n) Y
Project name (my-docs):
GitHub repo (myorg/myrepo, Enter to accept, "-" to skip):
✓ Created project "my-docs"
✓ Deployment queued (a3f9c1b2)

You're all set.

  Dashboard:  https://app.holydocs.com/projects/proj_abc123

Next steps:
  holydocs init      # scaffold docs.json + starter pages here
  holydocs dev       # local preview on http://localhost:3333
  holydocs deploy    # push your latest changes
  holydocs status    # check deployment status
```

The wizard:
- Asks at most **two questions** (project name, optional GitHub repo)
- Defaults the project name to your current directory's basename
- Auto-detects your repo from `git remote get-url origin` (supports `owner/name`, HTTPS, and SSH formats)
- Creates the project via the API
- Triggers your **first deployment as proof** if a repo is connected
- Prints next-steps with both a clickable dashboard URL and CLI equivalents

Skip the wizard with `holydocs login --no-wizard`. It also self-skips if your organization already has projects, or if `stdout` is not a TTY (CI environments).

## holydocs whoami

Check your current authentication status:

```bash
holydocs whoami
```

Output:

```
HolyDocs Auth Status

  API URL: https://api.holydocs.com
  API Key: hd_a1b2c3****
  Email:   sean@example.com
  Org ID:  org_abc123

✓ API key is valid
```

The `whoami` command displays your stored credentials (with the API key partially masked) and verifies the key against `/api/v1/auth/me`. If the key is invalid, expired, or revoked, you'll see a warning — generate a new key or run `holydocs login` again.

## holydocs logout

Clear all stored credentials:

```bash
holydocs logout
```

This removes the API key, email, org ID, and all other authentication data from `~/.holydocs/config.json`. You'll need to run `holydocs login` again before using authenticated commands.

## CI / CD

For GitHub Actions, GitLab CI, and other automated pipelines, either use the `--api-key` flag or set `HOLYDOCS_API_KEY` directly.

```yaml
# GitHub Actions
- name: Deploy docs
  run: |
    holydocs login --api-key ${{ secrets.HOLYDOCS_API_KEY }}
    holydocs deploy
```

```yaml
# GitHub Actions (ephemeral env vars, no local config writes)
- name: Deploy docs
  run: npx @holydocs/cli deploy --no-watch
  env:
    HOLYDOCS_API_KEY: ${{ secrets.HOLYDOCS_API_KEY }}
    HOLYDOCS_PROJECT: ${{ secrets.HOLYDOCS_PROJECT_ID }}
```

```yaml
# GitLab CI
deploy:
  script:
    - holydocs login --api-key $HOLYDOCS_API_KEY
    - holydocs deploy
```

Never commit API keys to version control. Always use your CI provider's secret store.

## Troubleshooting

**The browser opened but the page says 'No device code provided'**

Your terminal opened the URL without the `?code=...` query parameter. Look at the CLI output — there's a code printed below the URL (e.g. `8ZYW-NCPC`). Visit `https://app.holydocs.com/device` and enter the code manually.
  **The CLI says 'Authorization timed out'**

Device codes expire after 15 minutes. Run `holydocs login` again to get a fresh code.
  **The browser didn't open automatically**

The CLI tried to spawn `open` (macOS), `xdg-open` (Linux), or `start` (Windows). If your environment doesn't have these, copy the URL from the terminal output and open it manually. To suppress the auto-open attempt entirely, use `holydocs login --no-browser`.
  **I'm running in a Docker container / SSH session**

Use `holydocs login --no-browser` to print the URL without trying to spawn a browser, then open the URL on your local machine. The browser device flow works across machines — you don't need to authorize from the same machine the CLI is running on.
  **The wizard ran but I want to reset it**

The wizard only runs when your org has zero projects. Delete the project from the dashboard, then re-run `holydocs login --no-wizard` followed by `holydocs login` to trigger it again. Or just use `holydocs init` directly.

## Related

- [CLI Overview](/cli/overview) — All commands and global behavior
- [holydocs init](/cli/init) — Scaffold a new project locally
- [holydocs deploy](/cli/deploy) — Deploy (requires authentication)
- [API Authentication](/api/authentication) — API key scopes and the underlying authorization model