
Integrando Transcrição com Notion: Receita de API (2026)
Summarize this article with:
Não existe integração nativa entre ConvertAudioToText e Notion. O caminho que funciona é a API webhook: registre um webhook, receba o evento job.completed, busque a transcrição pela URL retornada e escreva num banco de dados do Notion com um token de integração. Isso dá cerca de 120 linhas de Node.js, ou zero código via Zapier ou n8n. Planeje em torno dos limites da API do Notion: transcrições longas precisam ser divididas em vários blocos e as requisições devem ter limite de taxa.
Os Caminhos de Trabalho
Hoje não existe integração nativa do Notion para o ConvertAudioToText no marketplace do Notion. O que existe é um caminho limpo via API: registrar um endpoint de webhook com a API do CATT, receber um evento job.completed quando uma transcrição terminar, buscar a transcrição pela URL retornada e gravá-la em um banco de dados do Notion. Cerca de 120 linhas de Node.js, uma tarde de configuração, e toda gravação que seu time faz vira conteúdo pesquisável no Notion.
Três padrões cobrem a maioria dos setups de equipe. Este guia detalha o padrão de linha de banco de dados por completo, com notas sobre os outros.
Linha de banco de dados por transcrição. Um banco de dados "Transcrições" com colunas para data, palestrante, projeto, resumo e um link para o resultado. Melhor para times que filtram e ordenam muitas gravações.
Anexado a páginas de projeto existentes. Cada transcrição anexa blocos a uma página de projeto ou reunião já existente. Melhor para times onde as transcrições pertencem a notas de projeto mais amplas.
Uma página por palestrante ou entrevistado. Mantenha um mapeamento de palestrante para ID de página e roteie as transcrições de acordo. Útil para jornalistas com fontes recorrentes e times de vendas acompanhando contas-chave.
Passo 1: Criar o Banco de Dados no Notion
No Notion, crie um novo banco de dados de página cheia com estas propriedades:
| Propriedade | Tipo | Uso |
|---|---|---|
| Título | Título | Nome do arquivo ou tópico da reunião |
| Data | Data | Data da gravação |
| Palestrantes | Seleção múltipla | Quem está na gravação |
| Projeto | Seleção | A qual projeto isso pertence |
| Resumo | Texto | Resumo, se gerado |
| Duração | Número | Duração do áudio em segundos |
| Idioma | Seleção | Idioma detectado ou especificado |
| URL do resultado | URL | Link de volta para a página de resultado do CATT |
Copie o ID do banco de dados da URL. É a string hexadecimal de 32 caracteres que vem depois da última barra e antes de qualquer parâmetro de consulta ?v=.
Passo 2: Criar uma Integração no Notion
- Acesse notion.so/my-integrations e clique em "New integration".
- Dê um nome (por exemplo, "Transcription Integration"), selecione seu workspace, escolha o tipo Internal e envie.
- Copie o Internal Integration Token. Desde setembro de 2024, novos tokens começam com
ntn_em vez do prefixo antigosecret_. Os dois formatos funcionam de forma idêntica nas chamadas de API. - Abra seu banco de dados Transcripts no Notion, clique no menu "...", vá em "Add connections" e selecione sua integração.
A integração só tem acesso aos bancos de dados que você compartilhar explicitamente com ela.
Etapa 3: Registre um webhook com o CATT
Webhooks no ConvertAudioToText exigem o plano Business. Registre seu endpoint:
curl -X POST https://api.convertaudiototext.com/api/v1/webhooks \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhooks/catt",
"events": ["job.completed", "job.failed"]
}'
A resposta inclui um campo secret. Guarde-o como CATT_WEBHOOK_SECRET no seu ambiente. Você não consegue recuperar esse valor depois de criado.
Para a alternativa de polling (sem precisar de webhook), veja webhook vs polling para transcrições.
Etapa 4: O manipulador de webhook
O payload de job.completed inclui um campo result_url que aponta para a transcrição completa. O manipulador verifica a assinatura, confere o tipo de evento, busca a transcrição e então escreve no Notion.
import express from 'express';
import { Client as NotionClient } from '@notionhq/client';
import crypto from 'crypto';
const app = express();
const notion = new NotionClient({ auth: process.env.NOTION_TOKEN });
const NOTION_DB_ID = process.env.NOTION_DATABASE_ID;
app.post(
'/webhooks/catt',
express.raw({ type: 'application/json' }),
async (req, res) => {
const sigHeader = req.header('X-Webhook-Signature'); // "sha256=<hex>"
const [, sig] = (sigHeader || '').split('=');
const expected = crypto
.createHmac('sha256', process.env.CATT_WEBHOOK_SECRET)
.update(req.body)
.digest('hex');
if (!sig || !crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
return res.status(401).send('Bad signature');
}
const event = JSON.parse(req.body.toString());
if (event.event !== 'job.completed') return res.sendStatus(200);
// Busca a transcrição completa na URL do resultado
const result = await fetch(event.data.result_url, {
headers: { Authorization: `Bearer ${process.env.CATT_API_KEY}` }
}).then(r => r.json());
await createNotionPage({
jobId: event.data.job_id,
language: event.data.language,
durationSeconds: event.data.duration,
completedAt: event.data.completed_at,
resultUrl: event.data.result_url,
transcript: result.transcript,
summary: result.summary,
utterances: result.utterances,
filename: result.filename,
});
res.sendStatus(200);
}
);
Os campos do evento que sempre estão presentes em job.completed: event, timestamp, data.job_id, data.status, data.created_at, data.language, data.duration, data.completed_at, data.result_url. O texto completo da transcrição, o resumo e as utterances vêm da busca do resultado, não do evento em si.
Resumo mais transcrição: os dois blocos que seu banco de dados Notion quer
Passo 5: Escreva a Página no Notion
async function createNotionPage(data) {
const transcriptBlocks = buildTranscriptBlocks(data.utterances || []);
const page = await notion.pages.create({
parent: { database_id: NOTION_DB_ID },
properties: {
Title: {
title: [{ text: { content: data.filename || `Transcript ${data.completedAt?.slice(0, 10)}` } }]
},
Date: { date: { start: data.completedAt?.slice(0, 10) || new Date().toISOString().slice(0, 10) } },
Language: { select: { name: data.language || 'auto' } },
Duration: { number: data.durationSeconds },
'Result URL': { url: data.resultUrl },
Summary: {
rich_text: [{ text: { content: (data.summary || '').slice(0, 2000) } }]
}
}
});
// Anexa os blocos da transcrição em lotes de 100 (limite da API do Notion)
if (transcriptBlocks.length > 0) {
await appendBlocksInBatches(page.id, transcriptBlocks);
}
}
function buildTranscriptBlocks(utterances) {
const blocks = [];
blocks.push({
object: 'block',
type: 'heading_2',
heading_2: { rich_text: [{ text: { content: 'Transcript' } }] }
});
for (const u of utterances) {
// O rich_text.content do Notion tem limite de 2.000 caracteres por bloco
const label = u.speaker ? `[${u.speaker}] ` : '';
const text = (label + (u.text || '')).slice(0, 2000);
blocks.push({
object: 'block',
type: 'paragraph',
paragraph: { rich_text: [{ text: { content: text } }] }
});
}
return blocks;
}
async function appendBlocksInBatches(pageId, blocks) {
for (let i = 0; i < blocks.length; i += 100) {
const batch = blocks.slice(i, i + 100);
await notion.blocks.children.append({ block_id: pageId, children: batch });
if (i + 100 < blocks.length) {
await new Promise(r => setTimeout(r, 400)); // fica dentro da média de 3 req/s
}
}
}
O limite de 100 blocos por requisição é uma restrição rígida da API do Notion. A pausa de 400ms mantém você dentro da média de 3 requisições por segundo. Para gravações muito longas (100+ falas), isso significa que a escrita leva alguns segundos; é aceitável para uma etapa de pós-processamento assíncrona.
Variação: Anexar a uma Página de Projeto Existente
Se as transcrições pertencem a páginas de projeto em vez de um banco de dados independente, use blocks.children.append com o ID de uma página existente:
async function appendToProjectPage(projectPageId, data) {
const divider = { object: 'block', type: 'divider', divider: {} };
const heading = {
object: 'block',
type: 'heading_3',
heading_3: {
rich_text: [{ text: { content: `Transcrição da reunião ${data.completedAt?.slice(0, 10)}` } }]
}
};
const transcriptBlocks = buildTranscriptBlocks(data.utterances || []);
await appendBlocksInBatches(projectPageId, [divider, heading, ...transcriptBlocks]);
}
Caminhos Sem Código
Se você quer isso sem escrever um servidor, duas opções funcionam hoje.
Zapier. O fluxo: gatilho de Webhook (captura o evento job.completed do CATT), depois uma etapa de Código para buscar a URL do resultado e, em seguida, uma ação "Create Database Item" no Notion. Zaps com múltiplas etapas exigem um plano pago do Zapier. O Zapier é mais rápido de configurar que código personalizado, mas mais difícil de depurar quando as gravações no Notion falham silenciosamente.
n8n. Existe um template de workflow n8n publicado que encadeia a transcrição do Whisper a uma página do Notion. A versão self-hosted do n8n é gratuita com execuções ilimitadas e permite manter as gravações fora de nuvens de terceiros. O Make.com também tem um módulo do Notion que funciona do mesmo jeito. Veja automatizando transcrição com Zapier para um passo a passo sem código.
Fireflies.ai tem uma integração nativa com o Notion (sem precisar de Zapier) que envia resumos de reuniões, itens de ação e um link da transcrição para um banco de dados do Notion após cada chamada gravada. É a escolha certa se você precisa principalmente de bots de reunião em vez de uploads de arquivos.
Nota sobre a Versão da API do Notion (2026)
A versão 2026-03-11 da API do Notion introduziu três mudanças significativas que vale a pena conhecer se você está atualizando integrações existentes:
- O parâmetro
afterem append-block-children é substituído porposition. - O campo
archivedé substituído porin_trash. - O tipo de bloco
transcriptionpassa a se chamarmeeting_notes.
Se você está escrevendo código novo hoje, instale @notionhq/client na versão 5.12.0 ou posterior e defina notionVersion: "2026-03-11" ao construir o client se quiser o comportamento mais recente. Formatos antigos de token (prefixo secret_) continuam funcionando.
Padrões de Produção
Equipes de jornalismo. Cada entrevista gravada cai em um banco de dados pesquisável do Notion. Filtros por tópico, fonte e data permitem que repórteres puxem todas as citações de uma fonte em segundos. Para o fluxo completo de entrevistas, veja como transcrever uma gravação de entrevista.
Equipes de sucesso do cliente. Cada ligação com cliente cai em uma página do Notion por cliente. A preparação da revisão trimestral de negócios cai de horas de reescuta para 15 minutos de leitura.
Produção de podcasts. Cada episódio ganha uma página no Notion com transcrição, resumo e a URL do resultado para edição. O produtor repassa para a equipe de redes sociais sem compartilhar o arquivo de áudio bruto. Veja melhor transcrição para podcasts para comparações de precisão entre ferramentas comuns.
Se você só precisa de uma transcrição limpa, sem servidor de webhook, o ConvertAudioToText cuida do upload e gera uma saída com identificação de falantes que você pode copiar, colar ou exportar direto para qualquer página do Notion.
Para construir a camada de atas de reunião por cima da transcrição bruta, criar atas de reunião a partir de áudio cobre os padrões de saída estruturada que mapeiam direto para as propriedades do banco de dados do Notion.
FAQ
O ConvertAudioToText tem integração nativa com o Notion?
Ainda não. Não existe uma conexão com um clique no marketplace de integrações do Notion. O caminho que funciona é registrar um endpoint de webhook (plano Business) que recebe um evento job.completed, depois buscar a transcrição pela result_url e escrevê-la no Notion usando a API do Notion.
Quais limites da API do Notion devo considerar?
A API do Notion permite uma média de 3 requisições por segundo por integração. Cada chamada de append-block-children aceita no máximo 100 blocos. O conteúdo de rich text por bloco é limitado a 2.000 caracteres. Para transcrições longas, faça o append dos blocos em lotes de 100, com um pequeno intervalo entre as chamadas.
Preciso de um plano pago do Notion para usar a API?
Não. A API do Notion é gratuita em todos os planos, incluindo o plano gratuito. Você só precisa de um plano pago para recursos do Notion, como compartilhar com convidados além de certos limites. Os limites de taxa da API são os mesmos em todos os planos.
Qual é o caminho no-code para enviar transcrições ao Notion?
Duas boas opções: o Zapier (plano pago necessário para zaps de múltiplas etapas) permite capturar um webhook e criar uma página no Notion sem código. O n8n Cloud tem um template de Whisper para Notion, e a versão self-hosted roda gratuitamente. Ambos os caminhos servem para fluxos simples de transcrição para página; código personalizado é melhor para blocos com identificação de falante, lotes e arquivos longos.
Fontes
- Notion API: Limites de requisições - verificado em 02/07/2026
- Notion API: Anexar blocos filhos - verificado em 02/07/2026
- Guia de atualização da Notion API 11/03/2026 - verificado em 02/07/2026
- Guia de integração Fireflies com Notion - verificado em 02/07/2026
- Marketplace de integrações da Notion - verificado em 02/07/2026 (nenhum conector nativo de transcrição listado)
- @notionhq/client no npm - v5.12.0 suporta a versão 2026-03-11 da API
Try transcription free
Convert any audio or video to clean, unwatermarked text — speaker labels, timestamps, and AI summaries included. First 30 minutes free, no account.
Related Articles

Speechmatics Alternative for Non-Developers: Web Transcription Without Code
Speechmatics is genuinely excellent for developers: 50 hours free per month, 56 languages, on-prem deployment. If you need a drag-and-drop web app with flat $14.99/mo pricing instead of an API, here is an honest comparison of the two.

Best Transcription Tools with API Access (2026)
Which transcription SaaS tools actually give you API keys, and on which plan? Verified pricing and plan gates for Descript, Sonix, Fireflies, Happy Scribe, AssemblyAI, and more.