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.
npm install -g @lobbe/cli# Paste your token when askedlobbe login
# Send a meeting and wait until it's readylobbe upload meeting.m4a --wait
# Your finished meetings, and one as Markdownlobbe listlobbe get MEETING_ID --mdInstall
Section titled “Install”npm install -g @lobbe/cliOr 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.
Log in
Section titled “Log in”Make a token in the app, under Connections, with the scopes you need (see Tokens and scopes), then:
lobbe loginlobbe 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(orLOBBE_PROFILE=work) on any command. - Containers and CI: set
LOBBE_TOKENinstead; nothing is read from or written to disk. That token goes toLOBBE_BASE_URL, or tohttps://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.
The commands
Section titled “The commands”| 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>.
Send a meeting
Section titled “Send a meeting”lobbe upload weekly.m4a --series "Weekly sync" --waitupload 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.
Vocabulary
Section titled “Vocabulary”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.
Waiting, and the naming link
Section titled “Waiting, and the naming link”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-namingstops there instead, with exit3;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 exit2.lobbe retry <id>retries one by hand.
The progress lines go to stderr, so stdout stays clean for a script.
Exit codes
Section titled “Exit codes”| 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 for scripts
Section titled “--json for scripts”--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.
Follow the events feed
Section titled “Follow the events feed”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:
lobbe events --after latest --cursor-file cursor.txt # once: take a cursor, from nowlobbe 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:
lobbe events --follow --cursor-file cursor.txt >> events.jsonlYour 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.
The token stays secret
Section titled “The token stays secret”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.