ListenHubSDKs & CLI
CLI

Authentication

Log in with browser OAuth for interactive use, or configure an API key for scripts and CI — and switch between them.

The CLI authenticates two ways, mapped to two command namespaces:

  • OAuth loginlistenhub auth login opens your browser, signs you in as a ListenHub user, and stores a refreshable token. Bare commands (listenhub podcast …, listenhub tts …) run as that user.
  • API key — a lh_sk_… key authenticates the listenhub openapi … commands. You set it through an environment variable or a stored config file. This is the mode for servers, scripts, and CI.

The two modes use separate credential files and never interfere with each other. You can have both configured at once.

OAuth loginAPI key
Set up withlistenhub auth loginlistenhub openapi config set-key or LISTENHUB_API_KEY
Used bybare commands (listenhub <cmd>)listenhub openapi <cmd>
Acts asthe signed-in userthe key owner
Stored at~/.config/listenhub/credentials.json~/.config/listenhub/openapi.json (or env var)
Best forinteractive work on your own machinescripts, CI/CD, automation

Both credential files live under ~/.config/listenhub/. If XDG_CONFIG_HOME is set, the CLI uses $XDG_CONFIG_HOME/listenhub/ instead. Files are written with 0600 permissions (owner read/write only).

OAuth login

Use OAuth when you are working interactively on a machine you control. Nothing long-lived gets baked into a script — the CLI holds a short-lived access token plus a refresh token, and renews automatically.

Log in

listenhub auth login

This runs a one-time browser flow:

The CLI starts a temporary callback server on a random local port (127.0.0.1) and opens your default browser to the ListenHub login page.

You sign in (and authorize, if prompted) in the browser. ListenHub redirects back to the local callback with an authorization code.

The CLI exchanges the code for tokens, writes them to ~/.config/listenhub/credentials.json, and prints the account it logged in as:

✓ Logged in as Ada Lovelace

The browser flow has a 5-minute timeout. If you do not finish signing in within that window, the command aborts with Login timed out after 5 minutes — rerun listenhub auth login to try again. If the browser does not open on its own, the login URL is printed to the terminal; open it manually.

Check status

listenhub auth status
✓ Logged in as Ada Lovelace
  Email:      ada@example.com
  Expires at: 2026-07-01T12:00:00.000Z

status calls the API with your current token to confirm it is still valid. Add --json for a machine-readable form:

listenhub auth status --json
{
  "loggedIn": true,
  "user": "Ada Lovelace",
  "email": "ada@example.com",
  "expiresAt": "2026-07-01T12:00:00.000Z"
}

If you are not logged in, or the token has expired and cannot be used, status reports that and exits with a non-zero code:

{ "loggedIn": false }

Log out

listenhub auth logout

This revokes your refresh token on the server, then deletes the local credentials.json:

✓ Logged out

If the remote revoke call fails (for example, you are offline), the CLI prints a warning and still clears the local credentials, so the machine is left signed out either way.

Token storage and refresh

credentials.json holds the access token, the refresh token, and an expiresAt timestamp. You do not refresh tokens manually — the CLI renews the access token from the refresh token as needed while you run commands. The file is written atomically (temp file then rename) with 0600 permissions.

Treat credentials.json like any other secret. It grants access to your ListenHub account until you run listenhub auth logout or the refresh token is revoked.

API key

Use an API key when commands run somewhere you cannot complete a browser flow — CI pipelines, cron jobs, servers. API-key auth drives the listenhub openapi … namespace.

Create a key at listenhub.ai/settings/api-keys. Keys start with lh_sk_.

There are two ways to supply the key. The environment variable always takes precedence over the stored file.

Environment variable

Set LISTENHUB_API_KEY in your shell or CI secrets:

export LISTENHUB_API_KEY="lh_sk_your_key_here"
listenhub openapi speakers list --language en

This is the recommended approach for CI/CD: keep the key in your platform's secret store and inject it as an environment variable. Nothing is written to disk.

Stored config

For repeated local use, store the key once:

listenhub openapi config set-key

The command prompts for the key (input goes to stderr, so it stays out of piped output), validates that it starts with lh_sk_, and writes it to ~/.config/listenhub/openapi.json with 0600 permissions. It then echoes a masked confirmation:

✓ API Key saved (lh_sk_***)

A key that does not start with lh_sk_ is rejected before anything is saved:

✗ Invalid API Key format. Must start with "lh_sk_".

Inspect and clear

Check which key is active and where it comes from:

listenhub openapi config show
✓ API Key configured (source: env)
  Key ID: lh_sk_***

The source is env when LISTENHUB_API_KEY is set, or file when the key comes from openapi.json. The full key is never printed — only the masked lh_sk_*** prefix. Add --json for scripting:

listenhub openapi config show --json
{ "source": "env", "keyId": "lh_sk_live" }

If no key is configured, show reports that and exits non-zero.

Remove the stored key (this clears the file only; it does not unset an environment variable):

listenhub openapi config clear
✓ API Key cleared

An API key is a long-lived secret tied to your account. Never commit it to source control or paste it into shared logs. Prefer LISTENHUB_API_KEY from a secret store in CI; use stored config only on machines you control.

Which mode should I use?

  • Working interactively on your own machine → OAuth login. You avoid keeping a long-lived key on disk, and commands run as you.
  • Scripts, CI/CD, servers → API key via LISTENHUB_API_KEY. It works without a browser and slots into secret managers.

The two are independent. A common setup is OAuth login for day-to-day terminal work plus an API key in CI — both can be configured on the same machine without conflict.

Troubleshooting auth errors

The CLI uses exit code 2 for authentication failures, so scripts can distinguish "not authorized" from other errors (1 = general error, 3 = timeout). Errors are written to stderr.

Common cases and fixes:

SymptomCauseFix
No API Key configuredNeither LISTENHUB_API_KEY nor a stored key is setRun listenhub openapi config set-key, or export LISTENHUB_API_KEY
Invalid API Key format. Must start with "lh_sk_"The key you entered has the wrong prefixCopy a fresh key from settings/api-keys; keys start with lh_sk_
Not logged in (token expired or invalid) from auth statusOAuth token expired or was revokedRun listenhub auth login again
An openapi command fails with an auth error despite config set-keyLISTENHUB_API_KEY is set to a stale/wrong value and overrides the fileunset LISTENHUB_API_KEY (env wins over stored config), or fix the variable
Login timed out after 5 minutesBrowser flow not completed in timeRerun listenhub auth login and finish signing in promptly

To confirm what the CLI currently sees:

listenhub auth status            # OAuth session
listenhub openapi config show    # API key source (env vs file)

Next steps

On this page