> ## 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.

# Meetings

> Access meeting recordings, transcripts, AI analysis, and extract structured data with custom schemas

## 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

<Info>
  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.
</Info>

## Typical Flow

<Steps>
  <Step title="Create a meeting">
    `POST /meetings` with `meeting_url`, `title`, and optional `join_at`. Bot joins the call and records.
  </Step>

  <Step title="Monitor status">
    Poll `GET /meetings/{id}` or list meetings. Wait until `status` is `done` before accessing transcript and analysis.
  </Step>

  <Step title="Get transcript">
    `GET /meetings/{id}/transcript` with optional `format` (segments, text, srt) and time range.
  </Step>

  <Step title="Get analysis">
    `GET /meetings/{id}/analysis` for summary, tasks, decisions, highlights, coaching metrics.
  </Step>

  <Step title="Run schema (optional)">
    `POST /meetings/{id}/schemas/{schema_id}/run` to extract structured data (e.g. qualification fields).
  </Step>
</Steps>

<CardGroup cols={2}>
  <Card title="Meeting Recordings" icon="video">
    Access recordings from Zoom, Google Meet, Microsoft Teams, and other platforms
  </Card>

  <Card title="Transcripts" icon="closed-captioning">
    Get transcripts in segments, plain text, or SRT subtitle format with speaker attribution
  </Card>

  <Card title="AI Analysis" icon="brain">
    Summaries, key takeaways, highlights, tasks, decisions, and coaching metrics
  </Card>

  <Card title="Custom Schemas" icon="table-columns">
    Define and run schemas to extract structured data like qualification info or objection handling
  </Card>
</CardGroup>

## Meeting Lifecycle

Meetings go through the following statuses:

| Status              | Description                               |
| ------------------- | ----------------------------------------- |
| `pending`           | Bot scheduled to join                     |
| `joining_call`      | Bot is joining the meeting                |
| `in_waiting_room`   | Bot in meeting waiting room               |
| `in_call_recording` | Bot is actively recording                 |
| `call_ended`        | Meeting ended, processing starting        |
| `recording_done`    | Recording complete                        |
| `done`              | All processing complete, ready for access |
| `fatal`             | Error occurred during recording           |
| `cancelled`         | Meeting 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.

<CodeGroup>
  ```python Python theme={"dark"}
  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']}")
  ```

  ```javascript JavaScript theme={"dark"}
  const apiKey = "mvra_live_your_key_here";
  const headers = {
    "Authorization": `Bearer ${apiKey}`,
    "Content-Type": "application/json"
  };

  // Create a bot to join immediately
  const meeting = await fetch("https://app.mavera.io/api/v1/meetings", {
    method: "POST",
    headers,
    body: JSON.stringify({
      meeting_url: "https://zoom.us/j/123456789",
      title: "Sales Discovery Call",
      bot_name: "Mavera Notetaker"
    })
  }).then(r => r.json());

  console.log(`Meeting ID: ${meeting.id}`);
  console.log(`Status: ${meeting.status}`);

  // Schedule for later
  const scheduledMeeting = await fetch("https://app.mavera.io/api/v1/meetings", {
    method: "POST",
    headers,
    body: JSON.stringify({
      meeting_url: "https://meet.google.com/abc-defg-hij",
      title: "Weekly Standup",
      join_at: "2024-03-20T14:00:00Z"
    })
  }).then(r => r.json());
  ```

  ```bash cURL theme={"dark"}
  # Join immediately
  curl -X POST https://app.mavera.io/api/v1/meetings \
    -H "Authorization: Bearer mvra_live_your_key_here" \
    -H "Content-Type: application/json" \
    -d '{
      "meeting_url": "https://zoom.us/j/123456789",
      "title": "Sales Discovery Call",
      "bot_name": "Mavera Notetaker"
    }'

  # Schedule for later
  curl -X POST https://app.mavera.io/api/v1/meetings \
    -H "Authorization: Bearer mvra_live_your_key_here" \
    -H "Content-Type: application/json" \
    -d '{
      "meeting_url": "https://meet.google.com/abc-defg-hij",
      "title": "Weekly Standup",
      "join_at": "2024-03-20T14:00:00Z"
    }'
  ```
</CodeGroup>

### Supported Platforms

| Platform        | URL Pattern               | Example                                         |
| --------------- | ------------------------- | ----------------------------------------------- |
| Zoom            | `zoom.us/j/...`           | `https://zoom.us/j/123456789`                   |
| Google Meet     | `meet.google.com/...`     | `https://meet.google.com/abc-defg-hij`          |
| Microsoft Teams | `teams.microsoft.com/...` | `https://teams.microsoft.com/l/meetup-join/...` |
| Webex           | `webex.com/...`           | `https://company.webex.com/meet/...`            |

### Listing Meetings

<CodeGroup>
  ```python Python theme={"dark"}
  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)}")
  ```

  ```javascript JavaScript theme={"dark"}
  const apiKey = "mvra_live_your_key_here";
  const headers = { "Authorization": `Bearer ${apiKey}` };

  // List meetings
  const meetings = await fetch("https://app.mavera.io/api/v1/meetings", { headers })
    .then(r => r.json());

  meetings.data.forEach(meeting => {
    console.log(`${meeting.title} - ${meeting.status}`);
    console.log(`  Participants: ${meeting.participant_count}`);
  });

  // Filter by status
  const completed = await fetch(
    "https://app.mavera.io/api/v1/meetings?status=done",
    { headers }
  ).then(r => r.json());

  // Paginate
  async function getAllMeetings() {
    const allMeetings = [];
    let cursor = null;

    while (true) {
      const url = new URL("https://app.mavera.io/api/v1/meetings");
      url.searchParams.set("limit", "50");
      if (cursor) url.searchParams.set("cursor", cursor);

      const response = await fetch(url, { headers }).then(r => r.json());
      allMeetings.push(...response.data);

      if (!response.has_more) break;
      cursor = response.next_cursor;
    }

    return allMeetings;
  }
  ```

  ```bash cURL theme={"dark"}
  # List meetings
  curl https://app.mavera.io/api/v1/meetings \
    -H "Authorization: Bearer mvra_live_your_key_here"

  # Filter by status
  curl "https://app.mavera.io/api/v1/meetings?status=done" \
    -H "Authorization: Bearer mvra_live_your_key_here"

  # Filter by workspace
  curl "https://app.mavera.io/api/v1/meetings?workspace_id=ws_abc123" \
    -H "Authorization: Bearer mvra_live_your_key_here"
  ```
</CodeGroup>

### Getting Meeting Details

<CodeGroup>
  ```python Python theme={"dark"}
  # 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']}")
  ```

  ```javascript JavaScript theme={"dark"}
  const meeting = await fetch(
    `https://app.mavera.io/api/v1/meetings/${meetingId}`,
    { headers }
  ).then(r => r.json());

  console.log(`Title: ${meeting.title}`);
  console.log(`Status: ${meeting.status}`);
  console.log(`Participants: ${meeting.participant_count}`);

  // Transcript info
  if (meeting.transcript) {
    console.log(`Duration: ${meeting.transcript.duration_seconds}s`);
  }

  // Tasks
  meeting.tasks.forEach(task => {
    console.log(`Task: ${task.content} (${task.owner})`);
  });
  ```
</CodeGroup>

## Managing Meetings

### Cancelling a Meeting

Cancel a scheduled or in-progress meeting recording. The meeting record is kept but marked as cancelled.

<CodeGroup>
  ```python Python theme={"dark"}
  # 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']}")
  ```

  ```javascript JavaScript theme={"dark"}
  const result = await fetch(
    `https://app.mavera.io/api/v1/meetings/${meetingId}/cancel`,
    {
      method: "POST",
      headers: { ...headers, "Content-Type": "application/json" },
      body: JSON.stringify({ reason: "Meeting rescheduled" })
    }
  ).then(r => r.json());

  console.log(`Cancelled at: ${result.cancelled_at}`);
  ```

  ```bash cURL theme={"dark"}
  curl -X POST https://app.mavera.io/api/v1/meetings/meeting_123/cancel \
    -H "Authorization: Bearer mvra_live_your_key_here" \
    -H "Content-Type: application/json" \
    -d '{"reason": "Meeting rescheduled"}'
  ```
</CodeGroup>

### Deleting a Meeting

Permanently delete a meeting and all associated data including recordings, transcripts, and analysis.

<Warning>
  This action is irreversible. All data associated with the meeting will be permanently deleted.
</Warning>

<CodeGroup>
  ```python Python theme={"dark"}
  # 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")
  ```

  ```javascript JavaScript theme={"dark"}
  const result = await fetch(
    `https://app.mavera.io/api/v1/meetings/${meetingId}`,
    { method: "DELETE", headers }
  ).then(r => r.json());

  if (result.deleted) {
    console.log(`Meeting ${result.id} deleted`);
  }
  ```

  ```bash cURL theme={"dark"}
  curl -X DELETE https://app.mavera.io/api/v1/meetings/meeting_123 \
    -H "Authorization: Bearer mvra_live_your_key_here"
  ```
</CodeGroup>

### Accessing Recording URL

When a meeting is complete, you can access the recording URL:

<CodeGroup>
  ```python Python theme={"dark"}
  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")
  ```

  ```javascript JavaScript theme={"dark"}
  const meeting = await fetch(
    `https://app.mavera.io/api/v1/meetings/${meetingId}`,
    { headers }
  ).then(r => r.json());

  if (meeting.recording_url) {
    console.log(`Recording: ${meeting.recording_url}`);
  }
  ```
</CodeGroup>

## Transcripts

Get meeting transcripts in multiple formats for different use cases.

### Transcript Formats

| Format     | Description                                                 | Use Case                      |
| ---------- | ----------------------------------------------------------- | ----------------------------- |
| `segments` | Structured JSON with speaker, timestamps, word-level timing | Analysis, search, integration |
| `text`     | Plain text with speaker labels                              | Human reading, documents      |
| `srt`      | Subtitle format with timestamps                             | Video players, accessibility  |

### Getting Transcripts

<CodeGroup>
  ```python Python theme={"dark"}
  # 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()
  ```

  ```javascript JavaScript theme={"dark"}
  // Get structured transcript
  const transcript = await fetch(
    `https://app.mavera.io/api/v1/meetings/${meetingId}/transcript`,
    { headers }
  ).then(r => r.json());

  transcript.segments.forEach(seg => {
    console.log(`[${seg.start.toFixed(1)}s] ${seg.speaker}: ${seg.text}`);
  });

  // Get SRT format
  const srt = await fetch(
    `https://app.mavera.io/api/v1/meetings/${meetingId}/transcript?format=srt`,
    { headers }
  ).then(r => r.json());

  // Download as file
  const blob = new Blob([srt.content], { type: 'text/plain' });
  const url = URL.createObjectURL(blob);

  // Get time range
  const partial = await fetch(
    `https://app.mavera.io/api/v1/meetings/${meetingId}/transcript?start_time=300&end_time=600`,
    { headers }
  ).then(r => r.json());
  ```

  ```bash cURL theme={"dark"}
  # Get structured transcript
  curl https://app.mavera.io/api/v1/meetings/meeting_123/transcript \
    -H "Authorization: Bearer mvra_live_your_key_here"

  # Get SRT format
  curl "https://app.mavera.io/api/v1/meetings/meeting_123/transcript?format=srt" \
    -H "Authorization: Bearer mvra_live_your_key_here"

  # Get specific time range
  curl "https://app.mavera.io/api/v1/meetings/meeting_123/transcript?start_time=300&end_time=600" \
    -H "Authorization: Bearer mvra_live_your_key_here"
  ```
</CodeGroup>

## AI Analysis

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

### Getting Analysis

<CodeGroup>
  ```python Python theme={"dark"}
  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']}")
  ```

  ```javascript JavaScript theme={"dark"}
  const analysis = await fetch(
    `https://app.mavera.io/api/v1/meetings/${meetingId}/analysis`,
    { headers }
  ).then(r => r.json());

  console.log(`Summary: ${analysis.summary}`);

  console.log("\nKey Takeaways:");
  analysis.key_takeaways.forEach(t => console.log(`  - ${t}`));

  console.log("\nHighlights:");
  analysis.highlights.forEach(h => {
    console.log(`  [${h.timestamp_start.toFixed(1)}s] ${h.speaker}`);
    console.log(`  "${h.quote}"`);
  });

  // Coaching metrics
  if (analysis.coaching_metrics) {
    const cm = analysis.coaching_metrics;
    console.log("\nCoaching Metrics:");
    console.log(`  Talk ratio: ${(cm.overall_host_talk_ratio * 100).toFixed(1)}%`);
    console.log(`  Questions: ${cm.total_questions_asked}`);
  }
  ```
</CodeGroup>

### Analysis Components

| Component          | Description                                             |
| ------------------ | ------------------------------------------------------- |
| `summary`          | AI-generated meeting summary                            |
| `key_takeaways`    | List of key points from the meeting                     |
| `topics`           | Topics discussed                                        |
| `sentiment`        | Overall meeting sentiment                               |
| `highlights`       | Key moments with quotes and timestamps                  |
| `tasks`            | Action items extracted from discussion                  |
| `decisions`        | Decisions made during the meeting                       |
| `coaching_metrics` | Sales coaching analytics (talk ratios, questions, etc.) |
| `schema_results`   | Structured 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

| Category               | Description                             |
| ---------------------- | --------------------------------------- |
| `sales_discovery`      | Sales discovery call data               |
| `qualification`        | Lead qualification (MEDDIC, BANT, etc.) |
| `objection_competitor` | Objection and competitor mentions       |
| `cs_health`            | Customer success health metrics         |
| `product_feedback`     | Product feedback and feature requests   |
| `custom`               | Custom schemas you define               |

### Field Types

| Type           | Description                | Example             |
| -------------- | -------------------------- | ------------------- |
| `text`         | Short text (max 500 chars) | Company name        |
| `long_text`    | Long text (max 2000 chars) | Summary             |
| `enum`         | Single choice from options | Deal stage          |
| `multi_select` | Multiple choices           | Pain points         |
| `number`       | Numeric value              | Budget amount       |
| `boolean`      | True/false                 | Next step confirmed |
| `list`         | Array of strings           | Stakeholders        |
| `person`       | Name, email, role          | Decision maker      |
| `date`         | Date (YYYY-MM-DD)          | Expected close date |

### Creating a Schema

<CodeGroup>
  ```python Python theme={"dark"}
  # 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']}")
  ```

  ```javascript JavaScript theme={"dark"}
  const schema = await fetch("https://app.mavera.io/api/v1/meetings/schemas", {
    method: "POST",
    headers: { ...headers, "Content-Type": "application/json" },
    body: JSON.stringify({
      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"
        }
      ]
    })
  }).then(r => r.json());

  console.log(`Schema created: ${schema.id}`);
  ```

  ```bash cURL theme={"dark"}
  curl -X POST https://app.mavera.io/api/v1/meetings/schemas \
    -H "Authorization: Bearer mvra_live_your_key_here" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Sales Discovery Schema",
      "category": "sales_discovery",
      "fields": [
        {
          "name": "budget_range",
          "label": "Budget Range",
          "field_type": "enum",
          "enum_options": ["<$10k", "$10k-$50k", "$50k-$100k", ">$100k"],
          "requires_evidence": true
        },
        {
          "name": "decision_makers",
          "label": "Decision Makers",
          "field_type": "list"
        }
      ]
    }'
  ```
</CodeGroup>

### Listing Schemas

<CodeGroup>
  ```python Python theme={"dark"}
  # 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()
  ```

  ```javascript JavaScript theme={"dark"}
  const schemas = await fetch(
    "https://app.mavera.io/api/v1/meetings/schemas",
    { headers }
  ).then(r => r.json());

  schemas.data.forEach(schema => {
    const builtIn = schema.is_built_in ? "[Built-in]" : "";
    console.log(`${builtIn} ${schema.name}`);
    console.log(`  Category: ${schema.category}, Fields: ${schema.field_count}`);
  });
  ```
</CodeGroup>

### Running a Schema on a Meeting

<CodeGroup>
  ```python Python theme={"dark"}
  # 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']}\"")
  ```

  ```javascript JavaScript theme={"dark"}
  const result = await fetch(
    `https://app.mavera.io/api/v1/meetings/${meetingId}/schemas/${schemaId}/run`,
    { method: "POST", headers }
  ).then(r => r.json());

  console.log(`Schema: ${result.schema_name}`);
  console.log(`Overall Score: ${result.overall_score}`);

  result.field_values.forEach(fv => {
    console.log(`${fv.field_name}: ${fv.value}`);
    if (fv.quote) {
      console.log(`  Evidence: "${fv.quote}"`);
    }
  });
  ```

  ```bash cURL theme={"dark"}
  curl -X POST https://app.mavera.io/api/v1/meetings/meeting_123/schemas/schema_456/run \
    -H "Authorization: Bearer mvra_live_your_key_here"
  ```
</CodeGroup>

### Getting Schema Results for a Meeting

<CodeGroup>
  ```python Python theme={"dark"}
  # 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()
  ```

  ```javascript JavaScript theme={"dark"}
  const results = await fetch(
    `https://app.mavera.io/api/v1/meetings/${meetingId}/schema-results`,
    { headers }
  ).then(r => r.json());

  results.data.forEach(sr => {
    console.log(`\n${sr.schema_name}`);
    console.log(`  Score: ${sr.overall_score}`);
    sr.field_values.forEach(fv => {
      console.log(`  ${fv.field_label}: ${fv.value}`);
    });
  });
  ```
</CodeGroup>

### Deleting a Schema

<Warning>
  You can only delete schemas that you created. Built-in schemas cannot be deleted.
</Warning>

<CodeGroup>
  ```python Python theme={"dark"}
  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")
  ```

  ```javascript JavaScript theme={"dark"}
  const result = await fetch(
    `https://app.mavera.io/api/v1/meetings/schemas/${schemaId}`,
    { method: "DELETE", headers }
  ).then(r => r.json());

  if (result.deleted) {
    console.log(`Schema ${result.id} deleted`);
  }
  ```
</CodeGroup>

## Best Practices

<AccordionGroup>
  <Accordion title="Use appropriate transcript format">
    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
  </Accordion>

  <Accordion title="Create reusable schemas">
    Design schemas that can be applied across multiple meetings:

    ```python theme={"dark"}
    # 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", ...}
        ]
    }
    ```
  </Accordion>

  <Accordion title="Use evidence for verification">
    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:

    ```python theme={"dark"}
    for fv in result["field_values"]:
        if fv["quote"]:
            print(f"Verified: {fv['field_name']} = {fv['value']}")
            print(f"  Source: \"{fv['quote']}\"")
    ```
  </Accordion>

  <Accordion title="Handle time range filtering">
    For long meetings, filter transcripts by time range to focus on specific segments:

    ```python theme={"dark"}
    # 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()
    ```
  </Accordion>

  <Accordion title="Check meeting status before accessing data">
    Transcripts and analysis are only available once processing is complete:

    ```python theme={"dark"}
    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)
    ```
  </Accordion>
</AccordionGroup>

## Use Cases

<CardGroup cols={2}>
  <Card title="CRM Integration" icon="database">
    Extract qualification data and sync to Salesforce, HubSpot, or other CRMs using schema field mappings
  </Card>

  <Card title="Sales Coaching" icon="graduation-cap">
    Analyze coaching metrics like talk ratios, question rates, and objection handling to improve rep performance
  </Card>

  <Card title="Meeting Notes" icon="note-sticky">
    Auto-generate meeting summaries, action items, and decision logs
  </Card>

  <Card title="Compliance" icon="shield">
    Extract and verify required disclosures or compliance statements from recorded calls
  </Card>
</CardGroup>

<CardGroup cols={2}>
  <Card title="Meetings API Reference" icon="video" href="/api-reference/meetings/list-meetings">
    See the full API specification for Meetings endpoints
  </Card>

  <Card title="Schemas API Reference" icon="table-columns" href="/api-reference/meetings/list-schemas">
    See the full API specification for Schema endpoints
  </Card>
</CardGroup>
