Your Best Ideas Happen When You Can't Type
You're walking back from a meeting. Three action items, two key decisions, and a question for the design team — all in your head, fading fast.
You get back to your desk. Open Notion. Create a new page. Pick the workspace. Start typing. By the third bullet point, you've already forgotten the nuance of the second decision.
Or: you're in a meeting, trying to take notes. But typing while listening splits your attention. You capture fragments — half-sentences, missing context, no structure. The notes are useless by tomorrow.
What if you could just speak?
"Meeting with product team. Three decisions. First, we're pushing the launch to April 15th because the onboarding flow isn't ready. Second, pricing stays at 7.99 but we're adding a student discount at 40 percent off. Third, the comparison page needs real latency benchmarks, not just our claim. Action items: Alex updates the launch timeline, Maria runs the pricing A/B test, I need to get benchmark data from engineering by Friday."
Release. SpeechButton transcribes your speech, transforms it into structured markdown, and sends it to Notion's API. A new page appears:
Meeting with Product Team — April 4, 2026
Decisions
- Launch pushed to April 15 — onboarding flow not ready
- Pricing stays at $7.99 — adding 40% student discount
- Comparison page needs real benchmarks — not just latency claims
Action Items
- Alex: Update launch timeline
- Maria: Run pricing A/B test
- Me: Get benchmark data from engineering by Friday
Structured, formatted, in Notion. From 40 seconds of speaking. You captured everything while it was fresh.
How It Works
Your voice ──▶ SpeechButton STT ──▶ Transform script ──▶ Notion API
(7ms) (Parakeet V3, (structures as (creates page
100% offline) markdown/blocks) with content)
- SpeechButton captures and transcribes your voice locally on Apple Neural Engine (parakeet-tdt-0.6b-v3-int8)
- Transform prompt (
prompts/notion_page.md) structures the raw transcript — by default using a local AI model entirely on-device - A Python script (
integrations/send_notion.py) calls Notion's REST API to create or append a page
Transform options
Local AI (default)
transform = "prompts/notion_page.md" — runs entirely on your Mac. No API key, no cost, no data leaves the device until the Notion API call.
Claude API
Set transform = "transforms/notion_claude.sh" and provide ANTHROPIC_API_KEY. Better at complex multi-topic notes; costs ~$0.001 per note.
Setup
Five steps. Under ten minutes from nothing to your first voice-created Notion page.
Step 1: Create a Notion integration
- Go to https://www.notion.so/my-integrations
- Click "+ New integration"
- Name it "Voice Notes", select your workspace
- Copy the token (starts with
ntn_)
Step 2: Connect a database or page
Two modes — pick one:
Mode 1: Append to a page (NOTION_PAGE_ID)
Open the target page, share it with your integration via "..." → Add Connections", then copy the 32-char hex ID from the URL and set NOTION_PAGE_ID=e4a5bfb0-1234-.... Each invocation appends blocks to this page.
Mode 2: Create pages in a database (NOTION_DATABASE_ID)
Open the database, share it with your integration, copy the ID from the URL, and set NOTION_DATABASE_ID=xxx. Each invocation creates a new database entry with the first line as the title.
Required: Without sharing, the API returns 404. The integration has zero access by default.
Step 3: SpeechButton config.toml
Add a [[hotkey]] block. The default transform uses local AI — no API key needed.
[global] model = "parakeet-tdt-0.6b-v3-int8" # Notion — hold RightCommand, speak, release [[hotkey]] key = "RightCommand" channel = "7" name = "notion" transform = "prompts/notion_page.md" exec = "NOTION_API_KEY=ntn_xxx NOTION_DATABASE_ID=xxx integrations/send_notion.py"
Replace ntn_xxx with your integration token and set either NOTION_DATABASE_ID or NOTION_PAGE_ID.
Step 4: Prompt file
Save as prompts/notion_page.md. This tells the Local AI how to structure your speech for Notion:
You are a note formatter for Notion. Convert raw speech into well-structured markdown for a Notion page. Rules: - Start with a clear heading (## Title) - Use bullet points for lists - Use numbered lists for steps or sequences - Clean up filler words (um, uh, like) - Fix grammar and punctuation - Keep the speaker's intent and tone - If it sounds like meeting notes, format with attendees and action items - If it sounds like a task, format with description and checklist Output clean markdown only, no commentary.
Step 5: Integration script
Save as integrations/send_notion.py inside your SpeechButton config directory. Reads transformed text from stdin and calls Notion's API — no third-party libraries required.
#!/usr/bin/env python3 """Create a Notion page or append to existing page.""" import json, os, sys, urllib.request API = "https://api.notion.com/v1" def notion(key, method, path, body=None): req = urllib.request.Request(f"{API}{path}", json.dumps(body).encode() if body else None, method=method, headers={"Authorization": f"Bearer {key}", "Content-Type": "application/json", "Notion-Version": "2022-06-28"}) return json.loads(urllib.request.urlopen(req, timeout=15).read()) def text_to_blocks(text): blocks = [] for p in text.split("\n\n"): p = p.strip() if not p: continue if p.startswith("## "): blocks.append({"object":"block","type":"heading_2", "heading_2":{"rich_text":[{"type":"text","text":{"content":p[3:]}}]}}) elif p.startswith("- "): for line in p.split("\n"): item = line.lstrip("- ").strip() if item: blocks.append({"object":"block","type":"bulleted_list_item", "bulleted_list_item":{"rich_text":[{"type":"text","text":{"content":item}}]}}) else: blocks.append({"object":"block","type":"paragraph", "paragraph":{"rich_text":[{"type":"text","text":{"content":p}}]}}) return blocks def main(): text = sys.stdin.read().strip() if not text: sys.exit(0) key = os.environ.get("NOTION_API_KEY") if not key: print("NOTION_API_KEY not set", file=sys.stderr); sys.exit(1) db_id = os.environ.get("NOTION_DATABASE_ID") page_id = os.environ.get("NOTION_PAGE_ID") blocks = text_to_blocks(text) if page_id: notion(key, "PATCH", f"/blocks/{page_id}/children", {"children": blocks}) print("Notion: appended to page") elif db_id: title = text.split("\n")[0][:80] result = notion(key, "POST", "/pages", { "parent": {"database_id": db_id}, "properties": {"Name": {"title": [{"text": {"content": title}}]}}, "children": blocks}) print(f"Notion: {result.get('url', 'created')}") if __name__ == "__main__": main()
chmod +x integrations/send_notion.py
Real Workflows
Meeting notes — capture everything, format nothing
You're in a 30-minute meeting. Instead of splitting attention between listening and typing, you speak your notes afterward while everything is fresh:
"Product sync April 4th. Attendees: Alex, Maria, James. We reviewed the Q2 roadmap. Key discussion: the auth rewrite is blocked on the security audit, estimated two more weeks. James proposed using feature flags to ship the UI changes independently. Agreed. Maria flagged that the analytics dashboard has a 3-second load time regression since last deploy. Action items: Alex files the analytics regression bug, James sets up feature flags for the auth UI, I schedule the security audit follow-up for next Thursday."
One continuous stream of speech becomes a fully structured Notion page with attendees, discussion summary, decisions, and action items. The AI transform handles the formatting — you just speak.
Quick thoughts — capture before they vanish
Walking, commuting, between meetings. Ideas are perishable.
"Idea for the onboarding flow. What if we show a 7ms latency comparison animation right in the setup wizard? User presses the hotkey, sees SpeechButton capture instantly versus a simulated 200ms competitor delay. Makes the speed advantage tangible before they even start using it."
A Notion page titled "Onboarding idea: latency comparison animation" with the full description. Captured in 12 seconds, retrievable forever.
Daily journal — append throughout the day
Use the append channel (Command+Shift+2) to add to a running daily note:
"Started the day reviewing PRs. Found a race condition in the WebSocket handler, created Linear issue ENG-847."
"Good meeting with the design team. Agreed on the new pricing page layout. They'll have mockups by Monday."
"Wrapped up the CSV export fix. Tests passing. PR ready for review."
End of day: a complete log of what you did, in Notion, without ever opening Notion.
Research dumps — long-form capture
You've just finished reading three articles about pricing psychology. The insights are in your head. Typing a summary feels like work. Speaking is natural:
"Research notes on pricing psychology. Three key findings. First, charm pricing still works — 9.99 converts 24 percent better than 10 dollars, left digit effect. Second, showing the expensive plan first increases mid-tier selection by 23 percent, Ahrefs tested this. Third, annual discounts between 15 and 20 percent are the sweet spot. Below 15 people don't bother switching, above 20 you're leaving money on the table. Source: Price Intelligently analysis of 100 SaaS companies."
A structured research note in Notion with numbered findings and sources. 30 seconds of speech versus 5 minutes of typing and formatting.
Notion Database Integration
The send_notion.py script handles both modes automatically depending on which environment variable you set:
NOTION_PAGE_ID
Append mode. Blocks are appended to an existing page. Good for daily journals and running logs.
NOTION_DATABASE_ID
Create mode. A new database entry is created with the first line of the transcript as the Name property. Good for meeting notes, research dumps, and task capture.
If both are set, NOTION_PAGE_ID takes priority. Every voice note is searchable and structured in your Notion workspace — no additional tooling required.
Why Voice Beats Typing for Notes
The gap between thinking and typing is where ideas die. You think at 400 words per minute. You type at 40–60. By the time you've typed the first sentence, the fourth idea has evaporated.
Split attention between listening and formatting. You miss context while you type. The notes are incomplete before you finish them.
Capture thoughts at 150–180 wpm, nearly as fast as they form. AI handles formatting. You stay focused on thinking, not structure.
And because SpeechButton captures audio in 7ms, there's no awkward pause between pressing the hotkey and starting to talk. You hold, speak, release. The flow is seamless — like thinking out loud into a system that actually listens.
Privacy
Here's exactly what stays on your Mac and what goes to the cloud:
| Component | Where it runs | Data sent externally |
|---|---|---|
| Voice capture | Your Mac | ✓ Nothing |
| Speech-to-text (Parakeet V3) | Apple Neural Engine | ✓ Nothing |
| Transform (local AI, default) | Your Mac | ✓ Nothing |
| Notion API call | Your Mac | Structured content → Notion (your workspace) |
Voice capture and transcription are 100% local. Your spoken words never leave your Mac as audio. The default transform runs on-device — the only external call is to Notion's API (your own workspace). For maximum privacy, use NOTION_PAGE_ID mode so no new pages are created externally.
Get Started
- 1 Download SpeechButton — free 15 min/day, no account needed
-
2
Create a Notion integration — notion.so/my-integrations → copy the
ntn_token - 3 Share your database or page with the integration and copy its ID from the URL
-
4
Add the
[[hotkey]]block from Step 3 above to your config and saveintegrations/send_notion.py - 5 Hold RightCommand, speak your notes, release. Your first voice-created Notion entry in under a minute.
Start dictating to Notion today
Free 15 min/day · No account needed · macOS 15+ · Apple Silicon
Download for macOS — FreePro ($7.99/mo) removes the daily limit. Requires macOS 15+ and Apple Silicon.