The problem it solves
Local journalists and residents want to know what officials said about a zoning change, a budget item or a school policy. Finding it means scrubbing through hours of video across many meetings. Agendas and minutes rarely capture the full discussion, and many local newsrooms no longer have reporters attending every meeting.
What to include in your first version
- Automatic ingestion of every meeting from the body's channel
- Speaker labels so you can search by official
- Topic and keyword search across years of meetings
- Alerts when a topic or address is discussed
- Shareable links to the exact moment in the recording
How to build it, step by step
- 01
Collect meeting videos
Resolve the council's channel or meeting playlist and keep checking for new uploads.
- 02
Transcribe with speakers
Use ASR with speakerLabels enabled, and speakerId with known names, so each passage is attributed to a speaker. Meetings are long, so use the estimate endpoint to preview cost.
- 03
Index by meeting and speaker
Store paragraphs with meeting date, speaker and timestamp, and add full-text and semantic search.
- 04
Add alerts
Let users save searches such as a street name or policy topic and email them when it comes up in a new meeting.
Starter code
This idea is built on the "Recipe 3: Bulk-load a playlist into a knowledge base" pattern. Swap in your own channels, prompts and storage.
import requests
API = "https://www.youtubetranscript.dev/api/v2"
HEADERS = {"Authorization": "Bearer yt_sk_live_YOUR_KEY"}
playlist = requests.post(f"{API}/playlists/resolve", headers=HEADERS,
json={"playlist_url": "https://www.youtube.com/playlist?list=PLAYLIST_ID",
"limit": 100}).json()
ids = [v["video_id"] for v in playlist["items"]]
batch = requests.post(f"{API}/batch", headers=HEADERS, json={
"video_ids": ids,
"format": {"timestamp": True, "paragraphs": True},
}).json()
# Large batches run async: poll GET /batch/{batch_id} until status is "completed"
for r in batch.get("results", []):
if r["status"] == "completed":
for p in r["data"]["transcript"].get("paragraphs") or []:
store(video_id=r["video_id"], start=p["start"], text=p["text"]) # your vector DBWhy it's worth building
Local news outlets, advocacy groups and real estate or policy firms will pay for alerts and research tools. Civic projects often run on grants or offer a free public archive with paid alerts.
Mistakes to avoid
- Relying on automatic captions for long meetings with many speakers: speaker labels make the archive far more useful.
- Underestimating length: meetings run for hours, so estimate ASR credits before transcribing a backlog.
- Publishing without context: link every quote to the recording so readers can hear it themselves.
Questions about this idea
Can I transcribe city council meetings from YouTube?
Yes. Use captions when they exist, or AI speech recognition with speaker labels for more readable transcripts of long meetings.
How do I identify who is speaking?
Enable speaker labels to separate speakers, and speaker identification with a list of known names or roles to attribute them.
How much does it cost to transcribe a three-hour meeting?
AI speech recognition costs about 40 credits per hour before add-ons. Use the estimate endpoint to see the exact cost before you start.