Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.mavera.io/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The Meetings API provides access to meeting recordings, transcripts, and AI-powered analysis. You can retrieve meeting details, get transcripts in multiple formats, access AI-generated insights like summaries, tasks, and decisions, and run custom schemas to extract structured data from meeting transcripts.

When to Use Meetings

Use the Meetings API when you need to:
  • Record and transcribe calls from Zoom, Google Meet, Microsoft Teams, or Webex
  • Extract insights — summaries, action items, decisions, highlights — without manual note-taking
  • Run custom schemas — qualification data (BANT, MEDDIC), objection handling, product feedback — from sales or customer calls
  • Sales coaching — talk ratios, question counts, discovery completeness
  • Compliance — verify disclosures or required statements in recorded calls
Meetings require a bot to join the call. Create a meeting with a meeting_url; the bot joins immediately or at join_at. Processing (transcript, analysis) happens after the call ends.

Typical Flow

1

Create a meeting

POST /meetings with meeting_url, title, and optional join_at. Bot joins the call and records.
2

Monitor status

Poll GET /meetings/{id} or list meetings. Wait until status is done before accessing transcript and analysis.
3

Get transcript

GET /meetings/{id}/transcript with optional format (segments, text, srt) and time range.
4

Get analysis

GET /meetings/{id}/analysis for summary, tasks, decisions, highlights, coaching metrics.
5

Run schema (optional)

POST /meetings/{id}/schemas/{schema_id}/run to extract structured data (e.g. qualification fields).

Meeting Recordings

Access recordings from Zoom, Google Meet, Microsoft Teams, and other platforms

Transcripts

Get transcripts in segments, plain text, or SRT subtitle format with speaker attribution

AI Analysis

Summaries, key takeaways, highlights, tasks, decisions, and coaching metrics

Custom Schemas

Define and run schemas to extract structured data like qualification info or objection handling

Meeting Lifecycle

Meetings go through the following statuses:
StatusDescription
pendingBot scheduled to join
joining_callBot is joining the meeting
in_waiting_roomBot in meeting waiting room
in_call_recordingBot is actively recording
call_endedMeeting ended, processing starting
recording_doneRecording complete
doneAll processing complete, ready for access
fatalError occurred during recording
cancelledMeeting was cancelled

Basic Usage

Creating a Meeting Bot

Start recording a meeting by creating a meeting bot. The bot will join the meeting immediately or at a scheduled time.
import requests

api_key = "mvra_live_your_key_here"
headers = {"Authorization": f"Bearer {api_key}"}

# Create a bot to join immediately
meeting = requests.post(
    "https://app.mavera.io/api/v1/meetings",
    headers=headers,
    json={
        "meeting_url": "https://zoom.us/j/123456789",
        "title": "Sales Discovery Call",
        "bot_name": "Mavera Notetaker"
    }
).json()

print(f"Meeting ID: {meeting['id']}")
print(f"Status: {meeting['status']}")
print(f"Platform: {meeting['platform']}")

# Schedule a bot for a future meeting
scheduled_meeting = requests.post(
    "https://app.mavera.io/api/v1/meetings",
    headers=headers,
    json={
        "meeting_url": "https://meet.google.com/abc-defg-hij",
        "title": "Weekly Standup",
        "bot_name": "Mavera Notetaker",
        "join_at": "2024-03-20T14:00:00Z"  # ISO 8601 format
    }
).json()

print(f"Scheduled for: {scheduled_meeting['join_at']}")

Supported Platforms

PlatformURL PatternExample
Zoomzoom.us/j/...https://zoom.us/j/123456789
Google Meetmeet.google.com/...https://meet.google.com/abc-defg-hij
Microsoft Teamsteams.microsoft.com/...https://teams.microsoft.com/l/meetup-join/...
Webexwebex.com/...https://company.webex.com/meet/...

Listing Meetings

import requests

api_key = "mvra_live_your_key_here"
headers = {"Authorization": f"Bearer {api_key}"}

# List all meetings
meetings = requests.get(
    "https://app.mavera.io/api/v1/meetings",
    headers=headers
).json()

for meeting in meetings["data"]:
    print(f"{meeting['title']} - {meeting['status']}")
    print(f"  Participants: {meeting['participant_count']}")
    print(f"  Has analysis: {meeting['has_analysis']}")

# Filter by status (e.g., only completed meetings)
completed = requests.get(
    "https://app.mavera.io/api/v1/meetings",
    headers=headers,
    params={"status": "done"}
).json()

# Filter by workspace
workspace_meetings = requests.get(
    "https://app.mavera.io/api/v1/meetings",
    headers=headers,
    params={"workspace_id": "ws_abc123"}
).json()

# Paginate through results
cursor = None
all_meetings = []

while True:
    params = {"limit": 50}
    if cursor:
        params["cursor"] = cursor

    response = requests.get(
        "https://app.mavera.io/api/v1/meetings",
        headers=headers,
        params=params
    ).json()

    all_meetings.extend(response["data"])

    if not response["has_more"]:
        break

    cursor = response["next_cursor"]

print(f"Total meetings: {len(all_meetings)}")

Getting Meeting Details

# Get meeting with all details
meeting = requests.get(
    f"https://app.mavera.io/api/v1/meetings/{meeting_id}",
    headers=headers
).json()

print(f"Title: {meeting['title']}")
print(f"Status: {meeting['status']}")
print(f"Participants: {meeting['participant_count']}")

# Transcript info
if meeting["transcript"]:
    print(f"Duration: {meeting['transcript']['duration_seconds']}s")
    print(f"Words: {meeting['transcript']['total_words']}")

# Tasks extracted from meeting
print(f"\nTasks ({meeting['task_count']}):")
for task in meeting["tasks"]:
    print(f"  - {task['content']}")
    print(f"    Owner: {task['owner']}")
    print(f"    Priority: {task['priority']}")

# Decisions made
print(f"\nDecisions ({meeting['decision_count']}):")
for decision in meeting["decisions"]:
    print(f"  - {decision['statement']}")

Managing Meetings

Cancelling a Meeting

Cancel a scheduled or in-progress meeting recording. The meeting record is kept but marked as cancelled.
# Cancel a meeting
result = requests.post(
    f"https://app.mavera.io/api/v1/meetings/{meeting_id}/cancel",
    headers=headers,
    json={"reason": "Meeting rescheduled"}
).json()

print(f"Status: {result['status']}")
print(f"Cancelled at: {result['cancelled_at']}")
print(f"Reason: {result['cancel_reason']}")

Deleting a Meeting

Permanently delete a meeting and all associated data including recordings, transcripts, and analysis.
This action is irreversible. All data associated with the meeting will be permanently deleted.
# Delete a meeting
result = requests.delete(
    f"https://app.mavera.io/api/v1/meetings/{meeting_id}",
    headers=headers
).json()

if result["deleted"]:
    print(f"Meeting {result['id']} deleted successfully")

Accessing Recording URL

When a meeting is complete, you can access the recording URL:
meeting = requests.get(
    f"https://app.mavera.io/api/v1/meetings/{meeting_id}",
    headers=headers
).json()

if meeting["recording_url"]:
    print(f"Recording available at: {meeting['recording_url']}")
    # Download or stream the recording
else:
    print("Recording not yet available")

Transcripts

Get meeting transcripts in multiple formats for different use cases.

Transcript Formats

FormatDescriptionUse Case
segmentsStructured JSON with speaker, timestamps, word-level timingAnalysis, search, integration
textPlain text with speaker labelsHuman reading, documents
srtSubtitle format with timestampsVideo players, accessibility

Getting Transcripts

# Get structured transcript (default)
transcript = requests.get(
    f"https://app.mavera.io/api/v1/meetings/{meeting_id}/transcript",
    headers=headers
).json()

print(f"Duration: {transcript['duration_seconds']}s")
print(f"Total words: {transcript['total_words']}")

for segment in transcript["segments"]:
    print(f"[{segment['start']:.1f}s] {segment['speaker']}: {segment['text']}")

# Get plain text format
text_transcript = requests.get(
    f"https://app.mavera.io/api/v1/meetings/{meeting_id}/transcript",
    headers=headers,
    params={"format": "text"}
).json()

print(text_transcript["content"])

# Get SRT subtitle format
srt_transcript = requests.get(
    f"https://app.mavera.io/api/v1/meetings/{meeting_id}/transcript",
    headers=headers,
    params={"format": "srt"}
).json()

# Save as .srt file
with open("meeting.srt", "w") as f:
    f.write(srt_transcript["content"])

# Get specific time range (e.g., minutes 5-10)
partial = requests.get(
    f"https://app.mavera.io/api/v1/meetings/{meeting_id}/transcript",
    headers=headers,
    params={
        "format": "segments",
        "start_time": 300,  # 5 minutes
        "end_time": 600     # 10 minutes
    }
).json()

AI Analysis

Access comprehensive AI-powered analysis of meetings including summaries, highlights, coaching metrics, and more.

Getting Analysis

analysis = requests.get(
    f"https://app.mavera.io/api/v1/meetings/{meeting_id}/analysis",
    headers=headers
).json()

# Summary and key points
print(f"Summary: {analysis['summary']}")
print(f"\nKey Takeaways:")
for takeaway in analysis["key_takeaways"]:
    print(f"  - {takeaway}")

# Topics discussed
print(f"\nTopics: {', '.join(analysis['topics'])}")

# Highlights (key moments)
print(f"\nHighlights ({len(analysis['highlights'])}):")
for highlight in analysis["highlights"]:
    print(f"  [{highlight['timestamp_start']:.1f}s] {highlight['speaker']}")
    print(f"  \"{highlight['quote']}\"")
    print(f"  Category: {highlight['category']}")

# Tasks
print(f"\nTasks ({len(analysis['tasks'])}):")
for task in analysis["tasks"]:
    status = f"[{task['status']}]" if task['status'] else ""
    print(f"  {status} {task['content']}")
    if task["owner"]:
        print(f"      Owner: {task['owner']}")
    if task["due_date"]:
        print(f"      Due: {task['due_date']}")

# Decisions
print(f"\nDecisions ({len(analysis['decisions'])}):")
for decision in analysis["decisions"]:
    print(f"  - {decision['statement']}")
    if decision["owner"]:
        print(f"    Owner: {decision['owner']}")

# Coaching metrics (for sales calls)
if analysis["coaching_metrics"]:
    cm = analysis["coaching_metrics"]
    print(f"\nCoaching Metrics:")
    print(f"  Host talk ratio: {cm['overall_host_talk_ratio']:.1%}")
    print(f"  Questions asked: {cm['total_questions_asked']}")
    print(f"  Interruptions: {cm['interruptions']}")
    print(f"  Next step confirmed: {cm['next_step_confirmed']}")
    print(f"  Discovery score: {cm['discovery_completeness_score']}")

Analysis Components

ComponentDescription
summaryAI-generated meeting summary
key_takeawaysList of key points from the meeting
topicsTopics discussed
sentimentOverall meeting sentiment
highlightsKey moments with quotes and timestamps
tasksAction items extracted from discussion
decisionsDecisions made during the meeting
coaching_metricsSales coaching analytics (talk ratios, questions, etc.)
schema_resultsStructured data extracted via schemas

Custom Schemas

Schemas allow you to define structured data extraction templates that can be run against meeting transcripts. This is powerful for extracting qualification data, objection handling, or any custom business information.

Schema Categories

CategoryDescription
sales_discoverySales discovery call data
qualificationLead qualification (MEDDIC, BANT, etc.)
objection_competitorObjection and competitor mentions
cs_healthCustomer success health metrics
product_feedbackProduct feedback and feature requests
customCustom schemas you define

Field Types

TypeDescriptionExample
textShort text (max 500 chars)Company name
long_textLong text (max 2000 chars)Summary
enumSingle choice from optionsDeal stage
multi_selectMultiple choicesPain points
numberNumeric valueBudget amount
booleanTrue/falseNext step confirmed
listArray of stringsStakeholders
personName, email, roleDecision maker
dateDate (YYYY-MM-DD)Expected close date

Creating a Schema

# Create a sales qualification schema
schema = requests.post(
    "https://app.mavera.io/api/v1/meetings/schemas",
    headers=headers,
    json={
        "name": "Sales Discovery Schema",
        "description": "Extract key qualification data from sales calls",
        "category": "sales_discovery",
        "fields": [
            {
                "name": "budget_range",
                "label": "Budget Range",
                "field_type": "enum",
                "enum_options": ["<$10k", "$10k-$50k", "$50k-$100k", ">$100k"],
                "is_required": True,
                "requires_evidence": True
            },
            {
                "name": "decision_makers",
                "label": "Decision Makers",
                "field_type": "list",
                "requires_evidence": True
            },
            {
                "name": "timeline",
                "label": "Expected Timeline",
                "field_type": "text",
                "requires_evidence": True
            },
            {
                "name": "pain_points",
                "label": "Pain Points",
                "field_type": "multi_select",
                "enum_options": [
                    "Cost reduction",
                    "Efficiency",
                    "Scaling",
                    "Compliance",
                    "Integration"
                ]
            },
            {
                "name": "next_step_confirmed",
                "label": "Next Step Confirmed",
                "field_type": "boolean",
                "scoring_enabled": True
            },
            {
                "name": "champion",
                "label": "Champion Contact",
                "field_type": "person"
            }
        ]
    }
).json()

print(f"Schema created: {schema['id']}")
print(f"Fields: {schema['field_count']}")

Listing Schemas

# List all available schemas
schemas = requests.get(
    "https://app.mavera.io/api/v1/meetings/schemas",
    headers=headers
).json()

print(f"Available schemas ({len(schemas['data'])}):")
for schema in schemas["data"]:
    built_in = "[Built-in]" if schema["is_built_in"] else ""
    print(f"  {built_in} {schema['name']}")
    print(f"    Category: {schema['category']}")
    print(f"    Fields: {schema['field_count']}")
    print(f"    Usage count: {schema['usage_count']}")

# Filter by category
discovery_schemas = requests.get(
    "https://app.mavera.io/api/v1/meetings/schemas",
    headers=headers,
    params={"category": "sales_discovery"}
).json()

# Exclude built-in schemas
custom_schemas = requests.get(
    "https://app.mavera.io/api/v1/meetings/schemas",
    headers=headers,
    params={"include_built_in": "false"}
).json()

Running a Schema on a Meeting

# Run schema against a meeting's transcript
result = requests.post(
    f"https://app.mavera.io/api/v1/meetings/{meeting_id}/schemas/{schema_id}/run",
    headers=headers
).json()

print(f"Schema: {result['schema_name']}")
print(f"Overall Score: {result['overall_score']}")
print(f"Processing Time: {result['processing_time_ms']}ms")

print("\nExtracted Values:")
for fv in result["field_values"]:
    print(f"  {fv['field_name']}: {fv['value']}")
    if fv["quote"]:
        print(f"    Evidence: \"{fv['quote']}\"")
    if fv["confidence"]:
        print(f"    Confidence: {fv['confidence']:.1%}")
    if fv["score"]:
        print(f"    Score: {fv['score']}")

# Evidence spans (where data was found in transcript)
print("\nEvidence:")
for ev in result["evidence"]:
    print(f"  [{ev['timestamp_start']:.1f}s - {ev['timestamp_end']:.1f}s]")
    print(f"  Speaker: {ev['speaker']}")
    print(f"  \"{ev['text']}\"")

Getting Schema Results for a Meeting

# Get all schema results for a meeting
results = requests.get(
    f"https://app.mavera.io/api/v1/meetings/{meeting_id}/schema-results",
    headers=headers
).json()

print(f"Schema results ({results['total']}):")
for sr in results["data"]:
    print(f"\n{sr['schema_name']} ({sr['schema_category']})")
    print(f"  Overall Score: {sr['overall_score']}")

    for fv in sr["field_values"]:
        print(f"  {fv['field_label']}: {fv['value']}")

# Filter by schema
discovery_results = requests.get(
    f"https://app.mavera.io/api/v1/meetings/{meeting_id}/schema-results",
    headers=headers,
    params={"schema_id": schema_id}
).json()

# Exclude evidence (smaller response)
compact_results = requests.get(
    f"https://app.mavera.io/api/v1/meetings/{meeting_id}/schema-results",
    headers=headers,
    params={"include_evidence": "false"}
).json()

Deleting a Schema

You can only delete schemas that you created. Built-in schemas cannot be deleted.
result = requests.delete(
    f"https://app.mavera.io/api/v1/meetings/schemas/{schema_id}",
    headers=headers
).json()

if result["deleted"]:
    print(f"Schema {result['id']} deleted")

Best Practices

Choose the right format for your use case:
  • segments: Best for programmatic analysis, search, or integration with other tools
  • text: Best for human reading or document generation
  • srt: Best for video players or accessibility features
Design schemas that can be applied across multiple meetings:
# Good: Generic qualification schema
{
    "name": "Qualification Framework",
    "category": "qualification",
    "fields": [
        {"name": "budget", "field_type": "enum", ...},
        {"name": "authority", "field_type": "person", ...},
        {"name": "need", "field_type": "text", ...},
        {"name": "timeline", "field_type": "date", ...}
    ]
}
When requires_evidence: true is set on a field, the AI includes the exact transcript quote that supports the extracted value. Use this to verify accuracy:
for fv in result["field_values"]:
    if fv["quote"]:
        print(f"Verified: {fv['field_name']} = {fv['value']}")
        print(f"  Source: \"{fv['quote']}\"")
For long meetings, filter transcripts by time range to focus on specific segments:
# Get just the first 10 minutes
intro = requests.get(
    f"{base_url}/transcript",
    params={"start_time": 0, "end_time": 600}
).json()

# Get the closing discussion (last 5 minutes)
# First, get full duration
full = requests.get(f"{base_url}/transcript").json()
duration = full["duration_seconds"]

closing = requests.get(
    f"{base_url}/transcript",
    params={"start_time": duration - 300}
).json()
Transcripts and analysis are only available once processing is complete:
meeting = get_meeting(meeting_id)

if meeting["status"] != "done":
    print(f"Meeting still processing: {meeting['status']}")
    return

# Safe to access transcript and analysis
transcript = get_transcript(meeting_id)
analysis = get_analysis(meeting_id)

Use Cases

CRM Integration

Extract qualification data and sync to Salesforce, HubSpot, or other CRMs using schema field mappings

Sales Coaching

Analyze coaching metrics like talk ratios, question rates, and objection handling to improve rep performance

Meeting Notes

Auto-generate meeting summaries, action items, and decision logs

Compliance

Extract and verify required disclosures or compliance statements from recorded calls

Meetings API Reference

See the full API specification for Meetings endpoints

Schemas API Reference

See the full API specification for Schema endpoints