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

# CLI Authentication

Log in from the terminal with a browser-based device flow or an API key. Works in CI, on remote servers, and in local dev.

The hookstream CLI authenticates with an **API key**. You can either grab a key through the browser device flow (recommended for humans) or pass one directly via a flag, env var, or config file (recommended for scripts and CI).

## Browser login (recommended)

`hookstream login` starts a device flow against https://hookstream.io/dashboard/cli-auth. A short, readable code is shown in your terminal and pre-filled in the browser — you approve once and the CLI picks up the key automatically.

**Run hookstream login**

```bash
hookstream login
```

**Copy the code and approve in the browser**

The CLI prints an 8-character code (like `ABCD-EFGH`) and opens your browser to `https://hookstream.io/dashboard/cli-auth?code=ABCD-EFGH`. Confirm the code matches, then approve.

The code alphabet excludes `O/0/I/1/L` to avoid ambiguity. Codes expire after 15 minutes.

**CLI receives the key**

The CLI polls the auth endpoint every 5 seconds and saves the key to `~/.config/hookstream/config.json` once you approve. No copy-pasting.

```
Logged in as hs_live_d82e...
Config saved to ~/.config/hookstream/config.json
```

**First-run wizard (optional)**

If you have no sources yet, the CLI asks whether you want to create one. It runs a 2-question wizard (name + provider template) and prints your ingest URL plus a ready-to-run `curl` command. Skip with `--no-wizard`.

### Login flags

Don't auto-open the browser. Prints the code and URL so you can open it manually — useful on remote servers or over SSH.

Skip the first-run onboarding wizard after login.

Prompt for an API key in the terminal instead of using the browser flow. Falls back to this automatically if the device-auth endpoint is unreachable.

Skip the flow entirely and save a key you already have.

Authenticate against a non-default hookstream instance (staging, self-hosted).

```bash
# Headless / remote server — don't try to open a browser
hookstream login --no-browser

# Script mode — save a known key without prompts
hookstream login --api-key hs_live_abc123...

# Interactive fallback if something breaks
hookstream login -i
```

## API key auth

You can bypass the login flow entirely and pass an API key directly. This is how you'd use the CLI in CI/CD.

### Precedence

The CLI checks sources in this order, highest wins:

| Priority | Source | Use case |
|---|---|---|
| 1 | `--api-key <key>` flag | Per-command override |
| 2 | `HOOKSTREAM_API_KEY` env var | CI/CD, scripts, session override |
| 3 | `~/.config/hookstream/config.json` | Persistent default from `hookstream login` |

### Per-command flag

Override the stored key for a single command:

```bash
hookstream sources list --api-key hs_live_abc123...
```

### Environment variable

Ideal for CI. Set the var once, run many commands:

```bash
export HOOKSTREAM_API_KEY=hs_live_abc123...
hookstream sources list
hookstream events list --limit 10
```

### Key format

hookstream API keys follow this format:

- **Live**: `hs_live_<64 hex characters>`
- **Test**: `hs_test_<64 hex characters>`

The plaintext key is shown **once** at creation. hookstream stores only the SHA-256 hash for verification — you cannot recover a lost key. Create and rotate keys in the dashboard at **Settings → API Keys**, or read more about the key model on the [API authentication](/api/authentication) page.

## Logout

Clear the stored API key and base URL:

```bash
hookstream logout
```

This removes `api_key` from `~/.config/hookstream/config.json`. The file itself stays behind.

## whoami

Verify which user, org, and project your current key resolves to:



## Scripting tips

Add `--json` to any command for clean, machine-readable output you can pipe into `jq`:

```bash
hookstream --json sources list | jq '.sources[] | .name'
hookstream --json events get evt_abc | jq '.event.payload'
```

## Troubleshooting

**"Not authenticated"**

No API key was found in any source. Run `hookstream login`, or set `HOOKSTREAM_API_KEY`, or pass `--api-key`.

**"Authentication failed"**

The key is malformed or was revoked. Verify the format (`hs_live_` or `hs_test_` + 64 hex chars), then create a new key in the dashboard at **Settings → API Keys**.

**"Authorization timed out"**

You didn't approve the device code within 15 minutes, or the browser tab never opened. Run `hookstream login` again — or `hookstream login --no-browser` if you're on a headless machine and need to copy the URL manually.

**Unexpected resources / wrong project**

Your key is probably bound to a different project than you expect. Run `hookstream whoami` to confirm, and create a project-scoped key in the dashboard if needed.

**Browser opens but nothing happens after approval**

The CLI polls every 5 seconds. Wait up to 10 seconds after approving. If it still hangs, the local clock may be wrong (affects TLS) or a corporate proxy may be blocking the poll — try `--no-browser` and verify the URL in the terminal matches what's in the browser.

## Related

**[API authentication](/api/authentication)**

How the server verifies API keys and sessions.
  **[API keys](/api/api-keys)**

Create, list, and revoke keys via API.