Que fait Notion ?
Parler à Notion de deux manières. Le même jeton d'intégration fonctionne pour les deux — choisissez selon ce qui est disponible.
◆ ntn CLI — La CLI officielle de Notion. Syntaxe plus courte, téléversement de fichiers en une ligne, requis pour les Workers. macOS et Linux seulement en mai 2026 (support Windows "bientôt disponible"). Par défaut si installé.
◆ HTTP + curl — Fonctionne partout, y compris sur Windows. Par défaut si ntn n'est pas installé.
Configuration
1. Obtenir un jeton d'intégration (obligatoire pour les deux voies)
- Créez une intégration sur https://notion.so/my-integrations
- Copiez la clé API (commence par
ntn_ousecret_) - Stockez-la dans
~/.hermes/.env:NOTION_API_KEY=ntn_votre_cle_ici - Partagez les pages/bases de données cibles avec l'intégration dans Notion : menu de la page
...→Connecter à→ le nom de votre intégration. Sans cela, l'API retourne une erreur 404 pour cette page même si elle existe.
2. Installer ntn (voie recommandée sur macOS / Linux)
# Recommandé
curl -fsSL https://ntn.dev | bash
# Ou via npm (nécessite Node 22+, npm 10+)
npm install --global ntn
ntn --version # vérifier
Ignorez ntn login — utilisez plutôt le jeton d'intégration. Cela fonctionne sans interface graphique, aucun navigateur requis :
export NOTION_API_TOKEN=$NOTION_API_KEY # ntn lit NOTION_API_TOKEN
export NOTION_KEYRING=0 # ne pas essayer d'utiliser le trousseau OS
Ajoutez ces exportations à votre profil shell (ou à ~/.hermes/.env) pour que chaque session les hérite.
3. Choisir la voie au moment de l'exécution
if command -v ntn >/dev/null 2>&1; then
# utiliser ntn
else
# utiliser curl comme solution de repli
fi
Utilisateurs Windows : ignorez l'étape 2 jusqu'à ce que la version native de ntn soit disponible — la voie B (curl) fonctionne parfaitement. Si vous voulez une ergonomie CLI dès maintenant, installez ntn dans WSL2.
Principes de base de l'API
Notion-Version: 2025-09-03 est obligatoire sur toutes les requêtes HTTP. ntn gère cela pour vous. Dans cette version, ce que les utilisateurs appellent "bases de données" sont appelées sources de données dans l'API.
Voie A — CLI ntn (recommandée, macOS / Linux)
Appels API bruts (raccourcis pour curl)
ntn api v1/users # GET
ntn api v1/pages parent[page_id]=abc123 \ # POST avec corps en ligne
properties[title][0][text][content]="Notes"
ntn api v1/pages/abc123 -X PATCH archived:=true # PATCH; := pour non-chaîne (bool/num/null)
Notes de syntaxe :
key=value— champs chaînekey[nested]=value— champs d'objet imbriquékey:=value— assignation typée (booléens, nombres, null, tableaux)
Recherche
ntn api v1/search query="titre de la page"
Lire les métadonnées d'une page
ntn api v1/pages/{page_id}
Lire une page en Markdown (adapté aux agents)
ntn api v1/pages/{page_id}/markdown
Lire le contenu d'une page sous forme de blocs
ntn api v1/blocks/{page_id}/children
Créer une page à partir de Markdown
ntn api v1/pages \
parent[page_id]=xxx \
properties[title][0][text][content]="Notes de réunion" \
markdown="# Ordre du jour
- Roadmap T3
- Recrutement"
Modifier une page avec Markdown
ntn api v1/pages/{page_id}/markdown -X PATCH \
markdown="## Mise à jour
Le prototype est livré."
Interroger une base de données (source de données)
ntn api v1/data_sources/{data_source_id}/query -X POST \
filter[property]=Statut filter[select][equals]=Actif
Pour les requêtes complexes avec sorts, plusieurs clauses de filtre ou logique composée, passez le JSON via l'entrée standard :
echo '{"filter": {"property": "Statut", "select": {"equals": "Actif"}}, "sorts": [{"property": "Date", "direction": "descending"}]}' | \
ntn api v1/data_sources/{data_source_id}/query -X POST --json -
Téléversement de fichiers (une seule ligne — le plus grand avantage de la CLI)
ntn files create < photo.png
ntn files create --external-url https://exemple.com/photo.png
ntn files list
Comparez au flux HTTP en 3 étapes (créer téléversement → PUT les octets → référencer).
Variables d'environnement utiles
| Variable | Effet |
|---|---|
NOTION_API_TOKEN | Jeton d'authentification (remplace le trousseau) — définissez-le à votre jeton d'intégration |
NOTION_KEYRING=0 | Identifiants basés sur fichier dans ~/.config/notion/auth.json au lieu du trousseau OS |
NOTION_WORKSPACE_ID | Ignorer la demande de sélection d'espace de travail |
Voie B — HTTP + curl (multiplateforme, par défaut sur Windows)
Toutes les requêtes suivent ce modèle :
curl -s -X GET "https://api.notion.com/v1/..." \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json"
Sur Windows, le curl fourni avec Windows 10+ fonctionne tel quel. Les utilisateurs de PowerShell peuvent également utiliser Invoke-RestMethod.
Recherche
curl -s -X POST "https://api.notion.com/v1/search" \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{"query": "titre de la page"}'
Lire les métadonnées d'une page
curl -s "https://api.notion.com/v1/pages/{page_id}" \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2025-09-03"
Lire une page en Markdown (adapté aux agents)
Plus facile à donner à un modèle que le JSON de blocs.
curl -s "https://api.notion.com/v1/pages/{page_id}/markdown" \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2025-09-03"
Lire le contenu d'une page sous forme de blocs (pour une structure détaillée)
curl -s "https://api.notion.com/v1/blocks/{page_id}/children" \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2025-09-03"
Créer une page à partir de Markdown
POST /v1/pages accepte un paramètre de corps markdown.
curl -s -X POST "https://api.notion.com/v1/pages" \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{
"parent": {"page_id": "xxx"},
"properties": {"title": [{"text": {"content": "Notes de réunion"}}]},
"markdown": "# Ordre du jour\n\n- Roadmap T3\n- Recrutement\n\n## Décisions\n- Livrer le prototype vendredi"
}'
Modifier une page avec Markdown
curl -s -X PATCH "https://api.notion.com/v1/pages/{page_id}/markdown" \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{"markdown": "## Mise à jour\n\nLe prototype est livré."}'
Créer une page dans une base de données (propriétés typées)
curl -s -X POST "https://api.notion.com/v1/pages" \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{
"parent": {"database_id": "xxx"},
"properties": {
"Name": {"title": [{"text": {"content": "Nouvel élément"}}]},
"Statut": {"select": {"name": "À faire"}}
}
}'
Interroger une base de données (source de données)
curl -s -X POST "https://api.notion.com/v1/data_sources/{data_source_id}/query" \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{
"filter": {"property": "Statut", "select": {"equals": "Actif"}},
"sorts": [{"property": "Date", "direction": "descending"}]
}'
Créer une base de données
curl -s -X POST "https://api.notion.com/v1/data_sources" \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{
"parent": {"page_id": "xxx"},
"title": [{"text": {"content": "Ma base de données"}}],
"properties": {
"Nom": {"title": {}},
"Statut": {"select": {"options": [{"name": "À faire"}, {"name": "Terminé"}]}},
"Date": {"date": {}}
}
}'
Mettre à jour les propriétés d'une page
curl -s -X PATCH "https://api.notion.com/v1/pages/{page_id}" \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{"properties": {"Statut": {"select": {"name": "Terminé"}}}}'
Ajouter des blocs à une page
curl -s -X PATCH "https://api.notion.com/v1/blocks/{page_id}/children" \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{
"children": [
{"object": "block", "type": "paragraph", "paragraph": {"rich_text": [{"text": {"content": "Bonjour de la part d'Hermes!"}}]}}
]
}'
Téléversement de fichiers (flux en 3 étapes)
# 1. Créer le téléversement
curl -s -X POST "https://api.notion.com/v1/file_uploads" \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{"filename": "photo.png", "content_type": "image/png"}'
# 2. PUT les octets vers l'upload_url retourné ci-dessus
curl -s -X PUT "{upload_url}" --data-binary @photo.png
# 3. Référencer {file_upload_id} dans la charge utile d'une page/bloc
Types de propriétés
Formats de propriétés courants pour les éléments de base de données :
- Titre :
{"title": [{"text": {"content": "..."}}]} - Texte enrichi :
{"rich_text": [{"text": {"content": "..."}}]} - Sélection :
{"select": {"name": "Option"}} - Sélection multiple :
{"multi_select": [{"name": "A"}, {"name": "B"}]} - Date :
{"date": {"start": "2026-01-15", "end": "2026-01-16"}} - Case à cocher :
{"checkbox": true} - Nombre :
{"number": 42} - URL :
{"url": "https://..."} - E-mail :
{"email": "[email protected]"} - Relation :
{"relation": [{"id": "page_id"}]}
Version de l'API 2025-09-03 — Bases de données vs Sources de données
- Les bases de données sont devenues des sources de données. Utilisez les points de terminaison
/data_sources/pour les requêtes et la récupération. - Deux IDs par base de données :
database_idetdata_source_id.database_idlors de la création de pages :parent: {"database_id": "..."}data_source_idlors de l'interrogation :POST /v1/data_sources/{id}/query
- La recherche retourne les bases de données comme
"object": "data_source"avec le champdata_source_id.
Workers Notion (avancé, nécessite ntn)
Les Workers sont des programmes TypeScript que Notion héberge pour vous. Un Worker peut exposer n'importe quelle combinaison de :
- Synchronisations — importer des données d'API externes dans une base de données Notion selon un calendrier (30 min par défaut).
- Outils — apparaissent comme outils appelables dans les Agents personnalisés de Notion.
- Webhooks — recevoir des événements HTTP de services externes (GitHub, Stripe, etc.) et agir dans Notion.
Restrictions selon le plan / plateforme :
- La CLI fonctionne sur tous les plans. Le déploiement de Workers nécessite Business ou Enterprise.
ntnest disponible uniquement sur macOS/Linux en mai 2026. Les utilisateurs Windows ont besoin de WSL2 ou doivent attendre le support natif.- Gratuit jusqu'au 11 août 2026 ; facturé en crédits Notion par la suite.
Worker minimal
ntn workers new my-worker # générer la structure
cd my-worker
# Modifier src/index.ts
ntn workers deploy --name my-worker
src/index.ts :
import { Worker } from "@notionhq/workers";
const worker = new Worker();
export default worker;
worker.tool("saluer", {
title: "Saluer un utilisateur",
description: "Retourne un message de bienvenue",
inputSchema: { type: "object", properties: { nom: { type: "string" } }, required: ["nom"] },
execute: async ({ nom }) => `Bonjour, ${nom}!`,
});
Fonctionnalité webhook
worker.webhook("onGithubPush", {
title: "Gestionnaire de push GitHub",
execute: async (events, { notion }) => {
for (const event of events) {
// event.body, event.rawBody (pour vérification de signature), event.headers
console.log("livraison reçue", event.deliveryId);
}
},
});
Après déploiement : ntn workers webhooks list affiche l'URL générée par Notion. Traitez cette URL comme secrète — toute personne qui la possède peut POSTer des événements à moins que vous n'ajoutiez une vérification de signature.
Commandes du cycle de vie du Worker
ntn workers deploy
ntn workers list
ntn workers exec <cle-capacite> -d '{"nom": "monde"}'
ntn workers sync trigger <cle> # exécuter une synchronisation maintenant
ntn workers sync pause <cle>
ntn workers env set GITHUB_WEBHOOK_SECRET=...
ntn workers runs list # invocations récentes
ntn workers runs logs <id-execution>
ntn workers webhooks list
Lorsque vous devez créer un Worker, générez la structure avec ntn workers new, écrivez le code dans src/index.ts, définissez les secrets avec ntn workers env set, et déployez. La documentation de Notion sur https://developers.notion.com/workers couvre l'intégralité de la surface de l'API.
Markdown façon Notion (utilisé par les points de terminaison /markdown)
CommonMark standard plus des balises de type XML pour les blocs spécifiques à Notion. Utilisez des tabulations pour l'indentation.
Blocs au-delà de CommonMark :
<callout icon="🎯" color="blue_bg">
Livrez le MVP d'ici **vendredi**.
</callout>
<details color="gray">
<summary>Titre du bloc déroulant</summary>
Enfants indentés d'une tabulation
</details>
<columns>
<column>Côté gauche</column>
<column>Côté droit</column>
</columns>
<table_of_contents color="gray"/>
En ligne :
- Mentions :
<mention-user url="..."/>,<mention-page url="...">Titre</mention-page>,<mention-date start="2026-05-15"/> - Souligné :
<span underline="true">texte</span> - Couleur :
<span color="blue">texte</span>ou au niveau du bloc{color="blue"}sur la première ligne - Mathématiques : en ligne
$x^2$, bloc$$ ... $$ - Citations :
[^https://exemple.com]
Couleurs : gray brown orange yellow green blue purple pink red, plus les variantes *_bg pour les arrière-plans.
Les titres de niveau 5/6 sont convertis en H4. Plusieurs lignes > s'affichent comme des blocs de citation séparés — utilisez <br> à l'intérieur d'un seul > pour les citations multilignes.
Choisir la bonne voie
| Tâche | macOS / Linux | Windows |
|---|---|---|
| Lire/écrire des pages, rechercher, interroger des bases de données | ntn api ... | curl |
| Lire une page pour qu'un agent la résume | ntn api v1/pages/{id}/markdown | point de terminaison curl /markdown |
| Téléverser un fichier | ntn files create < fichier | Flux HTTP en 3 étapes |
| Exploration API ponctuelle | ntn api ... | curl |
| Construire une synchronisation / un webhook / un outil agent hébergé par Notion | ntn workers ... | WSL2 + ntn workers ... |
Remarques
- Les IDs de page/base de données sont des UUIDs (avec ou sans tirets — les deux sont acceptés).
- Limite de débit : ~3 requêtes/seconde en moyenne. La CLI ne contourne pas cette limite.
- L'API ne peut pas définir les filtres de vue d'une base de données — c'est réservé à l'interface utilisateur.
- Utilisez
"is_inline": truelors de la création de sources de données pour les intégrer dans une page. - Passez toujours
-sà curl pour supprimer les barres de progression (sortie agent plus propre). - Passez le JSON dans
jqlors de la lecture :... | jq '.results[0].properties'. - Notion propose également un serveur MCP maintenant (`Notion
…
[truncated for translation]