Meetings
Search transcripts, list and load meetings, read analysis, find a contact's meetings, and work with calendar events, topics, and summaries.
These operations read the meetings you can access in Optiverse, including meetings shared with you through your workspace. They are free and count toward the read limit of 120 requests per minute. Each one is also an MCP tool with the name shown in brackets.
Date filters accept an ISO date or timestamp. dateFrom is inclusive. A dateTo given as a date includes that whole UTC day; a dateTo given as a timestamp is exclusive.
Search Transcripts
GET /v2/meetings/search (search_meetings)
Full-text search across every transcript you can access. Returns matching quotes with the speaker, meeting title, and date.
| Parameter | Type | Default | Description |
|---|---|---|---|
query | string | required | Keywords, for example budget review Q3 |
limit | integer | 20 | Maximum quotes, 1 to 50 |
dateFrom | date | Meetings on or after this date | |
dateTo | date | Meetings up to this date |
curl "https://developer.optiverse.ai/api/v2/meetings/search?query=pricing&dateFrom=2026-09-01" \
-H "Authorization: Bearer optiuser_v1_your_key_here"{
"data": {
"matches": [
{
"recordId": "8f0c...",
"meetingTitle": "Acme renewal",
"meetingDate": "2026-09-18T14:00:00.000Z",
"speaker": "Anna",
"quote": "We can hold the current pricing if they sign before October.",
"sentenceId": 212
}
],
"meetingCount": 1
}
}List Meetings
GET /v2/meetings (list_meetings)
Recorded meetings, most recent first, with a one-sentence summary each.
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 20 | 1 to 100 |
offset | integer | 0 | Number of meetings to skip |
dateFrom, dateTo | date | When the meeting happened | |
createdFrom, createdTo | date | When the meeting became available to you | |
titleSearch | string | Keyword in the meeting title (case-insensitive) | |
attendeeEmail | string | Attendee email, partial match | |
attendeeDomain | string | At least one attendee from this domain, for example acme.com |
To pick up new meetings, poll with createdFrom set to the time of your last run. It also catches meetings that were uploaded or shared with you after they took place.
{
"data": {
"meetings": [
{
"recordId": "8f0c...",
"title": "Acme renewal",
"date": "2026-09-18",
"startDate": "2026-09-18T14:00:00+00:00",
"endDate": "2026-09-18T14:45:00+00:00",
"durationMinutes": 42,
"attendees": ["anna@yourco.com", "mario@acme.com"],
"organizer": "anna@yourco.com",
"role": "owner",
"createdAt": "2026-09-18T14:46:12+00:00",
"summary": "Acme agreed to renew if pricing holds through Q4."
}
]
},
"pagination": { "limit": 20, "offset": 0, "hasMore": true, "nextOffset": 20, "total": 138 }
}date is the meeting day; startDate and endDate are full timestamps. organizer is the calendar organizer, and role is your access to the meeting: owner, invited (shared with you), or guest. createdAt is when the meeting became available to you: recorded, uploaded or shared.
Get a Meeting
GET /v2/meetings/{recordId} (get_meeting)
One meeting with its attendees, speakers, and full transcript. The transcript is grouped by speaker as [Speaker]: blocks of plain sentences. Over MCP, «n» follows each sentence: its sentence ID, the same ID that search results and action items reference.
{
"data": {
"recordId": "8f0c...",
"title": "Acme renewal",
"date": "2026-09-18T14:00:00.000Z",
"durationMinutes": 42,
"attendees": ["anna@yourco.com", "mario@acme.com"],
"speakers": ["Anna", "Mario"],
"transcript": "[Anna]:\nThanks for joining. Let's start with pricing. ..."
}
}Get Meeting Analysis
GET /v2/meetings/analysis (get_meeting_analysis)
Analysis for up to 20 meetings: one-sentence summary, topics with takeaways, and action items. IDs of meetings that don't exist or that you can't access are left out of the response.
| Parameter | Type | Default | Description |
|---|---|---|---|
recordIds | string[] | required | 1 to 20 meeting IDs, repeated or comma-separated |
includeSummaries | boolean | false | Also return meeting notes and summary template sections |
curl "https://developer.optiverse.ai/api/v2/meetings/analysis?recordIds=8f0c...,a71d...&includeSummaries=true" \
-H "Authorization: Bearer optiuser_v1_your_key_here"{
"data": {
"meetings": [
{
"recordId": "8f0c...",
"title": "Acme renewal",
"oneSentenceSummary": "Acme agreed to renew if pricing holds through Q4.",
"topics": [
{ "name": "Pricing", "description": "Holding current rates", "takeaways": [{ "content": "Price locked until Oct 31", "sentenceIds": [212] }] }
],
"actionItems": [
{ "text": "Send renewal contract to Mario", "type": "task", "isDone": false, "sentenceIds": [230] }
],
"summaries": []
}
]
}
}Find a Contact's Meetings
GET /v2/contacts/meetings (find_contact_meetings)
Fuzzy-matches a name or email across calendar attendees, meeting titles, and transcript speaker labels. Handles partial names and typos.
| Parameter | Type | Default | Description |
|---|---|---|---|
query | string | required | Name or email, for example Mario Assaf or mario@acme.com |
limit | integer | 15 | 1 to 50 |
threshold | number | 0.3 | Similarity from 0 to 1; lower is fuzzier |
dateFrom, dateTo | date | Date range |
Each meeting includes matchScore, matchedValue, and matchSource (attendee, title, or speaker) so you can see why it matched.
List Upcoming Calendar Events
GET /v2/calendar/events (list_upcoming_events)
Upcoming events from your synced Google or Outlook calendar, soonest first. Only events that have not ended; for past meetings use List meetings.
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 20 | 1 to 50 |
dateFrom | timestamp | now | Events starting at or after this time |
dateTo | timestamp | Events starting at or before this time | |
titleSearch | string | Keyword in the event title | |
attendeeEmail | string | Attendee email, partial match |
Each event has eventId, title, eventStart, eventEnd, attendees, organizer, joinUrl, meetingProvider, and joinPref (whether the Optiverse notetaker is set to join).
Browse Topics
GET /v2/topics (browse_topics)
Topics discussed in your meetings, grouped by meeting, most recent first. Use it to find the meetings about a theme.
| Parameter | Type | Default | Description |
|---|---|---|---|
dateFrom, dateTo | date | Date range. Always set one for a time period. | |
maxTopics | integer | 300 | Topic rows to read, 1 to 1000 |
The response has meetings (each with recordId, meetingTitle, meetingDate, and topics), plus topicCount and totalTopicCount. When hasMore is true, the topic cap was reached: narrow the date range or raise maxTopics.
Analyze Topic Trends
GET /v2/topics/trends (analyze_topic_trends)
How topics evolve over time: meetings grouped by week or month, newest first, with the most frequent topics, the meetings, and key takeaways in each period.
| Parameter | Type | Default | Description |
|---|---|---|---|
topic | string | Topic keyword to follow. Omit it for overall trends. | |
dateFrom, dateTo | date | Date range | |
groupBy | week or month | week | Period size. Labels look like 2026-W41 or 2026-10. |
timezone | string | UTC | IANA timezone for grouping, for example Europe/Zurich |
limit | integer | 30 | Topics to analyze, 5 to 100 |
{
"data": {
"periods": [
{
"period": "2026-W41",
"meetingCount": 4,
"topics": [{ "name": "Pricing", "count": 3 }],
"meetings": [{ "recordId": "8f0c...", "title": "Acme renewal" }],
"takeaways": ["Price locked until Oct 31"]
}
],
"topRecurring": [{ "name": "Pricing", "count": 9 }],
"meetingCount": 17,
"topicCount": 30,
"hasMore": false,
"timezone": "UTC"
}
}List Summary Templates
GET /v2/summary-templates (list_summary_templates)
The summary templates (protocols) you can use, newest first. Each has a protocolId, title, description, summaryType (structured, unstructured, or docx), managedBy (optiverse or user), and createdAt.
Get Meeting Summaries
GET /v2/summaries (get_meeting_summaries)
The summaries one template produced, newest first.
| Parameter | Type | Default | Description |
|---|---|---|---|
protocolId | string | required | Template ID from List summary templates |
recordId | string | Only summaries of this meeting | |
dateFrom, dateTo | timestamp | Summary creation time range | |
limit | integer | 20 | 1 to 50 |
offset | integer | 0 | Number of summaries to skip |
Each summary includes its own summaryType, based on the format stored when it was generated. Changing a template's format does not hide its earlier summaries. The response's top-level summaryType describes the current page: structured, unstructured, docx, or mixed when the page contains several formats. An empty page uses the template's current format. Pagination counts all stored formats.
structured:sections, each withtitle,question,answerType, andanswers.unstructured:markdown.docx:downloadUrl, a signed link to the Word document, andexpiresIn(seconds, one hour). Both fields arenullwhen no document is available: it has not been generated yet, or its file was removed. A temporary signing failure returns503 upstream_unavailable; it does not silently remove the summary from the page.

