رفتن به محتوا

جست‌وجو و پرسش

این مسیرها با دو دسترسی باز می‌شوند:

  • recordings:query («جست‌وجو و پرسش» در گروه «جلسه‌ها»): جست‌وجو در جلسه‌های شما و پرسیدن سؤال از یک جلسه.
  • series:query («پرسش از سری» در گروه «سری‌ها»): پرسیدن سؤال از کل یک سری.

جست‌وجو و گرفتن قیمت پرسش رایگان‌اند؛ هر پاسخ دقیقه خرج می‌کند.

GET /recordings/search جلسه‌های آماده را با واژه‌هایشان پیدا می‌کند:

Terminal window
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 همراه --data-urlencode پارامترها را کدگذاری‌شده در نشانی درخواست می‌گذارد، پس q فارسی هم همان‌طور که هست کار می‌کند.

  • همهٔ واژه‌های q باید جایی در جلسه آمده باشند: در عنوان، رونوشت یا لُب آن. واژه‌ای که درون واژه‌ای بلندتر آمده باشد هم پیدا می‌شود.
  • تفاوت‌های کوچک به حساب نمی‌آیند. بزرگی و کوچکی حروف، اعراب و نیم‌فاصله نادیده گرفته می‌شوند، شکل عربی حروف (ي، ك) با شکل فارسی آن‌ها یکی حساب می‌شود، و رقم‌های فارسی با رقم‌های لاتین.
  • q اجباری است و ۱ تا ۲۰۰ نویسه دارد. q بی‌هیچ واژه‌ای، مثلاً فقط فاصله، پاسخ 400 VALIDATION می‌گیرد.
  • بدون seriesId: جلسه‌های آمادهٔ خود شما، یعنی جلسه‌هایی که در READY هستند.
  • با seriesId: جلسه‌های آمادهٔ همان سری، از جمله سری‌ای که عضوش شده‌اید. سری‌ای که نمی‌توانید بخوانید پاسخ 404 می‌گیرد.
پارامتر کارش
seriesId فقط جلسه‌های این سری
kind فقط جلسه‌های این نوع: MEETING، LECTURE، INTERVIEW، VOICE_MEMO یا CALL
from و to فقط جلسه‌هایی که در این بازه برگزار شده‌اند (recordedAt، با هر دو سر بازه)، به قالب ISO 8601 با اختلاف ساعت
limit شمار جلسه‌های هر صفحه، از ۱ تا ۵۰ (به‌طور پیش‌فرض ۲۰)
cursor مقدار nextCursor صفحهٔ قبل، بی‌هیچ تغییری
  • هر پارامتر دیگری پاسخ 400 VALIDATION می‌گیرد، پس یک غلط تایپی هیچ‌وقت بی‌سروصدا به فیلتری بی‌اثر تبدیل نمی‌شود.
  • تازه‌ترین جلسه، بر اساس زمان برگزاری (recordedAt)، اول می‌آید. این همان ترتیب GET /recordings/ready نیست؛ آن فهرست به ترتیب زمانی است که لُب جلسه را دریافت کرده است. زمان برگزاری جلسه را ببینید.
  • در صفحهٔ آخر nextCursor برابر null است.
{
"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
}

هر مورد همان ردیف فهرست جلسه‌های آماده است، به‌اضافهٔ snippet: حداکثر ۲۰۰ نویسه پیرامون نخستین جایی که واژه‌ها پیدا شده‌اند، از رونوشت، یا اگر واژه‌ها فقط در لُب پیدا شده باشند از لُب. اگر واژه‌ها فقط در عنوان پیدا شده باشند، null است.

دسترسی recordings:query به کجا می‌رسد

Section titled “دسترسی recordings:query به کجا می‌رسد”
  • توکنی که recordings:query دارد اما recordings:read ندارد، نه فهرست جلسه‌ها را می‌گیرد و نه جلسهٔ کامل را. هر مورد همچنان bundleUrl دارد، اما گرفتن آن به recordings:read نیاز دارد.
  • جست‌وجو راهی برای پنهان کردن جلسه‌ها از چنین توکنی نیست: یک q کوتاه تقریباً همهٔ جلسه‌ها را پیدا می‌کند، پس این توکن به هر جلسهٔ آمادهٔ شما می‌رسد و بعد می‌تواند از آن بپرسد.
  • جست‌وجو از سقف دستهٔ search توکن خرج می‌کند که با گرفتن قیمت پرسش مشترک است؛ اندازهٔ این سقف در سقف درخواست‌ها آمده است.

پرسش دو گام دارد: قیمت را بگیرید، بعد با همان قیمت به‌عنوان سقف، سؤالتان را بپرسید.

Terminal window
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 رایگان است. قیمت به جلسه بستگی دارد، نه به سؤال: از طول رونوشتی می‌آید که لُب می‌خواند، و نام گوینده‌ها هم جزو آن است. پس یک قیمت برای هر سؤالی از همان جلسه معتبر است، تا وقتی رونوشت ویرایش نشده و گوینده‌ای نام تازه نگرفته باشد.

Terminal window
key=$(uuidgen) # one key for this question, kept for every retry of it
curl 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 }'
  • question پس از حذف فاصله‌های دو سرش، ۱ تا ۵۰۰ نویسه است.
  • maxMinutes اختیاری است: بیشترین قیمتی که می‌پذیرید. بدون آن، پرسش هر قیمتی داشته باشد همان را خرج می‌کند. با آن، اگر قیمت بیشتر باشد، پاسخ 409 PRICE_ABOVE_MAX است، با details.minutes (قیمت) و details.maxMinutes، و هزینه‌ای گرفته نمی‌شود. همان minutes را بفرستید که گرفتن قیمت پرسش داده است: آن‌وقت اگر قیمت از آن لحظه تغییر کرده باشد، هرگز بیش از آنچه دیده‌اید خرج نمی‌شود.
  • Idempotency-Key تلاش دوباره را بی‌خطر می‌کند: همان کلید همان پاسخ اول را برمی‌گرداند و هزینه هرگز دو بار گرفته نمی‌شود؛ تکرارپذیری و تلاش دوباره را ببینید.

POST /recordings/{id}/ask با 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 هزینه‌ای است که همین پاسخ گرفته است.

  • هر [n] در answer کنار ادعایی می‌آید که citations[n - 1] پشتیبان آن است. این پانویس‌ها به ترتیب خواندن ۱، ۲، ۳ و… شماره می‌خورند و citations منبع‌ها را به همان ترتیبی می‌آورد که پاسخ نخستین بار به آن‌ها ارجاع داده است. پانویس‌های کنار هم، مثل [1][2]، به دو منبع ارجاع می‌دهند.
  • پاسخ یک جلسه حداکثر ۳ منبع دارد. پاسخ ممکن است هیچ منبعی نداشته باشد و آن‌وقت پانویسی هم ندارد: مثلاً به سؤالی دربارهٔ مدت جلسه از روی آمار خود جلسه پاسخ داده می‌شود.
  • هر منبع یک نوبت از رونوشت است. startMs زمان شروع آن نوبت است، به میلی‌ثانیه از ابتدای صدا. speaker برچسب صدا در رونوشت است (speaker_0)، هرگز نامی که کسی به آن صدا داده است.
  • برای نشان دادن نوبتی که به آن ارجاع شده، در جلسهٔ کامل نوبتی (segments) را پیدا کنید که startMs آن همین عدد است. گوینده را از speaker همان نوبت بگیرید: جلسهٔ کامل این برچسب را از پیش به یکی از افراد transcript.speakers و نام او رسانده است. این کار به recordings:read نیاز دارد.
  • لُب منبع‌ها را بررسی می‌کند. منبعی که به هیچ نوبت واقعی‌ای اشاره نکند کنار گذاشته می‌شود، و پاسخی که همهٔ منبع‌هایش ساختگی باشند اصلاً داده نمی‌شود: پاسخ 502 GENERATE_FAILED است و هزینه‌ای گرفته نمی‌شود.

وقتی لُب از پاسخ خودداری می‌کند

Section titled “وقتی لُب از پاسخ خودداری می‌کند”

اگر جلسه جواب سؤال را نداشته باشد، refused برابر true است و answer دلیلش را می‌گوید. این پاسخ هم مثل هر پاسخ دیگری هزینه دارد: لُب باید کل جلسه را می‌خواند تا مطمئن شود.

  • این پرسش، پرسش خود شماست. در برگهٔ «پرسش» همان جلسه در برنامه دیده می‌شود. لُب آخرین سؤال‌ها و پاسخ‌های همان جلسه را، چه در برنامه پرسیده شده باشند چه با توکن، هنگام پاسخ به سؤال بعدی هم در نظر می‌گیرد.
  • کدام جلسه‌ها: جلسه‌های خود شما و جلسه‌های سری‌ای که عضوش شده‌اید. جلسه‌ای که READY نباشد پاسخ 409 ASK_NOT_READY می‌گیرد، و جلسه‌ای که به آن دسترسی ندارید 404.
  • هزینه: قیمت از موجودی شما برداشته می‌شود (اگر کافی نباشد، 402 INSUFFICIENT_MINUTES) و جزو سقف روزانهٔ توکن شمرده می‌شود (429 TOKEN_DAILY_CAP). سقف روزانهٔ خود لُب برای پرسش‌ها، که پرسش از جلسه و پرسش از سری با هم در آن شمرده می‌شوند، پاسخ 429 DAILY_LIMIT_REACHED همراه Retry-After می‌دهد. دقیقه‌ها، سقف‌ها و محدودیت‌ها را ببینید.
  • سقف درخواست‌ها: پرسش‌ها از سقف دستهٔ ask توکن خرج می‌کنند؛ اندازهٔ این سقف در سقف درخواست‌ها آمده است.
  • تا وقتی پرسش در لُب خاموش است، پرسیدن یا گرفتن قیمت پرسش پاسخ 409 ASK_DISABLED می‌گیرد: بعداً دوباره امتحان کنید.

با series:query یک سؤال همهٔ جلسه‌های آمادهٔ یک سری را می‌خواند: سری‌ای که ساخته‌اید یا سری‌ای که عضوش شده‌اید.

Terminal window
curl https://app.lobbe.ai/api/v1/series/SERIES_ID/ask/quote \
-H "Authorization: Bearer $LOBBE_TOKEN"
{ "schemaVersion": 1, "minutes": 9, "meetingCount": 6 }

بعد همان‌طور که از یک جلسه می‌پرسید بپرسید، با همان بدنه و یک Idempotency-Key:

Terminal window
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
}
  • چه چیزی خوانده می‌شود: GET /series/{id}/ask/quote قیمت را می‌دهد و meetingCount را، یعنی شمار جلسه‌های آماده‌ای که سؤال می‌خواند. برای پاسخ، اول لُب همهٔ این جلسه‌ها خوانده می‌شود، سپس هر چند رونوشت کامل که جا شود، از تازه‌ترین جلسه.
  • اگر جلسه کافی نباشد: سری دست‌کم ۲ جلسهٔ آماده لازم دارد. اگر کمتر باشد، هم گرفتن قیمت پرسش و هم پرسیدن پاسخ 409 SERIES_ASK_TOO_FEW می‌گیرند. اگر سری فقط یک جلسه دارد، از همان جلسه بپرسید.
  • منبع‌ها جلسه را هم نام می‌برند: هر منبع کنار startMs و speaker، مقدار recordingId را هم دارد، و پاسخ در مجموع حداکثر ۵ منبع دارد، از هر کدام از جلسه‌های سری. برای نشان دادن یکی از آن‌ها، جلسهٔ کامل همان جلسه را بخوانید.
  • پانویس‌ها، خودداری از پاسخ، maxMinutes، قیمت، موجودی، سقف‌ها و کلید در POST /series/{id}/ask همان‌طور کار می‌کنند که برای یک جلسه. قیمت از جلسه‌های سری می‌آید، پس با اضافه شدن جلسه یا تغییر جلسه‌ها تغییر می‌کند.
  • این پرسش، پرسش خود شماست و در «پرسش از سری» همان سری در برنامه دیده می‌شود. عضوی که می‌پرسد از موجودی خودش هزینه می‌دهد، هرگز صاحب سری.
  • سری‌ای که به آن دسترسی ندارید پاسخ 404 می‌گیرد، و تا وقتی سری‌ها در لُب خاموش‌اند هر سری‌ای همین پاسخ را می‌گیرد. تا وقتی پرسش خاموش است، پرسیدن پاسخ 409 ASK_DISABLED و گرفتن قیمت پرسش پاسخ 404 می‌گیرد.