惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Help Net Security
Help Net Security
S
Schneier on Security
Security Latest
Security Latest
C
Cyber Attacks, Cyber Crime and Cyber Security
博客园_首页
K
Kaspersky official blog
B
Blog
雷峰网
雷峰网
MyScale Blog
MyScale Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
人人都是产品经理
人人都是产品经理
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
T
Threatpost
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Latest news
Latest news
J
Java Code Geeks
W
WeLiveSecurity
GbyAI
GbyAI
V
Vulnerabilities – Threatpost
S
Secure Thoughts
IT之家
IT之家
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 叶小钗
Engineering at Meta
Engineering at Meta
S
Security @ Cisco Blogs
罗磊的独立博客
M
MIT News - Artificial intelligence
Blog — PlanetScale
Blog — PlanetScale
Stack Overflow Blog
Stack Overflow Blog
月光博客
月光博客
P
Proofpoint News Feed
博客园 - 聂微东
云风的 BLOG
云风的 BLOG
N
Netflix TechBlog - Medium
D
DataBreaches.Net
S
SegmentFault 最新的问题
V
Visual Studio Blog
V
V2EX
The Register - Security
The Register - Security
N
News | PayPal Newsroom
aimingoo的专栏
aimingoo的专栏
C
Cybersecurity and Infrastructure Security Agency CISA
N
News and Events Feed by Topic
Hacker News: Ask HN
Hacker News: Ask HN
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Google DeepMind News
Google DeepMind News
Webroot Blog
Webroot Blog
NISL@THU
NISL@THU
D
Darknet – Hacking Tools, Hacker News & Cyber Security

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Record and transcribe meetings with the Nylas Notetaker API
Qasim · 2026-06-22 · via DEV Community

Meeting notes are the feature everyone wants and nobody wants to build. The hard part isn't the summary — an LLM handles that. The hard part is getting into the meeting: a bot that joins Zoom, Google Meet, and Microsoft Teams, survives each platform's waiting room and admission flow, records cleanly, and produces a transcript you can feed downstream. Each provider has its own join mechanics, and none of them ships a tidy "record this meeting" API.

The Nylas Notetaker API is that bot as a service. You point it at a meeting link, it joins on schedule, records, and generates a transcript, and you fetch the recording and transcript through one endpoint. This post walks the Notetaker surface from the HTTP API and the Nylas CLI, which mirrors the whole lifecycle for terminal use and quick testing.

I work on the CLI, so the terminal commands below are exactly what I run when I'm testing a notetaker against a live meeting.

Two ways to run a notetaker: grant-scoped or standalone

Before any code, there's one architectural choice worth understanding, because it changes the endpoint you call.

A grant-scoped notetaker is tied to a connected account and lives under /v3/grants/{grant_id}/notetakers. Use it when the bot acts on behalf of a specific user — it can read that user's calendar and join their meetings as them.

A standalone notetaker has no grant at all and lives under /v3/notetakers. You hand it a raw meeting link and it joins, no connected account required. This is the one to reach for when you just have a URL and want a recording — a public webinar, a meeting on an account you haven't connected, or a system that deals in links rather than users.

Same request body, same lifecycle, same media output; the only difference is whether there's a grant_id in the path. See the Notetaker overview for how both models fit together.

Before you begin

You need a Nylas API key. If you're using a grant-scoped notetaker you also need a connected account; for standalone, the API key alone is enough. The CLI gets you started:

nylas init        # create an account, generate an API key
nylas auth login  # only needed for grant-scoped notetakers

The supported meeting providers are Zoom, Google Meet, and Microsoft Teams. Any meeting link from those three works as the target.

Send a notetaker into a meeting

Creating a notetaker is one call. The only required field is the meeting link; everything else has a sensible default. The CLI joins immediately if you don't pass a time:

# Join right now
nylas notetaker create --meeting-link "https://zoom.us/j/123456789"

# Join at a specific time, with a custom display name
nylas notetaker create \
  --meeting-link "https://meet.google.com/abc-defg-hij" \
  --join-time "2026-06-23 14:00" \
  --bot-name "Acme Notetaker"

The --bot-name flag sets what the other participants see in the attendee list, which matters more than it sounds — a bot labeled "Acme Notetaker" reads as intentional, while a generic name makes people wonder who joined. The --join-time flag accepts an absolute time, a relative offset like 30m, or natural phrasing like tomorrow 9am.

Over HTTP, the request body fields are meeting_link (required), join_time, name, and meeting_settings:

curl --request POST \
  --url "https://api.us.nylas.com/v3/grants/<GRANT_ID>/notetakers" \
  --header "Authorization: Bearer <NYLAS_API_KEY>" \
  --header "Content-Type: application/json" \
  --data '{
    "meeting_link": "https://meet.google.com/abc-defg-hij",
    "name": "Acme Notetaker",
    "meeting_settings": {
      "video_recording": true,
      "audio_recording": true,
      "transcription": true
    }
  }'

For a standalone notetaker, drop the grant from the path and POST the same body to /v3/notetakers. The meeting_settings object controls what gets captured — video_recording, audio_recording, and transcription toggles. They aren't fully independent, though: if transcription is true, both video_recording and audio_recording must also be true, because the transcript is generated from the recording. So "transcript only, no recording" isn't a valid combination — you can record audio-only, but a transcript always implies a recording exists.

There's also a transcription_settings object with an expected_languages array. It's a language declaration, not translation: the hints help the speech recognizer pick between the languages you expect in the meeting, and Notetaker never translates the transcript or forces it into one language. The full request body is in the invite notetaker reference, and the CLI flags are at notetaker create.

Follow the lifecycle

A notetaker moves through states, and your app usually waits for it to finish before pulling media. The CLI's --state filter accepts friendly names — scheduled (created, waiting to join), connecting, attending (in the meeting, recording), complete (done, media ready), cancelled, and failed. The raw API state field is more granular: a notetaker object surfaces values like waiting_for_entry, processing, and available (the API's equivalent of the CLI's "complete"). The list endpoint's state query filter uses its own enum (for example media_available), so don't assume the filter value and the object's state string are spelled identically. List notetakers and filter by state to find the ones worth acting on:

# All notetakers (20 by default)
nylas notetaker list

# Only the finished ones, ready for media
nylas notetaker list --state complete

The --state filter is how you build a polling loop: ask for complete notetakers, process their media, move on. The CLI returns 20 by default and the notetaker list command documents the rest. To inspect a single notetaker's current state and metadata, use nylas notetaker show <notetaker-id>. In production, rather than polling, you'd subscribe to notetaker webhooks so Nylas tells you when a session reaches complete.

Pull the recording and transcript

Once a notetaker is complete, its media is ready. The media endpoint returns URLs for the recording (the video or audio file) and the transcript (the text). One thing to watch: these URLs expire, so download promptly rather than storing the URL and fetching it days later.

nylas notetaker media <notetaker-id>

Over HTTP, it's a GET against the notetaker's media path:

curl --request GET \
  --url "https://api.us.nylas.com/v3/grants/<GRANT_ID>/notetakers/<NOTETAKER_ID>/media" \
  --header "Authorization: Bearer <NYLAS_API_KEY>"

The response gives you the download links; pull the bytes to your own storage immediately if you need them long-term. From there the transcript is plain text you can hand to an LLM for a summary, action items, or a searchable index. The get notetaker media reference and the notetaker media command cover the details.

Leave, cancel, or delete — they're different

This is the distinction that catches people, because the three sound interchangeable and aren't:

  • Leave tells an active notetaker to exit the meeting now. It stops the recording, triggers media generation, and keeps the notetaker record and its media. Use it to cleanly end a live recording early.
  • Cancel stops a scheduled notetaker before it ever joins. There's nothing to record, so there's no media. The API exposes this as a dedicated cancel endpoint.
  • Delete permanently removes the notetaker and all its media. If the notetaker is still scheduled or active, delete cancels it first, and any recording or transcript you haven't already downloaded is lost. In the CLI, cancel and rm are aliases of delete.

From the CLI:

# End a live recording but keep the media
nylas notetaker leave <notetaker-id>

# Remove a notetaker and its media
nylas notetaker delete <notetaker-id>

Reaching for delete when you meant leave permanently throws away the recording you just made, so it's worth getting right. The notetaker delete command and the API's separate leave and cancel endpoints keep these operations distinct on purpose.

Capabilities and notes

Dimension Value Notes
Providers Zoom, Google Meet, Microsoft Teams Any meeting link from these three
Models Grant-scoped and standalone /v3/grants/{id}/notetakers vs /v3/notetakers
Capture toggles video, audio, transcription meeting_settings flags; transcription requires both recordings on
Media URLs Expiring Download promptly; store your own copy
Lifecycle scheduled → connecting → attending → complete Simplified CLI states; the API exposes more granular values

The standalone model is the feature I'd point a new integration at first. Not needing a connected account to record a meeting removes the entire OAuth step for the common case where you already have a link, and you can always move to grant-scoped notetakers later when the bot needs to act as a specific user.

Wrapping up

The value here is that the genuinely hard part — a bot that reliably joins three different meeting platforms and comes back with clean media — is the part you don't write. You make one call with a meeting link, wait for complete, and pull a recording and transcript. The summary layer on top is a solved problem; getting a trustworthy transcript out of a live meeting was the bottleneck, and that's what the API removes. The CLI mirrors the full lifecycle, so you can record a real meeting and inspect the transcript from your terminal before committing any of it to code.

Where to go next:


Written by Qasim Muhammad and Pouya Sanooei.