Entegrasyon

Notion AI: turn every meeting into a structured Notion page

Speak AI auto-creates a structured Notion page for every meeting, call, and recording — transcript in 100+ languages, summary, action items, sentiment, speaker stats, and a link back to Speak. Build a single source of truth for every conversation your team has.

Özgür 7 günlük deneme. No credit card required. SOC 2 + GDPR-compliant. HIPAA-eligible plans available.
100+Diller
SOC 2+ GDPR
APIWebhook Ready
4.9G2 Score

Güvenilir 250.000'den fazla kişi ve ekip tarafından

Yapabilecekleriniz

Notion is the destination. Speak is the transcription and analysis engine that feeds it. Every meeting, call, and recording your team has becomes a structured Notion page — searchable, filterable, and linked back to the original recording. Research teams build interview repositories. Sales teams build call libraries. Podcast teams build show-note pipelines. All without anyone writing a single note.

Auto-create a Notion page per recording

When Speak finishes analyzing a meeting or call, fire a webhook that creates a new Notion page in your target database. The page is populated with the recording title, date, speaker list, and a link back to Speak. No manual entry, no copy-paste.

Map summary, action items, and sentiment to database properties

Speak extracts structured fields from every transcript: AI summary, action items, sentiment score, key themes, speaker names. Map each field to a typed Notion database property so the entire library is filterable and sortable by what was said, who said it, and how people felt.

Embed the full transcript in 100+ languages

Push the full speaker-labeled transcript into the Notion page body as structured blocks. Speak handles speaker diarization and auto-detects language across 100+ languages. Long transcripts are chunked automatically to stay within Notion’s 2,000-character block limit.

Pull Notion research notes into Speak for analysis

Already have research notes or customer interview notes in Notion? Pull Notion page content into Speak as a text note via POST /v1/upload and run Magic Prompts, sentiment scoring, and keyword extraction against it. Bi-directional data flow, one analysis layer.

3 Adımda Kurulum

The full webhook path takes about 10 minutes: create a Notion internal integration, share a database with it, register a Speak webhook, and let the handler create pages automatically. For no-code teams, Zapier or Make handles the same flow without writing a handler.

Speak AI’ye kaydolun

Ücretsiz hesap oluştur app.speakai.co7 günlük deneme sürümü alırsınız ve tam erişim sunar. Kredi kartı gerekmez. İçeri girdikten sonra şuraya gidin Ayarlar > API ve API anahtarınızı kopyalayın.

Entegrasyon yolunuzu seçin

Path A: Notion API webhook handler (recommended)

Şuraya git notion.so/my-integrations, click “New integration”, give it a name (e.g. “Speak AI”), and copy the Internal Integration Token. In your Notion database, click “Share” and invite the integration. Copy the database ID from the URL (the 32-character hex string after the workspace name). Register a Speak media.analyzed webhook endpoint in your server. When Speak fires, your handler calls POST https://api.notion.com/v1/pages with the Notion token, database ID, and the structured properties from the Speak insight payload. Full code in Tab 1 below.

Path B: Zapier or Make (no-code)

For teams that do not want to run a webhook server: use Zapier’s “Catch Hook” trigger with Speak’s media.analyzed webhook, then use the Notion “Create Database Item” action to create the page. Make (Integromat) offers the same flow with more control over property mapping. Recommended for teams already using Zapier or Make for other automations.

Path C: Bi-directional — pull Notion notes into Speak

Already have research notes in Notion? Fetch the page content via Notion’s POST https://api.notion.com/v1/databases/{database_id}/query API, extract the text from rich_text blocks, and send it to Speak via POST /v1/upload as a text note. Speak runs your Magic Prompts, sentiment, and keyword extraction against the existing notes. Useful for validating Notion research against new recordings.

Path D: MCP via Claude or ChatGPT

Already have recordings in Speak? Connect Claude Desktop with npx @speakai/mcp-server init, or add the remote MCP URL to Claude.ai or ChatGPT. Search and synthesize the entire Speak corpus through conversation, then paste insights into Notion manually. No webhook required.

Abone ol media.analyzed

Speak fires a signed webhook when transcription and AI analysis complete (typically within 60 seconds for a 10-minute recording). Register your endpoint via POST /v1/webhook and create Notion pages as they land — one page per recording, populated with the full structured insight payload.

Gerçek iş akışları, gerçek sonuçlar

Four production patterns Speak customers ship with Notion. Pick the one that fits your team and copy the recipe.







For research, PM, and ops teams · Speak webhook + Notion API

Auto-create a Notion page for every recording

Register a Speak media.analyzed webhook. When Speak finishes processing a recording, your handler fetches the full insight and creates a structured Notion page in your target database. Typically processes within 60-90 seconds of the recording completing.

Step 1: Register Speak’s media.analyzed webhook
# 1. Create a Notion internal integration at notion.so/my-integrations
# 2. Copy the Internal Integration Token (starts with "secret_")
# 3. Share your target Notion database with the integration (Share button in Notion)
# 4. Copy the database ID from the Notion URL:
#    https://notion.so/your-workspace/<DATABASE_ID>?v=...
# 5. Register a Speak webhook for media.analyzed:

curl -X POST https://api.speakai.co/v1/webhook 
  -H "x-speakai-key: $SPEAK_API_KEY" 
  -H "Content-Type: application/json" 
  -d '{
    "callbackUrl": "https://your-app.example.com/speak/notion-create-page",
    "events": ["media.analyzed"],
    "description": "Create Notion page per Speak recording"
  }'

# Store in your .env:
# SPEAK_API_KEY=...
# NOTION_TOKEN=secret_...
# NOTION_DB_ID=<32-char hex from Notion URL>
Step 2: Webhook handler — receive Speak event, create Notion page




// Speak webhook body shape (verified 2026-05-07): { eventType, state, mediaId }
import express from "express";
const app = express();
app.use(express.json());

app.post("/speak/notion-create-page", async (req, res) => {
  const { eventType, state, mediaId } = req.body;
  if (eventType !== "media.analyzed" || state !== "processed") return res.sendStatus(204);
  res.sendStatus(202); // Respond immediately

  // 1. Fetch full insight from Speak
  const { data } = await fetch(
    `https://api.speakai.co/v1/media/insight/${mediaId}`,
    { headers: { "x-speakai-key": process.env.SPEAK_API_KEY } }
  ).then(r => r.json());

  // 2. Fetch transcript for page body
  const transcriptRes = await fetch(
    `https://api.speakai.co/v1/media/${mediaId}/transcript`,
    { headers: { "x-speakai-key": process.env.SPEAK_API_KEY } }
  ).then(r => r.json());

  const paragraphs = transcriptRes.data?.paragraphs ?? [];
  const transcriptText = paragraphs
    .map(p => `[${p.speaker || "Speaker"}] ${p.text}`)
    .join("nn");

  // 3. Derive sentiment label from Speak's VADER compound score
  const compound = data.sentiment?.[0]?.document?.Compound || 0;
  const sentimentLabel = compound > 10 ? "Positive" : compound < -10 ? "Negative" : "Neutral";

  // 4. Chunk transcript into Notion blocks (max 2000 chars per rich_text block)
  const chunkSize = 1800;
  const chunks = [];
  for (let i = 0; i < transcriptText.length; i += chunkSize) {
    chunks.push(transcriptText.slice(i, i + chunkSize));
  }
  const transcriptBlocks = chunks.map(chunk => ({
    object: "block",
    type: "paragraph",
    paragraph: { rich_text: [{ type: "text", text: { content: chunk } }] },
  }));

  // 5. Create Notion page
  // Auth: Bearer $NOTION_TOKEN (Internal Integration Token from notion.so/my-integrations)
  // API version header REQUIRED: Notion-Version: 2022-06-28
  await fetch("https://api.notion.com/v1/pages", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.NOTION_TOKEN}`,
      "Notion-Version": "2022-06-28",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      parent: { database_id: process.env.NOTION_DB_ID },
      properties: {
        Title: { title: [{ text: { content: data.name } }] },
        Date: { date: { start: data.createdAt?.slice(0, 10) } },
        Sentiment: { select: { name: sentimentLabel } },
        "Speak URL": { url: `https://app.speakai.co/media/${mediaId}` },
        "Duration (s)": { number: data.duration?.inSecond || 0 },
      },
      children: [
        {
          object: "block", type: "heading_2",
          heading_2: { rich_text: [{ type: "text", text: { content: "AI Summary" } }] },
        },
        {
          object: "block", type: "paragraph",
          paragraph: { rich_text: [{ type: "text", text: { content: data.summary || "" } }] },
        },
        {
          object: "block", type: "heading_2",
          heading_2: { rich_text: [{ type: "text", text: { content: "Transcript" } }] },
        },
        ...transcriptBlocks.slice(0, 95), // Notion API: max 100 children per request
      ],
    }),
  });
  // If transcript is very long, append remaining blocks via PATCH /v1/blocks/{page_id}/children
});

app.listen(3000);
import os, requests
from fastapi import FastAPI, Request

app = FastAPI()

@app.post("/speak/notion-create-page")
async def hook(req: Request):
    body = await req.json()
    if body.get("eventType") != "media.analyzed" or body.get("state") != "processed":
        return {"ok": True}
    media_id = body["mediaId"]

    # 1. Fetch insight from Speak
    media = requests.get(
        f"https://api.speakai.co/v1/media/insight/{media_id}",
        headers={"x-speakai-key": os.environ["SPEAK_API_KEY"]},
        timeout=30,
    ).json()["data"]

    # 2. Fetch transcript
    transcript = requests.get(
        f"https://api.speakai.co/v1/media/{media_id}/transcript",
        headers={"x-speakai-key": os.environ["SPEAK_API_KEY"]},
        timeout=30,
    ).json().get("data", {})

    paragraphs = transcript.get("paragraphs", [])
    transcript_text = "nn".join(
        f"[{p.get('speaker', 'Speaker')}] {p['text']}" for p in paragraphs
    )

    # 3. Sentiment label from VADER compound score
    compound = (media.get("sentiment") or [{}])[0].get("document", {}).get("Compound", 0)
    label = "Positive" if compound > 10 else "Negative" if compound < -10 else "Neutral"

    # 4. Chunk transcript for Notion's 2000-char rich_text limit
    chunk_size = 1800
    chunks = [transcript_text[i:i+chunk_size] for i in range(0, len(transcript_text), chunk_size)]
    transcript_blocks = [
        {"object": "block", "type": "paragraph",
         "paragraph": {"rich_text": [{"type": "text", "text": {"content": c}}]}}
        for c in chunks
    ]

    # 5. Create Notion page
    # Auth: Bearer $NOTION_TOKEN -- Internal Integration Token from notion.so/my-integrations
    # API version header REQUIRED: Notion-Version: 2022-06-28
    requests.post(
        "https://api.notion.com/v1/pages",
        headers={
            "Authorization": f"Bearer {os.environ['NOTION_TOKEN']}",
            "Notion-Version": "2022-06-28",
            "Content-Type": "application/json",
        },
        json={
            "parent": {"database_id": os.environ["NOTION_DB_ID"]},
            "properties": {
                "Title": {"title": [{"text": {"content": media["name"]}}]},
                "Date": {"date": {"start": media.get("createdAt", "")[:10]}},
                "Sentiment": {"select": {"name": label}},
                "Speak URL": {"url": f"https://app.speakai.co/media/{media_id}"},
                "Duration (s)": {"number": media.get("duration", {}).get("inSecond", 0)},
            },
            "children": [
                {"object": "block", "type": "heading_2",
                 "heading_2": {"rich_text": [{"type": "text", "text": {"content": "AI Summary"}}]}},
                {"object": "block", "type": "paragraph",
                 "paragraph": {"rich_text": [{"type": "text", "text": {"content": media.get("summary", "")}}]}},
                {"object": "block", "type": "heading_2",
                 "heading_2": {"rich_text": [{"type": "text", "text": {"content": "Transcript"}}]}},
                *transcript_blocks[:95],  # Notion API: max 100 children per request
            ],
        },
        timeout=30,
    )
    return {"ok": True}

Notion's API requires the Notion-Version: 2022-06-28 header on every request or it returns a 400 error. The Integration Token from notion.so/my-integrations is scoped to only the databases you explicitly share with it -- a safer pattern than a full OAuth token. If the transcript exceeds ~95 blocks, append the remainder via PATCH https://api.notion.com/v1/blocks/{page_id}/children.

For research ops and RevOps · Notion database schema

Map Speak's structured fields to Notion database properties

Speak extracts structured data from every transcript: summary, action items, sentiment scores, key themes, speaker names, duration. Map each field to a typed Notion property so the entire library is filterable and sortable directly in Notion.

Recommended Notion database schema
Notion Database: Speak Transcripts
  Property          Type            Notes
  -------           ----            -----
  Title             title           data.name from Speak insight
  Date              date            data.createdAt (ISO date)
  Source            select          "zoom" / "teams" / "loom" / "upload" / "recorder"
  Sentiment         select          "Positive" / "Neutral" / "Negative" (from VADER compound)
  Themes            multi_select    data.keywords[].keyword (top 5)
  Speakers          multi_select    distinct speaker names from transcript paragraphs
  Duration (s)      number          data.duration.inSecond
  Action Items      number          data.actionItems?.length
  Speak URL         url             https://app.speakai.co/media/{mediaId}
  Transcript        rich_text       First 200 chars in DB row; full transcript in page body blocks

# Notion property shape reference (verified Notion API 2022-06-28):
{
  "Title":        { "title":       [{ "text": { "content": "..." } }] },
  "Date":         { "date":        { "start": "2026-05-07" } },
  "Source":       { "select":      { "name": "zoom" } },
  "Sentiment":    { "select":      { "name": "Positive" } },
  "Themes":       { "multi_select": [{ "name": "pricing" }, { "name": "onboarding" }] },
  "Speakers":     { "multi_select": [{ "name": "Alice" }, { "name": "Bob" }] },
  "Duration (s)": { "number":      3842 },
  "Action Items": { "number":      4 },
  "Speak URL":    { "url":         "https://app.speakai.co/media/..." },
  "Transcript":   { "rich_text":   [{ "text": { "content": "first 200 chars..." } }] }
}
Extract speakers and themes from Speak insight payload




// Build Notion properties object from Speak insight payload
function buildNotionProperties(data, mediaId, transcriptParagraphs) {
  const compound = data.sentiment?.[0]?.document?.Compound || 0;
  const sentimentLabel = compound > 10 ? "Positive" : compound < -10 ? "Negative" : "Neutral";

  // Extract unique speaker names from transcript paragraphs
  const speakers = [...new Set(
    (transcriptParagraphs || [])
      .map(p => p.speaker)
      .filter(Boolean)
  )].slice(0, 10); // Notion multi_select: recommended limit

  // Extract top keywords as themes
  const themes = (data.keywords || [])
    .slice(0, 5)
    .map(k => ({ name: k.keyword }));

  const transcriptSnippet = (transcriptParagraphs || [])
    .map(p => p.text)
    .join(" ")
    .slice(0, 200);

  return {
    Title:          { title:       [{ text: { content: data.name } }] },
    Date:           { date:        { start: data.createdAt?.slice(0, 10) } },
    Sentiment:      { select:      { name: sentimentLabel } },
    Themes:         { multi_select: themes },
    Speakers:       { multi_select: speakers.map(s => ({ name: s })) },
    "Duration (s)": { number:      data.duration?.inSecond || 0 },
    "Action Items": { number:      (data.actionItems || []).length },
    "Speak URL":    { url:         `https://app.speakai.co/media/${mediaId}` },
    Transcript:     { rich_text:   [{ text: { content: transcriptSnippet } }] },
  };
}
def build_notion_properties(data: dict, media_id: str, paragraphs: list) -> dict:
    compound = (data.get("sentiment") or [{}])[0].get("document", {}).get("Compound", 0)
    label = "Positive" if compound > 10 else "Negative" if compound < -10 else "Neutral"

    # Unique speaker names from transcript paragraphs
    seen = set()
    speakers = []
    for p in paragraphs:
        sp = p.get("speaker")
        if sp and sp not in seen:
            seen.add(sp)
            speakers.append({"name": sp})
    speakers = speakers[:10]

    # Top 5 keywords as Notion multi_select options
    themes = [{"name": k["keyword"]} for k in (data.get("keywords") or [])[:5]]

    snippet = " ".join(p.get("text", "") for p in paragraphs)[:200]

    return {
        "Title":          {"title":        [{"text": {"content": data["name"]}}]},
        "Date":           {"date":         {"start": data.get("createdAt", "")[:10]}},
        "Sentiment":      {"select":       {"name": label}},
        "Themes":         {"multi_select": themes},
        "Speakers":       {"multi_select": speakers},
        "Duration (s)":   {"number":       data.get("duration", {}).get("inSecond", 0)},
        "Action Items":   {"number":       len(data.get("actionItems") or [])},
        "Speak URL":      {"url":          f"https://app.speakai.co/media/{media_id}"},
        "Transcript":     {"rich_text":    [{"text": {"content": snippet}}]},
    }

Create the database properties in Notion before running the webhook. If a property does not exist in the database schema, the Notion API returns a 400 error on that field. Multi-select options are created automatically when you push a new name -- no need to pre-populate the option list.

For sales ops and RevOps · Verified webhook to CRM activity

Log every call in HubSpot, Salesforce, or Zoho alongside Notion

Notion is your knowledge base. Your CRM is the system of record for deals and contacts. The same media.analyzed webhook can create a Notion page AND log a CRM activity in a single handler -- one event, two destinations. Source-tag with the recording type so reports split by source.

Receive Speak webhook + create CRM activity + create Notion page
// Speak webhook body shape (verified 2026-05-07): { eventType, state, mediaId }
import express from "express";
const app = express();
app.use(express.json());

app.post("/speak/crm-and-notion", async (req, res) => {
  const { eventType, state, mediaId } = req.body;
  if (eventType !== "media.analyzed" || state !== "processed") return res.sendStatus(204);
  res.sendStatus(202);

  // 1. Fetch full insight
  const { data } = await fetch(
    `https://api.speakai.co/v1/media/insight/${mediaId}`,
    { headers: { "x-speakai-key": process.env.SPEAK_API_KEY } }
  ).then(r => r.json());

  const start = new Date(data.createdAt);
  const end = new Date(start.getTime() + (data.duration?.inSecond || 0) * 1000);
  const compound = data.sentiment?.[0]?.document?.Compound || 0;
  const sentimentLabel = compound > 10 ? "Positive" : compound < -10 ? "Negative" : "Neutral";

  // 2. Push to HubSpot Meetings (same pattern for Salesforce Tasks or Zoho Calls)
  await fetch("https://api.hubapi.com/crm/v3/objects/meetings", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.HUBSPOT_TOKEN}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      properties: {
        hs_timestamp: start.toISOString(),
        hs_meeting_title: data.name,
        hs_meeting_body: `Transcript and analysis in Notion. Open in Speak: https://app.speakai.co/media/${mediaId}`,
        hs_meeting_external_url: `https://app.speakai.co/media/${mediaId}`,
        hs_meeting_start_time: start.toISOString(),
        hs_meeting_end_time: end.toISOString(),
        hs_meeting_outcome: "COMPLETED",
      },
    }),
  });

  // 3. Also create a Notion page in the knowledge base
  // Auth: Bearer $NOTION_TOKEN (Internal Integration Token from notion.so/my-integrations)
  // API version header REQUIRED: Notion-Version: 2022-06-28
  await fetch("https://api.notion.com/v1/pages", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.NOTION_TOKEN}`,
      "Notion-Version": "2022-06-28",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      parent: { database_id: process.env.NOTION_DB_ID },
      properties: {
        Title:          { title:  [{ text: { content: data.name } }] },
        Date:           { date:   { start: data.createdAt?.slice(0, 10) } },
        Sentiment:      { select: { name: sentimentLabel } },
        "Speak URL":    { url:    `https://app.speakai.co/media/${mediaId}` },
      },
      children: [
        { object: "block", type: "heading_2",
          heading_2: { rich_text: [{ type: "text", text: { content: "AI Summary" } }] } },
        { object: "block", type: "paragraph",
          paragraph: { rich_text: [{ type: "text", text: { content: data.summary || "" } }] } },
      ],
    }),
  });
});

app.listen(3000);

Full destination-specific code (HubSpot Meeting + association IDs, Salesforce Task + SOQL contact resolution, Zoho Calls + Notes) on /integrations/hubspot/, /integrations/salesforce/ve /integrations/zoho/. The Speak side is identical across all three CRM destinations.

For analysts and research leads · Natural language

Search every recording from Claude or ChatGPT, save insights to Notion

Connect Speak's MCP server to Claude or ChatGPT and your team queries the entire recording library through conversation. Use Notion as the human-readable archive; MCP as the analyst's query layer. No SQL, no dashboards, no exports.

1. MCP sunucusunu yükleyin




# Claude Desktop / Claude Code (kurulumunuzu otomatik olarak algılar)
npx @speakai/mcp-server init

# İstendiğinde Speak API anahtarını yapıştırın. Kurulum yaklaşık 2 dakika sürer.
# Claude.ai (web) and ChatGPT MCP connector
# Settings > Integrations > Add MCP Server
# Remote URL:    https://api.speakai.co/v1/mcp
# Auth header:   x-speakai-key: YOUR_SPEAK_API_KEY

# Verify the connection responds:
curl -s https://api.speakai.co/v1/mcp 
  -H "x-speakai-key: $SPEAK_API_KEY" 
  -H "Accept: application/json"

2. Takımınızın bugün kullanabileceği örnek komutlar:

  • "Summarize every customer interview from last month and list the top 3 themes across all calls."
  • "Pull verbatim quotes where a speaker mentioned pricing or contract length. I will paste them into Notion."
  • "Show every recording from Q1 where sentiment was negative. Group by speaker."
  • "Compare key objections across the 10 most recent sales calls. What changed month over month?"
  • "Find every recording where a competitor was mentioned by name. Pull timestamps."

MCP queries Speak directly. Use Notion as the human-facing archive and Speak MCP for fast cross-call queries. Works with Claude.ai, Claude Desktop, Claude Code, and ChatGPT MCP connectors. MCP sunucusunu görüntüle →

Why Speak AI + Notion

Notion organizes your team's knowledge. Speak generates that knowledge from every conversation your team has. The combination keeps your Notion databases current without anyone writing a meeting note.

Every conversation source, one Notion database

Speak ingests from Zoom, Google Meet, Microsoft Teams, live recorder, URL, and direct file upload. Every source flows into the same webhook pipeline and lands in the same Notion database. One searchable knowledge base, every conversation source your team uses.

Sabit şablonlar değil, özel Magic İstemler

Speak's Magic Prompt runs your custom prompt on every recording: customer objection scoring, research theme extraction, sales discovery completeness, competitor mention tagging. Save the prompt once and the output lands in the Notion page body automatically.

SOC 2 + GDPR + HIPAA-eligible

Speak ships with SOC 2 Type 2, GDPR compliance, and HIPAA-eligible plans for healthcare and legal customers. Your recording data is encrypted in transit and at rest, and Speak does not train on your conversations.

Claude ve ChatGPT için MCP-native

Resmi @speakai/mcp-server exposes 83 tools to AI assistants. Your team queries the full recording library in plain English from Claude Desktop or ChatGPT, without exporting transcripts to other tools. Notion stores the record; MCP enables the query.

Teams trust Speak AI for their most important recordings

★★★★★
4.9 G2'de

“Speak AI, nitel verileri nasıl işlediğimizi dönüştürmede müdür olmuştur. Transkripsiyon doğruluğu etkileyici ve NLP içgörüleri bize manuel analiz saatlerini kurtarıyor.”

Araştırma Müdürü | Danışmanlık Firması

“Otter.ai’den geçtik ve analiz derinliği başka bir seviyede. Sentiment puanlama, anahtar kelime çıkarma ve tema tespiti otomatik olarak gerçekleşiyor.”

Ürün Yöneticisi | SaaS Şirketi

“The ability to search across all our customer recordings and pull specific moments is a game-changer for our support team.”

CX Müdürü | Enterprise Tech

How to use Speak AI with Notion for meeting transcription and knowledge management

Notion is the knowledge management platform used by millions of teams to organize research, sales intelligence, and operational knowledge. Every customer interview, sales call, and team meeting is a potential Notion page -- but only if someone writes it up. Speak AI automates that step: Speak transcribes the audio or video, extracts structure, and pushes a formatted Notion page to your database automatically. No meeting notes, no copy-paste, no manual tagging.

Where Speak fits in the Notion knowledge pipeline

Speak runs after the recording ends. Your recorder, conferencing tool, or uploaded audio file is the source. Speak handles transcription in 100+ languages, AI summary, action item extraction, sentiment scoring, and speaker diarization. The Speak media.analyzed webhook then fires, and your handler creates a Notion page populated with those structured fields. Notion becomes the permanent, browsable record of every conversation your team has.

How the Notion API works with Speak

Notion's API uses internal integration tokens scoped to specific databases. Create an integration at notion.so/my-integrations, share a database with it, and your handler authenticates with Authorization: Bearer $NOTION_TOKEN. Every request requires the Notion-Version: 2022-06-28 header. Pages are created via POST https://api.notion.com/v1/pages with a parent.database_id and a properties object that maps to your database schema. Transcript content goes in the page body as children blocks -- paragraph blocks, heading blocks, and code blocks, each limited to 2,000 characters of rich_text content per block.

How do I auto-create Notion pages from Speak recordings?

The production path uses Speak's media.analyzed webhook. When Speak finishes processing a recording:

  • Your handler receives { eventType: "media.analyzed", state: "processed", mediaId }
  • Fetch the full insight from GET https://api.speakai.co/v1/media/insight/{mediaId}
  • Fetch the transcript from GET https://api.speakai.co/v1/media/{mediaId}/transcript
  • Map Speak fields to Notion properties (title, date, sentiment, speakers, themes, duration)
  • Create the Notion page via POST https://api.notion.com/v1/pages with the mapped properties and transcript blocks

For long transcripts, chunk the text into 1,800-character segments (staying under Notion's 2,000-char limit per rich_text block) and append additional blocks via PATCH https://api.notion.com/v1/blocks/{page_id}/children. The Notion API limits each request to 100 children blocks -- split into multiple requests for very long transcripts.

Can I pull Notion pages into Speak for analysis?

Yes. Fetch Notion page content via POST https://api.notion.com/v1/databases/{database_id}/query veya GET https://api.notion.com/v1/blocks/{page_id}/children, extract the text from rich_text properties, and send it to Speak via POST /v1/upload as a text note. Speak runs sentiment scoring, keyword extraction, and Magic Prompts against it. Useful for analyzing existing research notes alongside new recording transcripts in the same Speak workspace.

Role’a Göre Kullanım Örnekleri

Product and research teams use Speak with Notion to build a searchable customer interview repository. Every interview recording becomes a Notion page with sentiment, key themes, and verbatim quotes as filterable properties. Magic Prompts extract structured insights -- pain points, desired outcomes, competitor mentions -- that map directly to product decision frameworks.

Satış ekipleri build a call library in Notion where every discovery call, demo, and follow-up is a structured page. Speak extracts action items and objections. Notion makes them browsable by deal stage, sentiment, or account. See Satış ekipleri için Speak AI.

Podcast and content teams pipe recorded episodes into Speak. Transcripts, show notes, and chapter markers generated by Magic Prompts land in a Notion content calendar automatically. No show notes writer needed.

Qualitative research teams bring field recordings into Speak, code themes via Magic Prompts, and push tagged summaries to a Notion research database. Cross-call analysis via MCP lets researchers ask Claude for patterns across hundreds of interviews in seconds. See Nitel araştırmacılar için Speak AI.

Sıkça sorulan sorular

How do I set up the Notion integration with Speak AI?

Create a Notion internal integration at notion.so/my-integrations, copy the Integration Token, and share your target database with the integration. Register a Speak media.analyzed webhook endpoint. When Speak fires the webhook, your handler fetches the insight and calls POST https://api.notion.com/v1/pages with the token and your database ID. Full code recipes are in Tab 1 above.

What database properties do I need in Notion?

A flexible starting schema: Title (title), Date (date), Source (select), Sentiment (select), Themes (multi_select), Speakers (multi_select), Duration (number), Action Items (number), Speak URL (url), Transcript (rich_text). Create the properties in Notion before pushing -- the API returns a 400 error if a property does not exist in the schema. Multi-select options are created automatically when you push a new name.

Does Speak overwrite existing Notion pages?

No. Each Speak recording creates a new Notion page. Speak does not update or delete existing Notion pages. If you reprocess a recording in Speak, your webhook handler will fire again and create a second page. Add a deduplication check in your handler using the Speak mediaId as a unique key -- for example, store the Notion page ID alongside the mediaId in your database and skip creation if a row already exists.

Can I send only certain meetings or recordings to Notion?

Yes. Tag recordings in Speak with a label (e.g. "notion" or "research") when uploading, then filter in your webhook handler: only create a Notion page if data.tags?.includes("notion"). You can also filter by folder, duration, sentiment, or any field in the Speak insight payload before calling the Notion API.

What about long transcripts and Notion's block limits?

Notion limits each rich_text block to 2,000 characters and each API request to 100 children blocks. For long transcripts, chunk the text into 1,800-character segments and split into multiple requests: create the page with the first 95 blocks, then append the rest via PATCH https://api.notion.com/v1/blocks/{page_id}/children. The Node and Python recipes in Tab 1 handle this chunking automatically.

Can I pull existing Notion pages into Speak for analysis?

Yes. Query your Notion database via POST https://api.notion.com/v1/databases/{database_id}/query, extract text from rich_text blocks, and send the content to Speak via POST /v1/upload as a text note. Speak runs sentiment, keyword extraction, and Magic Prompts against it. Useful for analyzing research notes already in Notion alongside new recording transcripts.

Is the Notion integration token scoped to one workspace?

An internal integration token is scoped to the Notion workspace it was created in. It only has access to databases and pages that have been explicitly shared with the integration -- it cannot access your entire Notion workspace. This is the recommended pattern: share only the databases your pipeline needs. If you need to write to databases in multiple workspaces, create a separate integration in each workspace.

Start using Speak AI with Notion today

83 analysis tools. 100+ languages. Auto-create Notion pages from every meeting, call, and recording -- with transcript, summary, action items, sentiment, and speaker stats. Same workspace as your Zoom, Meet, Teams, and live recorder sessions.

Speak AI'yı ücretsiz deneyin.

Create your account, upload or record your first meeting, and see a Notion page auto-created in your database. Full access for 7 days. No credit card required.

Demo rezervasyonu yapın

For teams evaluating Speak for a Notion-connected recording pipeline, book a demo with the Speak team. We will walk through the webhook setup, property mapping, and Magic Prompt configuration live.