Notion comme CMS headless : ce qui coince, et ce qui change
Un site qui lit l'API Notion : limites de débit, blocs imbriqués, URLs de fichiers qui expirent, webhooks sans contenu — et la réponse de Spunto CMS.
Utiliser Notion comme CMS d'un site web est un premier choix raisonnable. L'équipe y écrit déjà, l'éditeur est excellent, et l'API sait interroger une base de données. Quantité de blogs et de sites de documentation tournent dessus.
Cette page parle de ce qui a tendance à apparaître quand le site grandit, et de ce que Spunto CMS fait autrement. Elle essaie d'être juste envers les deux : là où Notion fait mieux, elle le dit.
Sources
Toutes les affirmations sur Notion ci-dessous viennent de la documentation développeur de Notion elle-même, telle que consultée en octobre 2026, et renvoient à la page d'où elles sont tirées. Notion fait évoluer son API : vérifiez le lien avant de vous fier à un chiffre.
Ce qu'un site rencontre
Limites de requêtes
L'API de Notion autorise
180 requêtes par minute, soit 3 par seconde en moyenne,
sur la plupart des offres ; Business et Enterprise ont droit à 600 par minute.
Au-delà, vous recevez un 429.
C'est largement suffisant pour une personne qui clique dans l'éditeur, et juste pour un build statique : une page avec ses blocs, c'est plusieurs requêtes (voir plus bas), si bien qu'un site de quelques centaines de pages passe son build à attendre le limiteur.
Blocs imbriqués, un niveau par appel
Récupérer les enfants d'un bloc « ne renvoie que le premier niveau d'enfants » (returns only the first level of children), avec au plus 100 résultats par appel. Un toggle, une liste imbriquée ou une mise en colonnes, c'est un niveau de plus, donc une requête de plus. Rendre une page revient à un parcours récursif.
Les URLs de fichiers expirent
Un fichier hébergé par Notion est fourni avec une URL temporaire valable une heure, et la documentation le dit sans détour : « Ne mettez pas ces URLs en cache et ne les référencez pas de façon statique » (Don't cache or statically reference these URLs.). Une page générée statiquement qui les intègre affiche des images cassées une heure après le build — à moins que le build ne recopie d'abord chaque fichier ailleurs.
Les notifications de changement portent des identifiants
Notion a bien des webhooks.
Une livraison porte l'identifiant de la page et le type d'événement, pas le
contenu, et les événements page.content_updated « sont regroupés et peuvent ne
pas être envoyés immédiatement » (are batched and may not be sent
immediately) — la documentation conseille d'attendre une minute ou deux. Pour
reconstruire une page, il faut la récupérer à nouveau, sous la même limite de
débit.
Ce que Spunto CMS fait à la place
Spunto CMS est un espace de travail dans l'esprit de Notion — des listes de cartes, des propriétés typées, des corps de cartes structurés en blocs, des vues sauvegardées — et les lignes que l'équipe modifie sont les lignes que renvoie l'API. Voici comment il répond à chacun des points ci-dessus.
| API Notion | Spunto CMS | |
|---|---|---|
| Limites de requêtes | 3 req/s en moyenne sur la plupart des offres, 10 sur Business et Enterprise | Aucune aujourd'hui — énoncé comme un fait, pas comme une promesse |
| Le corps d'une page | Parcours récursif, un niveau et 100 blocs par appel | Un seul appel : GET …/items/{itemId} renvoie le document entier — une liste plate de blocs avec un indent (corps des cartes) |
| Lister | Requête sur la base, 100 par page | Requête de vue avec un arbre de filtres, 200 par page, curseur keyset (requêtes) |
| Fichiers | URL publique temporaire, valable une heure | Aucune URL publique : l'API sert les octets derrière votre jeton, et un identifiant de fichier ne change jamais de contenu — votre site le relaie une fois et le met en cache pour de bon (fichiers) |
| Notifications de changement | Identifiants et type d'événement ; mises à jour du contenu regroupées | Les clés modifiées avec avant et après, signées (HMAC avec horodatage), retentées, une livraison par édition en masse, et un journal rejouable à partir d'un curseur (événements et webhooks) |
| Types pour votre code | SDK JavaScript officiel (@notionhq/client), typé | Générés depuis la spécification OpenAPI en une commande — en TypeScript, ou dans tout langage doté d'un générateur OpenAPI |
La ligne des fichiers est celle qu'on lit de travers. Spunto ne vous donne pas non plus une URL qui marche pour toujours — il ne vous donne aucune URL. C'est délibéré : un lien partageable serait une seconde porte d'entrée, plus faible que le jeton. Ce qui change, c'est que les octets derrière un identifiant sont immuables : une seule route de relais sur votre site (exemple) les met en cache indéfiniment au lieu de les récupérer à nouveau toutes les heures.
Là où Notion a de l'avance
Soyez au clair là-dessus avant de déplacer quoi que ce soit :
- L'éditeur et le modèle de base de données sont bien plus riches. Spunto a dix types de propriétés et ni relations, ni rollups, ni formules. Si votre modèle de contenu en dépend, restez.
- Les pages publiques. Notion peut publier une page sur le web à lui seul. Spunto n'a ni page publique ni lien de partage ; votre site est la seule surface publique.
- Maturité et écosystème. Notion a des années d'intégrations et de moteurs de rendu communautaires. Spunto CMS est jeune.
Lisez ce qu'il ne fait pas avant de décider. C'est court.
Migrer une base Notion
POST /workspaces/{workspaceId}/import existe pour ça. La requête nomme sa
source (notion) et chaque carte porte l'identifiant de sa page Notion en
externalId : l'import est donc rejouable. Relancez-le, il met à jour au
lieu de dupliquer, et une carte qui n'a pas changé n'est pas réécrite — ni
écriture, ni événement, ni webhook. Un import échoue toujours au moins une fois ;
celui-ci, vous pouvez le relancer jusqu'à ce qu'il soit juste.
La correspondance entre les propriétés et blocs de Notion et ceux de Spunto est
à votre charge : statuts vers statuts, select vers select, et les blocs de
Notion vers les dix types de blocs. Les règles
sont dans les imports qu'on peut lancer deux fois.
Et ensuite
Le guide Next.js relie un site à Spunto de bout en
bout : client typé, rendu des corps, images et revalidation par webhook. Un
compte gratuit sur /login suffit pour le suivre.
Next.js avec un CMS headless : guide pas à pas
Spunto CMS comme CMS headless d'un site Next.js : client typé généré depuis l'OpenAPI, server components, rendu des blocs, images et revalidation par webhook.
Écrire un connecteur pour la marketplace
Un service qui se connecte avec Spunto CMS, reçoit les webhooks d'un espace et se publie dans la marketplace — OAuth avec PKCE, webhooks à soi, vérification des signatures.