API v2

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.

ParameterTypeDefaultDescription
querystringrequiredKeywords, for example budget review Q3
limitinteger20Maximum quotes, 1 to 50
dateFromdateMeetings on or after this date
dateTodateMeetings 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.

ParameterTypeDefaultDescription
limitinteger201 to 100
offsetinteger0Number of meetings to skip
dateFrom, dateTodateWhen the meeting happened
createdFrom, createdTodateWhen the meeting became available to you
titleSearchstringKeyword in the meeting title (case-insensitive)
attendeeEmailstringAttendee email, partial match
attendeeDomainstringAt 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.

ParameterTypeDefaultDescription
recordIdsstring[]required1 to 20 meeting IDs, repeated or comma-separated
includeSummariesbooleanfalseAlso 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.

ParameterTypeDefaultDescription
querystringrequiredName or email, for example Mario Assaf or mario@acme.com
limitinteger151 to 50
thresholdnumber0.3Similarity from 0 to 1; lower is fuzzier
dateFrom, dateTodateDate 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.

ParameterTypeDefaultDescription
limitinteger201 to 50
dateFromtimestampnowEvents starting at or after this time
dateTotimestampEvents starting at or before this time
titleSearchstringKeyword in the event title
attendeeEmailstringAttendee 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.

ParameterTypeDefaultDescription
dateFrom, dateTodateDate range. Always set one for a time period.
maxTopicsinteger300Topic 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.

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.

ParameterTypeDefaultDescription
topicstringTopic keyword to follow. Omit it for overall trends.
dateFrom, dateTodateDate range
groupByweek or monthweekPeriod size. Labels look like 2026-W41 or 2026-10.
timezonestringUTCIANA timezone for grouping, for example Europe/Zurich
limitinteger30Topics 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.

ParameterTypeDefaultDescription
protocolIdstringrequiredTemplate ID from List summary templates
recordIdstringOnly summaries of this meeting
dateFrom, dateTotimestampSummary creation time range
limitinteger201 to 50
offsetinteger0Number 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 with title, question, answerType, and answers.
  • unstructured: markdown.
  • docx: downloadUrl, a signed link to the Word document, and expiresIn (seconds, one hour). Both fields are null when no document is available: it has not been generated yet, or its file was removed. A temporary signing failure returns 503 upstream_unavailable; it does not silently remove the summary from the page.