Quickstart: send a meeting
This page takes one meeting through Lobbe with curl: you make a token, send the audio, follow
its status, hand over the speakers’ names and read the Lobbe. It takes a few minutes, most of them
waiting.
1. Make a token
Section titled “1. Make a token”You make tokens in the Lobbe app, and they work only while developer mode is on.
-
In the app, open Account. Under Developers, turn on Developer mode. It is off by default; once it is on, Connections appears below it.
-
Open Connections and tap Create token, or go straight to app.lobbe.ai/connections/tokens/new.
-
Name the token. Under Meetings, tick Send meetings and keep Read, which is ticked already. Pick when it expires, then tap Create token.
-
The token is shown once. Copy it and keep it in an environment variable:
Terminal window export LOBBE_TOKEN=lobbe_…
If the form doesn’t offer Send meetings, sending meetings through a token isn’t on for your account yet. The read-only version at the end of this page works with Read alone.
2. Check the token
Section titled “2. Check the token”curl https://app.lobbe.ai/api/v1/whoami \ -H "Authorization: Bearer $LOBBE_TOKEN"The answer says who the token belongs to and what it may do:
{ "schemaVersion": 1, "owner": { "type": "user", "id": "USER_ID", "displayName": "Sara" }, "token": { "id": "TOKEN_ID", "name": "n8n office", "scopes": ["recordings:read", "recordings:write"], "dailyMinuteCap": null, "usedMinutes24h": 0, "expiresAt": "2027-01-17T09:12:00.000Z" }, "wallet": null, "limits": { "maxUploadMb": 300, "maxRecordingMinutes": 240 }}wallet is null unless the token holds account:read. limits is the largest file and the
longest meeting Lobbe takes right now: see Minutes, caps and limits. Every field
is in GET /whoami.
If this answers 401 or 403, error.code names the problem. 403 DEVELOPER_MODE_OFF means
developer mode is off. Errors lists every code.
3. Send a meeting
Section titled “3. Send a meeting”curl https://app.lobbe.ai/api/v1/recordings \ -H "Authorization: Bearer $LOBBE_TOKEN" \ -F "audio=@meeting.m4a;type=audio/mp4"The body is multipart/form-data, with the file in audio and its type after ;type=. Lobbe
answers 202:
{ "schemaVersion": 1, "recording": { "id": "MEETING_ID", "status": "QUEUED", "minutes": 42, "recordedAt": "2026-10-19T08:30:00.000Z", "statusUrl": "https://app.lobbe.ai/api/v1/recordings/MEETING_ID/status", "bundleUrl": null, "url": "https://app.lobbe.ai/m/MEETING_ID" }}Keep id. minutes is what the meeting costs, from your balance. The other fields you can send
(when the meeting happened, a title, a series, the kind of recording, the Lobbe’s language, naming)
are in POST /recordings. To send the request again
safely, without making a second meeting, add an Idempotency-Key header: see
Idempotency and retries.
Without ;type=, curl labels the file application/octet-stream. Lobbe recognizes most audio
files from their first bytes anyway, but not all: 400 VALIDATION with the message
Unsupported audio type means Lobbe couldn’t tell what the file is, so name its type. The accepted files and their types are listed in
Minutes, caps and limits.
4. Wait for it
Section titled “4. Wait for it”Ask for the status about once a minute:
curl https://app.lobbe.ai/api/v1/recordings/MEETING_ID/status \ -H "Authorization: Bearer $LOBBE_TOKEN"status moves through these values, in this order:
status |
What is happening |
|---|---|
QUEUED |
Lobbe has the audio, and the meeting is waiting its turn |
TRANSCRIBING |
The audio is being transcribed |
NAMING |
Waiting for the speakers’ names. Not every meeting stops here |
GENERATING |
The Lobbe is being written |
READY |
Done: read it |
FAILED |
It stopped. error.code says why, and error.retryable says whether POST /recordings/{id}/retry can help |
FAILED isn’t always the end: Lobbe retries a failed step by itself after a short wait, so a
status read can catch a FAILED that then moves on. The loop below waits until there is something
to do. At FAILED with error.retryable set to true, it retries the meeting and keeps waiting,
up to three times; at a FAILED that can’t recover, or on an error, it stops and prints the answer
(it needs jq, and curl 7.76 or later for --fail-with-body):
retries=0while true; do body=$(curl -sS --fail-with-body https://app.lobbe.ai/api/v1/recordings/MEETING_ID/status \ -H "Authorization: Bearer $LOBBE_TOKEN") || { echo "$body"; break; } status=$(jq -r .status <<<"$body") echo "$status" case "$status" in NAMING | READY) break ;; esac if [ "$status" = FAILED ]; then if [ "$(jq -r .error.retryable <<<"$body")" != true ] || [ "$retries" -ge 3 ]; then echo "$body" break fi retries=$((retries + 1)) # 409 NOT_FAILED: it recovered by itself in the meantime. Keep waiting either way. body=$(curl -sS --fail-with-body -X POST \ https://app.lobbe.ai/api/v1/recordings/MEETING_ID/retry \ -H "Authorization: Bearer $LOBBE_TOKEN") || [ "$(jq -r .error.code <<<"$body" 2>/dev/null)" = NOT_FAILED ] || { echo "$body"; break; } fi sleep 60doneThe retry is safe while Lobbe is still retrying by itself: it never starts a second run, and it
costs nothing more. See FAILED and retry.
Following many meetings? Read the events feed, GET /events,
instead of asking for each meeting’s status.
5. Name the speakers, or skip
Section titled “5. Name the speakers, or skip”At NAMING, the status carries naming:
{ "schemaVersion": 1, "id": "MEETING_ID", "status": "NAMING", "title": null, "error": null, "naming": { "url": "https://app.lobbe.ai/m/MEETING_ID?name=speakers", "deadline": "2026-10-20T08:45:00.000Z" }, "bundleUrl": null, "url": "https://app.lobbe.ai/m/MEETING_ID"}You have two choices:
-
Hand
naming.urlto the person. It opens the meeting’s speaker naming in the app, for the account’s owner only, signed in. So it is safe to send in a chat or an email. -
Skip naming:
Terminal window curl https://app.lobbe.ai/api/v1/recordings/MEETING_ID/naming \-H "Authorization: Bearer $LOBBE_TOKEN" \-H "Content-Type: application/json" \-d '{ "action": "skip" }'Unnamed voices take Lobbe’s suggestions, and the Lobbe is made. The answer is
200with the meeting’s status. A meeting that isn’t atNAMINGanswers409 NOT_NAMING.
If neither happens, Lobbe goes ahead without names from naming.deadline on. When it is null,
Lobbe waits for you. To never stop at naming, send -F naming=skip with the meeting.
6. Read the Lobbe
Section titled “6. Read the Lobbe”At READY:
curl "https://app.lobbe.ai/api/v1/recordings/MEETING_ID/bundle?format=markdown" \ -H "Authorization: Bearer $LOBBE_TOKEN"The answer is one Markdown document: the title, the meeting’s details, the Lobbe’s sections and
the transcript. Without ?format=markdown you get the same bundle as JSON; its fields are in
GET /recordings/{id}/bundle. Reading a bundle needs
recordings:read.
With a read-only token
Section titled “With a read-only token”A token with Read alone can’t send meetings, but it reads your finished meetings:
export LOBBE_TOKEN=lobbe_…
# Check the tokencurl https://app.lobbe.ai/api/v1/whoami \ -H "Authorization: Bearer $LOBBE_TOKEN"
# Your finished meetings, newest firstcurl https://app.lobbe.ai/api/v1/recordings/ready \ -H "Authorization: Bearer $LOBBE_TOKEN"
# One whole meeting, as Markdowncurl "https://app.lobbe.ai/api/v1/recordings/MEETING_ID/bundle?format=markdown" \ -H "Authorization: Bearer $LOBBE_TOKEN"- Tokens and scopes: developer mode, the eight scopes, the daily cap and what no token can do.
- Minutes, caps and limits: what spends minutes, rate limits and upload limits.
- API reference: every route, its fields and its errors.