Intégrer la transcription avec Notion : recette API (2026)
apinotionintegrations

Intégrer la transcription avec Notion : recette API (2026)

BMMamane B. MoussaMay 26, 2026Updated July 2, 202611 min read

Summarize this article with:

TL;DR

Il n'existe pas d'intégration native entre ConvertAudioToText et Notion. La solution qui fonctionne passe par l'API webhook : enregistrez un webhook, recevez l'événement job.completed, récupérez la transcription depuis l'URL renvoyée, puis écrivez-la dans une base Notion avec un jeton d'intégration. Cela représente environ 120 lignes de Node.js, ou zéro code via Zapier ou n8n. Prévoyez les limites de l'API Notion : les transcriptions longues doivent être découpées en plusieurs blocs et les requêtes doivent être limitées en débit.

Les chemins de travail

Il n'existe aujourd'hui aucune intégration native Notion pour ConvertAudioToText dans le marketplace Notion. Ce qui existe, c'est un chemin API propre : enregistrez un endpoint webhook avec l'API CATT, recevez un événement job.completed quand une transcription se termine, récupérez la transcription depuis l'URL renvoyée, puis écrivez-la dans une base Notion. Environ 120 lignes de Node.js, un après-midi de configuration, et chaque enregistrement de votre équipe devient du contenu Notion consultable.

Trois schémas couvrent la plupart des configurations d'équipe. Ce guide détaille le schéma par ligne de base de données, avec des notes sur les autres.

Une ligne de base par transcription. Une base « Transcripts » avec des colonnes pour la date, l'intervenant, le projet, le résumé et un lien vers le résultat. Idéal pour les équipes qui filtrent et trient de nombreux enregistrements.

Ajout aux pages de projet existantes. Chaque transcription ajoute des blocs à une page de projet ou de réunion existante. Idéal pour les équipes où les transcriptions s'intègrent dans des notes de projet plus larges.

Une page par intervenant ou personne interviewée. Maintenez un mapping intervenant-vers-id-de-page et acheminez les transcriptions en conséquence. Utile pour les journalistes avec des sources récurrentes et les équipes commerciales qui suivent des comptes clés.

Étape 1 : Créer la base Notion

Dans Notion, créez une nouvelle base plein écran avec ces propriétés :

PropriétéTypeUsage
TitreTitreNom du fichier ou sujet de réunion
DateDateDate d'enregistrement
IntervenantsSélection multipleQui figure dans l'enregistrement
ProjetSélectionAuquel ce projet appartient
RésuméTexteRésumé si généré
DuréeNombreDurée audio en secondes
LangueSélectionLangue détectée ou spécifiée
URL du résultatURLLien vers la page de résultat CATT

Copiez l'ID de la base depuis l'URL. C'est la chaîne hexadécimale de 32 caractères qui suit le dernier slash et précède tout paramètre de requête ?v=.

Étape 2 : Créer une intégration Notion

  1. Allez sur notion.so/my-integrations et cliquez sur « Nouvelle intégration ».
  2. Nommez-la (par exemple, « Intégration de transcription »), sélectionnez votre espace de travail, choisissez le type Interne, puis validez.
  3. Copiez le jeton d'intégration interne. Depuis septembre 2024, les nouveaux jetons commencent par ntn_ au lieu de l'ancien préfixe secret_. Les deux formats fonctionnent de manière identique dans les appels API.
  4. Ouvrez votre base de données Transcripts dans Notion, cliquez sur le menu « ... », allez dans « Ajouter des connexions », puis sélectionnez votre intégration.

L'intégration n'accède qu'aux bases de données que vous lui partagez explicitement.

Étape 3 : Enregistrer un webhook avec CATT

Les webhooks sur ConvertAudioToText nécessitent le plan Business. Enregistrez votre point de terminaison :

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"]
  }'

La réponse contient un champ secret. Stockez-le comme CATT_WEBHOOK_SECRET dans votre environnement. Vous ne pourrez plus récupérer cette valeur après sa création.

Pour l'alternative par sondage (sans webhook), consultez webhook ou sondage pour les transcriptions.

Étape 4 : Le gestionnaire de webhook

La charge utile de job.completed inclut un champ result_url pointant vers la transcription complète. Le gestionnaire vérifie la signature, contrôle le type d'événement, récupère la transcription, puis écrit dans 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);

    // Récupère la transcription complète depuis l'URL du résultat
    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);
  }
);

Les champs d'événement toujours présents sur job.completed : event, timestamp, data.job_id, data.status, data.created_at, data.language, data.duration, data.completed_at, data.result_url. Le texte complet de la transcription, le résumé et les utterances proviennent de la récupération du résultat, pas de l'événement lui-même.

Résumé plus transcription : les deux blocs que votre base Notion attendRésumé plus transcription : les deux blocs que votre base Notion attend

Étape 5 : Écrire la page 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) } }]
      }
    }
  });

  // Ajout des blocs de transcription par lots de 100 (limite de l'API 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) {
    // Le contenu de rich_text.content est limité à 2 000 caractères par bloc
    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)); // pour rester sous la moyenne de 3 requêtes par seconde
    }
  }
}

La limite de 100 blocs par requête est une contrainte stricte de l'API Notion. La pause de 400 ms vous maintient sous la moyenne de 3 requêtes par seconde. Pour les enregistrements très longs (plus de 100 interventions), l'écriture prend quelques secondes, ce qui reste acceptable pour une étape de post-traitement asynchrone.

Variante : ajout à une page de projet existante

Si les transcriptions doivent être rattachées à des pages de projet plutôt qu'à une base de données autonome, utilisez blocks.children.append avec l'ID d'une page existante :

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: `Meeting transcript ${data.completedAt?.slice(0, 10)}` } }]
    }
  };
  const transcriptBlocks = buildTranscriptBlocks(data.utterances || []);
  await appendBlocksInBatches(projectPageId, [divider, heading, ...transcriptBlocks]);
}

Solutions sans code

Si vous préférez éviter d'écrire un serveur, deux options fonctionnent aujourd'hui.

Zapier. Le flux : un déclencheur Webhook (capte l'événement job.completed de CATT), puis une étape Code pour récupérer l'URL du résultat, et enfin une action "Create Database Item" dans Notion. Les zaps multi-étapes nécessitent un plan Zapier payant. Zapier se configure plus vite qu'un code sur mesure, mais il est plus difficile à déboguer quand les écritures Notion échouent silencieusement.

n8n. Il existe un modèle de workflow n8n publié qui enchaîne la transcription Whisper vers une page Notion. La version auto-hébergée de n8n est gratuite avec des exécutions illimitées et vous permet de garder les enregistrements hors des clouds propriétaires. Make.com propose aussi un module Notion qui fonctionne de la même manière. Consultez automatiser la transcription avec Zapier pour un guide pas à pas sans code.

Fireflies.ai dispose d'une intégration native Notion (sans passer par Zapier) qui pousse les résumés de réunion, les points d'action et un lien vers la transcription dans une base Notion après chaque appel enregistré. C'est le bon choix si vous avez surtout besoin de bots de réunion plutôt que d'uploads de fichiers.

Note sur la version de l'API Notion (2026)

La version 2026-03-11 de l'API Notion introduit trois changements majeurs à connaître si vous mettez à jour des intégrations existantes :

  • Le paramètre after dans append-block-children est remplacé par position.
  • Le champ archived est remplacé par in_trash.
  • Le type de bloc transcription est renommé meeting_notes.

Si vous écrivez du nouveau code aujourd'hui, installez @notionhq/client en version 5.12.0 ou ultérieure et définissez notionVersion: "2026-03-11" lors de la construction du client si vous voulez le comportement le plus récent. Les anciens formats de jeton (préfixe secret_) continuent de fonctionner.

Patterns de production

Équipes de journalisme. Chaque entretien enregistré atterrit dans une base de données Notion consultable. Les filtres de propriétés par sujet, source et date permettent aux reporters de récupérer toutes les citations d'une source en quelques secondes. Pour le flux de travail complet d'un entretien, voir comment transcrire un enregistrement d'entretien.

Équipes de réussite client. Chaque appel client atterrit dans une page Notion dédiée au client. La préparation de la revue d'affaires trimestrielle passe de plusieurs heures de réécoute à 15 minutes de lecture.

Production de podcasts. Chaque épisode reçoit une page Notion avec la transcription, le résumé et l'URL du résultat pour le montage. Le producteur transmet le travail à l'équipe sociale sans partager le fichier audio brut. Voir meilleure transcription pour podcasts pour des comparaisons de précision entre les outils courants.

Si vous avez juste besoin d'une transcription propre sans serveur webhook, ConvertAudioToText gère le téléchargement et produit une sortie avec étiquettes de locuteurs que vous pouvez copier-coller ou exporter pour coller directement dans n'importe quelle page Notion.

Pour construire la couche de comptes rendus de réunion par-dessus la transcription brute, créer des comptes rendus de réunion à partir d'audio couvre les patterns de sortie structurée qui correspondent proprement aux propriétés de base de données Notion.

FAQ

Est-ce que ConvertAudioToText a une intégration native avec Notion ?

Pas encore. Il n’existe pas de connexion en un clic dans la marketplace d’intégrations Notion. Le chemin qui fonctionne consiste à enregistrer un endpoint webhook (plan Business) qui reçoit un événement job.completed, puis à récupérer la transcription via result_url et à l’écrire dans Notion avec l’API Notion.

Quelles limites de l’API Notion dois-je prévoir ?

L’API Notion autorise en moyenne 3 requêtes par seconde et par intégration. Chaque appel append-block-children accepte au maximum 100 blocs. Le contenu texte enrichi par bloc est plafonné à 2 000 caractères. Pour les transcriptions longues, regroupez vos ajouts de blocs par lots de 100 avec une courte pause entre les appels.

Ai-je besoin d’un plan Notion payant pour utiliser l’API ?

Non. L’API Notion est gratuite sur tous les plans Notion, y compris l’offre gratuite. Vous n’avez besoin d’un plan payant que pour des fonctionnalités Notion comme le partage avec des invités au-delà de certaines limites. Les limites de débit de l’API sont les mêmes sur tous les plans.

Quelle est la voie sans code pour envoyer des transcriptions vers Notion ?

Deux bonnes options : Zapier (niveau payant requis pour les zaps multi-étapes) permet de capter un webhook et de créer une page Notion sans code. n8n Cloud propose un modèle Whisper-to-Notion, et la version auto-hébergée fonctionne gratuitement. Les deux conviennent aux flux simples de transcription vers page ; un code personnalisé est préférable pour les blocs avec étiquettes de locuteur, le traitement par lots et les fichiers longs.

Sources

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