Search and Ask
Two scopes open these routes:
recordings:query(Meetings, Search and ask): search your meetings, and ask one meeting a question.series:query(Series, Ask a series): ask a whole series a question.
Searching is free, and so is asking what a question will cost. Each answer spends minutes.
Search
Section titled “Search”GET /recordings/search finds finished meetings by their
words:
curl -G https://app.lobbe.ai/api/v1/recordings/search \ -H "Authorization: Bearer $LOBBE_TOKEN" \ --data-urlencode "q=launch budget" \ --data-urlencode "from=2026-10-01T00:00:00+03:30"-G with --data-urlencode puts the parameters in the address, encoded, so a Persian q works as
it is.
What matches
Section titled “What matches”- Every word of
qmust appear somewhere in the meeting: its title, its transcript or its Lobbe. A word also matches inside a longer word. - Small differences don’t count. Capitals, diacritics and the half-space are ignored, Arabic
letter forms (
ي,ك) match Persian ones, and Persian digits match Latin ones. qis required, 1 to 200 characters. Aqwith no word in it, only spaces for example, answers400 VALIDATION.
Which meetings
Section titled “Which meetings”- Without
seriesId: your own finished meetings, the ones inREADY. - With
seriesId: the finished meetings of that series, a series you joined included. A series you can’t read answers404.
Filters and order
Section titled “Filters and order”| Parameter | What it does |
|---|---|
seriesId |
Only the meetings of this series |
kind |
Only meetings of this kind: MEETING, LECTURE, INTERVIEW, VOICE_MEMO or CALL |
from, to |
Only meetings that happened in this window (recordedAt, both ends included), ISO 8601 with an offset |
limit |
How many meetings per page, 1–50 (20 by default) |
cursor |
The nextCursor of the previous page, passed back as it is |
- Any other parameter answers
400 VALIDATION, so a typo never turns into a filter that silently does nothing. - The newest meeting comes first, by when it happened (
recordedAt). This is not the order ofGET /recordings/ready, which follows when Lobbe received each meeting. See The meeting time. nextCursorisnullon the last page.
What comes back
Section titled “What comes back”{ "schemaVersion": 1, "items": [ { "id": "MEETING_ID", "title": "Weekly product sync", "kind": "MEETING", "createdAt": "2026-10-19T08:31:12.000Z", "recordedAt": "2026-10-19T07:00:00.000Z", "durationSeconds": 2520, "url": "https://app.lobbe.ai/m/MEETING_ID", "bundleUrl": "https://app.lobbe.ai/api/v1/recordings/MEETING_ID/bundle", "series": { "id": "SERIES_ID", "name": "Product sync" }, "displayTitle": "Weekly product sync", "snippet": "…so the launch budget stays where it is until the payment fix ships…" } ], "nextCursor": null}Each item is an item of the list of finished meetings, plus snippet: up to 200 characters around
the first match, from the transcript, or from the Lobbe when only the Lobbe matched. It is null
when the words were found in the title alone.
What recordings:query reaches
Section titled “What recordings:query reaches”- A token with
recordings:queryand norecordings:readhas no list and no bundles. Each item still carriesbundleUrl, but fetching it needsrecordings:read. - Search is not a way to hide meetings from such a token: a short
qmatches nearly every meeting, so it can find any of your finished meetings, and then ask it. - Search spends the token’s
searchbudget, shared with the Ask quotes: its size is in Rate limits.
Ask a meeting
Section titled “Ask a meeting”Asking is two steps: get the price, then ask with that price as your ceiling.
1. Get the price
Section titled “1. Get the price”curl https://app.lobbe.ai/api/v1/recordings/MEETING_ID/ask/quote \ -H "Authorization: Bearer $LOBBE_TOKEN"{ "schemaVersion": 1, "minutes": 3 }GET /recordings/{id}/ask/quote is free. The price
depends on the meeting, not on the question: it comes from the length of the transcript as Lobbe
reads it, the speakers’ names included. So one quote holds for every question to that meeting, until
its transcript is edited or a speaker is named or renamed.
2. Ask
Section titled “2. Ask”key=$(uuidgen) # one key for this question, kept for every retry of itcurl https://app.lobbe.ai/api/v1/recordings/MEETING_ID/ask \ -H "Authorization: Bearer $LOBBE_TOKEN" \ -H "Idempotency-Key: $key" \ -H "Content-Type: application/json" \ -d '{ "question": "What did we decide about the launch date?", "maxMinutes": 3 }'questionis 1 to 500 characters, after spaces at either end are trimmed.maxMinutesis optional: the most you agree to pay. Without it, the Ask charges whatever the price is. With it, a higher price answers409 PRICE_ABOVE_MAX, withdetails.minutes(the price) anddetails.maxMinutes, and nothing is charged. Send the quote’sminutes: then a price that changed since the quote can never charge you more than you saw.Idempotency-Keymakes a retry safe: the same key gets the first answer back, never a second charge. See Idempotency and retries.
POST /recordings/{id}/ask answers 200:
{ "schemaVersion": 1, "answer": "The launch moves to 2 November [1], once the payment fix has been tested [2].", "citations": [ { "startMs": 754000, "speaker": "speaker_1" }, { "startMs": 812500, "speaker": "speaker_0" } ], "minutes": 3, "refused": false}minutes is what this answer charged.
Footnotes and citations
Section titled “Footnotes and citations”[n]inanswermarks the claim thatcitations[n - 1]supports. The markers are numbered 1, 2, 3… in reading order, andcitationslists the turns in the order the answer first cites them. A group such as[1][2]cites two turns.- A meeting’s answer cites at most 3 turns. An answer can cite none, and then has no markers: a question about how long the meeting was, say, is answered from its measured facts.
- Each citation is a turn of the transcript.
startMsis when the turn starts, in milliseconds from the start of the audio.speakeris the voice’s label as transcribed (speaker_0), never the name someone gave it. - To show a cited turn, find the segment in the meeting’s
bundle whose
startMsis the same. Take who spoke from that segment’sspeaker, which the bundle has already matched to a person intranscript.speakers, with their name. This needsrecordings:read. - Lobbe checks the citations. A citation that points at no real turn is dropped, and an answer
whose every citation is invented is not given at all: it answers
502 GENERATE_FAILED, and nothing is charged.
When Lobbe declines
Section titled “When Lobbe declines”When the meeting doesn’t answer the question, refused is true and answer says why. A refusal
is charged, like any answer: Lobbe had to read the whole meeting to know.
What else to know
Section titled “What else to know”- It is your Ask. It shows in the meeting’s Ask tab in the app. Lobbe also reads the latest questions and answers on the meeting as context for the next one, whether they were asked in the app or through a token.
- Which meetings: your own, and those of a series you joined. A meeting that isn’t
READYanswers409 ASK_NOT_READY, and one you can’t reach answers404. - Spending: the price comes from your balance (
402 INSUFFICIENT_MINUTESwhen it is short) and counts toward the token’s daily cap (429 TOKEN_DAILY_CAP). Lobbe’s own daily limit on Asks, one limit for meeting and series Asks together, answers429 DAILY_LIMIT_REACHEDwithRetry-After. See Minutes, caps and limits. - Budget: the Asks share the token’s
askbudget: its size is in Rate limits. - While Ask is switched off in Lobbe, an Ask or a quote answers
409 ASK_DISABLED: try again later.
Ask a series
Section titled “Ask a series”With series:query, one question reads every finished meeting of a series: one you own, or one you
joined.
curl https://app.lobbe.ai/api/v1/series/SERIES_ID/ask/quote \ -H "Authorization: Bearer $LOBBE_TOKEN"{ "schemaVersion": 1, "minutes": 9, "meetingCount": 6 }Then ask as you would a meeting, with the same body and an Idempotency-Key:
key=$(uuidgen)curl https://app.lobbe.ai/api/v1/series/SERIES_ID/ask \ -H "Authorization: Bearer $LOBBE_TOKEN" \ -H "Idempotency-Key: $key" \ -H "Content-Type: application/json" \ -d '{ "question": "Which action items are still open?", "maxMinutes": 9 }'{ "schemaVersion": 1, "answer": "Two are still open: the pricing page copy [1] and the Android release notes [2].", "citations": [ { "recordingId": "MEETING_ID", "startMs": 1203000, "speaker": "speaker_2" }, { "recordingId": "MEETING_ID_2", "startMs": 98000, "speaker": "speaker_0" } ], "minutes": 9, "refused": false}- What it reads:
GET /series/{id}/ask/quotegives the price andmeetingCount, how many finished meetings the question reads. It reads every one’s Lobbe, then as many full transcripts as fit, newest first. - Too few meetings: a series needs at least 2 finished meetings. With fewer, the quote and the
Ask both answer
409 SERIES_ASK_TOO_FEW. With one, ask that meeting instead. - Citations name a meeting too: each carries
recordingIdbesidestartMsandspeaker, and an answer cites at most 5 turns, from any of the series’ meetings. To show one, read that meeting’s bundle. - Footnotes, refusals,
maxMinutes, the price, the balance, the caps and the key work as for a meeting, throughPOST /series/{id}/ask. The price comes from the series’ meetings, so it changes as meetings are added or change. - It is your Ask, in the series’ Ask in the app. A member who asks pays from their own balance, never the series’ owner.
- A series you can’t reach answers
404, and so does every series while series are switched off. While Ask is switched off, the Ask answers409 ASK_DISABLEDand the quote answers404.