---
title: Meeting transcripts
description: "Zoom AI Companion transcripts land as markdown in a private S3 bucket, mirrored to a local folder agents grep."
---

# Meeting transcripts

Every meeting becomes one markdown file an agent can read. No video, no
database, no vendor.

The two rulings that shape everything else:

- **Fetch the AI Companion retained transcript**, not the cloud recording one.
  No recording means no storage quota and no dependence on someone pressing
  Record.
- **A private S3 bucket is the system of record.** A local mirror, outside any
  git repo, is a cache. That follows an existing standard — see
  [Storage](/be-pipeline-meeting-transcripts/storage).

```text
  ZOOM                     THE MAC                      DURABLE
  ┌──────────────┐
  │ AI Companion │
  │   summary    │  auto-start required
  │      ↓       │
  │  transcript  │
  │  retained    │
  └──────┬───────┘
         │  GET /meetings/meeting_summaries?from=&to=   ENUMERATE
         │  GET /meetings/<meeting-uuid>/transcript     FETCH (VTT)
         ▼
   ┌───────────────┐
   │ launchd, 06:00│  polls a 7-day overlapping window.
   │ + on wake     │  Missed a day? Next run heals it.
   └──────┬────────┘
          │  VTT ─▶ markdown + YAML frontmatter
          ▼
   ┌───────────────┐        aws s3 cp        ┌──────────────────┐
   │ ~/transcripts │ ─────────────────────▶  │ private S3 bucket│
   │  local mirror │ ◀───── aws s3 sync ──── │ SYSTEM OF RECORD │
   │  (cache)      │                         │ versioned, SSE   │
   └──────┬────────┘                         └──────────────────┘
          │
          ▼  Glob / Grep / Read — no creds, no network, no SDK
     ┌─────────┐
     │  agent  │
     └─────────┘
```

## Where transcripts must never go: `docs/`

Not in this repo. Two reasons, both hard:

1. `npm run validate` caps a page at 500 words. A transcript is thousands.
2. This wiki renders publicly right now. Google sign-in is built but parked in
   unmerged PR #17. A client transcript here is a disclosure, not a typo.

The wiki holds the spec and the pointers. Never the text.

## The pages

| Page | What it settles |
|---|---|
| [What Zoom gives you](/be-pipeline-meeting-transcripts/what-zoom-gives-you) | Three artifacts, one of them right |
| [Zoom settings](/be-pipeline-meeting-transcripts/zoom-settings) | The toggles an admin must flip first |
| [Zoom API](/be-pipeline-meeting-transcripts/zoom-api) | Endpoints, scopes, app type, gotchas |
| [Pipeline](/be-pipeline-meeting-transcripts/pipeline) | Poll, not webhooks. Enumerate then fetch |
| [File shape](/be-pipeline-meeting-transcripts/file-shape) | Naming, frontmatter, VTT cleanup |
| [Storage](/be-pipeline-meeting-transcripts/storage) | S3 is the record. The mirror is a cache |
| [Growth path](/be-pipeline-meeting-transcripts/growth-path) | What to build later, and the trigger for each |
| [Consent](/be-pipeline-meeting-transcripts/consent) | Internal vs client. Needs a human ruling |
| [Open questions](/be-pipeline-meeting-transcripts/open-questions) | Four decisions still owed |

Scale: about 13.5 MB and 750 files a year. S3 bills under $0.01/month for that.
Cost is not an argument for or against anything here.

Every example on these pages uses fake names — `Sample Person`, `ACME Corp`,
`<meeting-uuid>`. Keep it that way. This wiki is public.
