Skip to content

CLI

lobbe sends meetings to Lobbe, follows them and reads their minutes, from a terminal or a script. It speaks Lobbe’s API with your personal API token, is one file with no dependencies, and needs Node.js 20 or newer.

Terminal window
npm install -g @lobbe/cli
# Paste your token when asked
lobbe login
# Send a meeting and wait until it's ready
lobbe upload meeting.m4a --wait
# Your finished meetings, and one as Markdown
lobbe list
lobbe get MEETING_ID --md
Terminal window
npm install -g @lobbe/cli

Or run it without installing: npx -y @lobbe/cli <command>. If npmjs.org is slow or unreachable from your network, add --registry with a mirror you trust.

Make a token in the app, under Connections, with the scopes you need (see Tokens and scopes), then:

Terminal window
lobbe login

lobbe login asks for the token without showing it, checks it with Lobbe, and only then stores it in ~/.config/lobbe/config.json (or $XDG_CONFIG_HOME/lobbe/config.json). The file is readable by you alone (mode 0600, in a 0700 directory). A token Lobbe refuses is never stored. The MCP server reads the same file.

  • From a script: pipe the token in with lobbe login --token-stdin.
  • Several accounts: lobbe login --profile work, then --profile work (or LOBBE_PROFILE=work) on any command.
  • Containers and CI: set LOBBE_TOKEN instead; nothing is read from or written to disk. That token goes to LOBBE_BASE_URL, or to https://app.lobbe.ai, and never to a server a stored profile names.
  • Another server: LOBBE_BASE_URL=https://lobbe.example.com lobbe login. The profile remembers the server it was checked against.

lobbe whoami shows who the token belongs to, its scopes, its daily cap and the upload limits. lobbe logout forgets a stored token; the token itself works until you revoke it in the app.

Command What it does
lobbe login Store a token on this computer, once the server accepts it
lobbe logout Forget a stored token (it still works until you revoke it in the app)
lobbe whoami Who the token belongs to: its scopes, daily cap and limits
lobbe account The account’s balance in minutes and its settings
lobbe upload <file> Send a meeting’s recording; --wait follows it until it’s done
lobbe status <id> Where a meeting is; --wait follows it until it’s done
lobbe skip-naming <id> Go ahead without naming the voices: they take Lobbe’s suggestions
lobbe retry <id> Run a FAILED meeting’s failed step again, at no new charge
lobbe list Your finished meetings, newest first
lobbe get <id> One finished meeting: its minutes and transcript, as Markdown
lobbe search <query> Find finished meetings by their words
lobbe ask <id> <question> Ask a meeting a question (--series <id>: a whole series); the price is quoted first
lobbe series The series you own or joined; also series show <id>, series create, series update <id>
lobbe keyterms The vocabulary, one term per line; keyterms set <file> replaces it
lobbe memory What Lobbe remembers about you; also memory edit <id> <text>, memory delete <id>
lobbe events What happened to your meetings since a cursor; --follow keeps watching
lobbe skill install Install Lobbe’s agent skill for Claude Code, Codex or Cursor

lobbe <command> --help lists a command’s options, and lobbe --help all of the above. Every command takes --profile <name>.

Terminal window
lobbe upload weekly.m4a --series "Weekly sync" --wait

upload checks the file before it sends anything: it must exist, be a type Lobbe takes (by its extension) and fit the token’s upload limit. It prints the meeting’s id and what it costs in minutes. Its options: --series <name|id> (a series you own), --recorded-at <iso>, --title, --kind (in a series, the series’ type wins), --language (match, fa or en), --skip-naming, --no-keyterms (leaves your vocabulary and its surcharge out) and --attach <file> (a PDF, PPTX or DOCX for the Lobbe to read too; it adds minutes). See The meeting lifecycle.

An answer costs minutes, so lobbe ask gets the price first. On a terminal it shows the price and asks you to agree. In a script, --max-minutes <n> sets a ceiling instead (a dearer answer is refused with exit 4, and nothing is charged), or --yes takes the quoted price. Off a terminal, without either, it refuses (exit 1) and says what the answer would cost.

lobbe keyterms > words.txt saves the vocabulary; lobbe keyterms set words.txt replaces it with the file’s terms (blank lines and lines that start with # are left out). A file with no terms is refused, so a failed lobbe keyterms > words.txt can’t clear the list by accident: --empty clears it on purpose. --series <id> works on a series’ own list. See Account, vocabulary and memory.

lobbe upload --wait, or lobbe status <id> --wait later, checks once a minute (or after the Retry-After Lobbe asks for) until the meeting is READY:

  • At NAMING, Lobbe is waiting for you to name the voices. The naming link is printed once, and the wait goes on until you have named them. --no-wait-naming stops there instead, with exit 3; lobbe skip-naming <id> goes ahead without names. See Speaker naming.
  • At FAILED, a failure that can recover is retried, up to 3 times. Otherwise the wait ends with exit 2. lobbe retry <id> retries one by hand.

The progress lines go to stderr, so stdout stays clean for a script.

Code Meaning
0 Success; with --wait, the meeting is READY
1 A usage error, a network failure, or any other API error
2 The meeting FAILED: not retryable, or still failed after 3 retries
3 Waiting on a person: NAMING under --no-wait-naming
4 Minutes: INSUFFICIENT_MINUTES, TOKEN_DAILY_CAP, DAILY_LIMIT_REACHED, PRICE_ABOVE_MAX
5 Not allowed: no token configured, UNAUTHORIZED, TOKEN_INVALID, TOKENS_DISABLED, TOKEN_NOT_ACCEPTED, DEVELOPER_MODE_OFF, TOKEN_SCOPE, SCOPE_DISABLED, PENDING_APPROVAL

An error prints Lobbe’s code, its message and what to do next on stderr. A token without the scope a command needs exits with 5 and names the scope. See Errors.

--json prints the API’s answer exactly as received, on every command that reads or changes something (events always prints JSON). Fields can be added within v1 (see Versioning), so read the ones you need and ignore the rest.

With --wait, upload --json prints one document when the wait ends, however it ends:

{ "submitted": { "schemaVersion": 1, "recording": { "id": "…", "minutes": 12 } },
"status": { "schemaVersion": 1, "id": "…", "status": "READY" } }

submitted is the answer to the upload and status the final status. status is null when the wait itself failed (the exit code says why), so a script never loses the id of a meeting it paid for.

lobbe events prints the events feed one event per line, as compact JSON, oldest first, then stops and prints the cursor to read on from on stderr. For a pipeline that runs for good:

Terminal window
lobbe events --after latest --cursor-file cursor.txt # once: take a cursor, from now
lobbe events --follow --cursor-file cursor.txt # then: read on, for good

--follow doesn’t stop: once caught up it checks once a minute. A network error, a server error (5xx) or a rate limit (429, 503) only pauses it, for a minute or the Retry-After, with one line on stderr, so it outlives Lobbe’s own deploys. It ends on anything else with that error’s exit code: a 4xx such as TOKEN_INVALID (exit 5), or a cursor file it can’t write.

--cursor-file keeps the cursor in a file, replaced once a page’s lines have been written to stdout. The file marks what lobbe has written, not what you have handled: a consumer that dies with lines still unread would skip them. To handle every event, append to a file and keep your own offset into it:

Terminal window
lobbe events --follow --cursor-file cursor.txt >> events.jsonl

Your consumer reads events.jsonl from its own saved offset and moves the offset on only after it has handled a line. The feed gives every event at least once (a stop between a page and its cursor repeats that page), so skip what you have handled by the event’s id. Fetch a meeting that is ready with lobbe get <id>.

Events are kept for 30 days. A cursor older than that is refused (CURSOR_EXPIRED, exit 1). Recover in this order: take a new cursor with --after latest, catch up with lobbe list, then read on with --follow. See 30 days, then 410.

lobbe sends the token in the Authorization header to the server it was stored for, or to LOBBE_BASE_URL when you set it, and nowhere else. It never prints it, in any output or error, --json included.