Notion Agent API : piloter vos agents IA par code (2026)
La Notion Agent API permet, depuis le 20 août 2026, de déclencher un Custom Agent, de suivre sa réponse en temps réel et d’administrer vos agents depuis votre propre code. Elle est en bêta publique, sans liste d’attente, sur les plans Business et Enterprise.
Le calendrier a son importance : les routes de l’alpha privée ont été fermées le 30 septembre 2026. Si vous aviez bâti une intégration pendant l’accès anticipé et qu’elle renvoie des erreurs depuis trois semaines, ce guide vous donne la table de correspondance exacte. Pour les autres, c’est le moment de découvrir une API qui transforme en briques programmables les agents personnalisés, dont plus d’un million ont été créés en deux mois après le lancement de la bêta en février 2026 (Notion, bilan de la bêta des Custom Agents, mai 2026).
Ce que la Notion Agent API permet de faire
La Notion Agent API répond à une question simple : comment utiliser un Custom Agent ailleurs que dans l’interface Notion ? Jusqu’à l’été 2026, un agent ne se déclenchait que depuis l’application, par une automation, une @-mention ou une planification. L’API ouvre deux familles d’opérations.
Dialoguer avec un agent. Vous démarrez une session, vous envoyez un message, vous lisez la réponse. L’agent peut vous demander une approbation en cours de route ; vous la soumettez par l’API. Tout l’historique est consultable sous forme d’événements.
Administrer les agents. Vous listez les agents accessibles, vous lisez leurs métriques de consommation, vous fixez un plafond de crédits, vous activez, désactivez ou supprimez un agent, à l’unité ou par lot de 100.
Les cas d’usage cités par la documentation officielle sont un bot Slack, un outil interne, un client mobile et un tableau de bord d’administration. J’ajouterais tout ce qui ressemble à un déclencheur externe : un formulaire soumis, un ticket créé, une opportunité fermée dans un CRM.
REST pour la donnée, Agent API pour piloter un agent depuis votre application, MCP pour laisser un assistant IA le faire.
Agent API, API REST classique et MCP : trois couches distinctes
Les trois sont souvent confondues parce qu’elles partagent le même domaine, api.notion.com, et le même en-tête de version. Elles n’ont pourtant ni le même objet ni le même appelant.
| Couche | Ce qu’elle manipule | Qui appelle | Cas typique |
|---|---|---|---|
| API REST classique | Pages, bases de données, blocs, utilisateurs | Votre code | Synchroniser un CRM vers une base Notion |
| Notion Agent API | Sessions et Custom Agents | Votre code | Embarquer un agent dans un bot Slack |
| Serveur MCP officiel | Pages, bases, et sessions d’agents (outils) | Un assistant IA | Laisser Claude lancer un agent Notion |
| External Agents API | Agents tiers dans Notion | Claude Code, Codex | Assigner une tâche Notion à Claude Code |
La règle que j’applique : si l’appelant est un humain ou un assistant IA, le MCP suffit et ne demande aucun code. Si l’appelant est votre propre application, la Notion Agent API est le bon outil. L’API REST reste indispensable pour la donnée brute : l’Agent API ne lit ni n’écrit de pages par elle-même.
Prérequis et authentification
Trois éléments sont nécessaires avant la première requête.
Un Custom Agent existant. L’API ne crée pas d’agent. Vous le construisez dans l’application, comme décrit dans mon guide des Custom Agents, puis vous l’adressez par son identifiant.
Un jeton. Deux options : un personal access token (PAT), qui agit en votre nom et hérite de vos accès ; ou un jeton de connexion interne, qui doit disposer de la capacité « View sessions and interact with agents » et ne voit que les agents partagés avec cette connexion sous Agent access.
Les en-têtes habituels. Authorization: Bearer ntn_***, Notion-Version: 2026-03-11 (seule valeur acceptée) et Content-Type: application/json sur les POST.
Trois niveaux d’accès par agent
L’autorisation est évaluée agent par agent, avec les mêmes permissions que dans Notion :
- Read : lire l’agent et ses sessions.
- Edit : modifier son statut, le supprimer, déclencher des runs sur toutes ses sessions.
- Full : lire et modifier le plafond de crédits. Sans ce niveau, le champ
credit_limitrenvoie la chaîne"hidden"au lieu d’être omis.
Un détail qui a son importance en production : les sessions créées avec un PAT peuvent être poursuivies dans l’application Notion. Les sessions créées avec un jeton de connexion n’ont pas d’utilisateur associé et ne se poursuivent que par l’API.

Les 12 endpoints de la bêta publique
La bêta publique expose cinq endpoints de session et sept endpoints d’administration, tous préfixés https://api.notion.com/v1/ et décrits dans la référence officielle des Notion Agent APIs.
| Famille | Endpoint | Rôle |
|---|---|---|
| Sessions | POST /sessions | Démarrer, poursuivre, soumettre une action, streamer |
| Sessions | GET /sessions/{id} | Statut, métadonnées, actions requises |
| Sessions | POST /sessions/query | Rechercher les sessions accessibles |
| Sessions | POST /sessions/{id}/events/query | Paginer les événements |
| Sessions | POST /sessions/{id}/cancel | Interrompre un run en cours |
| Agents | POST /agents/query | Lister les Custom Agents accessibles |
| Agents | GET /agents/{id} | Métadonnées d’un agent |
| Agents | GET /agents/{id}/insights | Crédits consommés, runs complétés |
| Agents | PATCH /agents/{id}/status | Activer ou désactiver |
| Agents | PATCH /agents/{id}/credit_limit | Fixer ou retirer un plafond |
| Agents | DELETE /agents/{id} | Suppression douce |
| Agents | POST /agents/batch | 1 à 100 opérations, asynchrone |
Un seul endpoint, POST /sessions, concentre toute la conversation. C’est un choix de conception qui simplifie le client mais qui impose de bien comprendre ses trois modes.
Quatre requêtes suffisent pour un tour complet ; le statut
requires_action ouvre une boucle de validation humaine avant la reprise du run.
Dialoguer avec un Custom Agent : le cycle complet
J’ai suivi le quickstart officiel avec un PAT et un agent de synthèse hebdomadaire. Voici le cycle réel, en quatre requêtes.
Étape 1 : identifier l’agent
curl -X POST https://api.notion.com/v1/agents/query \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2026-03-11" \
-H "Content-Type: application/json" \
-d '{ "sorts": [{ "property": "created_time", "direction": "descending" }], "page_size": 10 }'
La réponse suit l’enveloppe habituelle de pagination (results, has_more, next_cursor). Chaque agent porte un id, un name et un status.
Étape 2 : créer la session
curl -X POST https://api.notion.com/v1/sessions \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2026-03-11" \
-H "Content-Type: application/json" \
-d '{ "agent_id": "'$AGENT_ID'", "message": "Résume les tâches terminées cette semaine." }'
La réponse est un objet session avec "status": "queued". Le message est limité à 10 000 caractères, et vous pouvez joindre jusqu’à 100 fichiers via attachments, ajouter un prompt_context de 10 000 caractères et un objet metadata de 20 paires clé-valeur pour vos propres identifiants (numéro de ticket, utilisateur Slack).
Étape 3 : attendre la fin du run
L’agent s’exécute de façon asynchrone. Sans streaming, vous interrogez GET /sessions/{id} jusqu’à ce que le statut quitte queued ou in_progress. Les sept statuts possibles sont queued, in_progress, requires_action, completed, failed, canceled et terminated.
Deux pièges relevés dans le guide de migration : canceled désigne un tour arrêté volontairement et ne doit pas être traité comme completed ; terminated doit être géré séparément de failed. Tout statut inconnu doit être considéré comme non terminal.
Étape 4 : lire la réponse
curl -X POST https://api.notion.com/v1/sessions/$SESSION_ID/events/query \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2026-03-11" \
-H "Content-Type: application/json" \
-d '{ "filter": { "property": "type", "event_type": { "equals": "agent.message" } } }'
La réponse de l’agent est découpée en parties text dans le tableau content : il faut les concaténer. Six types d’événements existent : user.message, agent.message, agent.thinking, agent.tool_use, agent.tool_result et session.status. Chaque événement porte un numéro sequence, un created_at et un metadata qui indique le modèle utilisé.
Pour poursuivre la conversation, renvoyez un POST /sessions avec le même session_id et un nouveau message. Le SDK TypeScript officiel @notionhq/client expose cela sous notion.sessions.update({ session_id, message }).
Streaming en server-sent events
Le streaming remplace le polling pour toute interface conversationnelle. Il suffit d’ajouter Accept: text/event-stream à la requête POST /sessions ; il n’existe pas de champ stream dans le corps.
Chaque événement SSE est une enveloppe dont le champ type dicte le traitement :
| Type d’enveloppe | Action côté client |
|---|---|
session.snapshot | Lire l’état de la session au démarrage du flux |
event.provisional | Afficher la sortie en cours, ne pas la persister |
event.committed | Enregistrer l’événement durable (event.committed.event) |
stream.timeout | Le tour continue, se reconnecter |
stream.end | Tour terminé ; si requires_action, soumettre une action |
stream.error | Échec ; vérifier error.retryable |
La reprise sur coupure est le point que je trouve le mieux conçu. Vous conservez l’id du dernier event.committed.event reçu et, à la reconnexion, vous renvoyez session_id et continue_from avec cet identifiant. Seuls les identifiants d’événements committed sont acceptés : un numéro de séquence ou un identifiant d’événement provisoire sera rejeté.

Soumettre une action demandée par l’agent
Un Custom Agent peut suspendre son exécution pour demander une validation : publier une page, envoyer un e-mail, supprimer des lignes. La session passe alors en requires_action et l’objet session expose un tableau required_actions dont chaque entrée porte un action_id, un title et des options (approve ou reject).
Vous répondez avec le même endpoint, en mode action :
{
"session_id": "2a1c7c06-781b-4987-9986-5c8dd3028014",
"actions": [
{ "action_id": "act_01", "option_id": "approve" }
]
}
Le corps accepte entre 1 et 100 actions uniques. Ce mécanisme reproduit par l’API l’étape « human in the loop » que vous connaissez dans l’interface, et c’est ce qui rend viable l’intégration dans un bot Slack : l’agent prépare, l’humain valide depuis Slack, l’agent exécute.
Un cas d’erreur fréquent : envoyer un message alors qu’un run est en cours renvoie un 409 conflict_error. Attendez le statut terminal avant de renvoyer.
Administrer vos agents par programmation
La seconde famille d’endpoints vise les administrateurs et les équipes qui opèrent des dizaines d’agents. Ramp, par exemple, fait tourner plus de 300 agents en production selon l’étude de cas publiée par Notion ; à cette échelle, le dashboard Notion Credits ne suffit plus et un pilotage scriptable devient nécessaire.
Lire les insights d’usage
GET /agents/{id}/insights renvoie, pour la période de facturation courante ou une fenêtre start_time/end_time en secondes Unix, les champs total_credits_used, runs_completed, credit_limit et pause_reason. Ce dernier prend une quinzaine de valeurs documentées, dont run_limit, credit_limit, runaway_credit_usage, failure_limit, disabled_from_api ou needs_user_review, ce qui permet de diagnostiquer pourquoi un agent est à l’arrêt sans ouvrir l’application.
Avec un tarif de 10 dollars pour 1 000 crédits et une consommation estimée par Notion entre 5 crédits (tâche simple) et 25 crédits (tâche complexe) par exécution (aide Notion, tarification des Custom Agents), un agent qui tourne 50 fois par jour coûte entre 75 et 375 dollars par mois. Les modèles légers comme Haiku 4.5 ou GPT-5.4 Mini consomment jusqu’à 10 fois moins de crédits que les modèles avancés, toujours selon Notion. L’endpoint d’insights est le seul moyen de brancher cette donnée sur votre propre outil de suivi de coûts.
Plafonner, désactiver, supprimer
PATCH /agents/{id}/credit_limit fixe un entier supérieur ou égal à zéro, ou null pour retirer le plafond ; il exige l’accès Full et ne s’applique pas à l’agent personnel notion_ai. PATCH /agents/{id}/status bascule entre active et disabled. DELETE /agents/{id} effectue une suppression douce.
Opérations par lot
POST /agents/batch accepte 1 à 100 opérations (update_status, update_credit_limit, delete) et répond immédiatement par un objet async_task avec un status_url et un poll_after_seconds. Le lot n’est pas atomique : chaque opération réussit ou échoue indépendamment, et vous rapprochez les résultats par index.
J’y vois l’outil naturel d’un script de fin de mois : lire les insights de tous les agents, désactiver ceux dont runs_completed est à zéro, abaisser le plafond de ceux qui ont dépassé leur budget. Trois appels, un tableau de bord Notion mis à jour par l’API REST classique, et la revue mensuelle est faite.
5 routes à remplacer : les threads deviennent des sessions, les messages des événements, et le streaming passe de NDJSON aux server-sent events.
Migration des routes alpha : la table de correspondance
Si vous aviez accès à l’alpha privée, vos appels ont cessé de fonctionner le 30 septembre 2026. Cinq routes seulement sont concernées, mais le changement de modèle est profond.
| Usage | Route alpha (fermée) | Route bêta publique |
|---|---|---|
| Lister les agents | GET /v1/agents | POST /v1/agents/query |
| Lister les threads | GET /v1/agents/:id/threads | POST /v1/sessions/query |
| Lister les messages | GET /v1/threads/:id/messages | POST /v1/sessions/:id/events/query |
| Chat | POST /v1/agents/:id/chat | POST /v1/sessions |
| Chat en streaming | POST /v1/agents/:id/chatStream | POST /v1/sessions + Accept: text/event-stream |
Les ruptures à traiter dans votre code :
- Format : les paramètres d’URL deviennent des corps JSON ; les filtres sont des objets
property+ condition combinables parand/or;sort_bydevient un tableausorts. - Vocabulaire :
thread_iddevientsession_id, les messages deviennent des événements avecsequenceettype,created_timedevientcreated_at. - Statuts :
pendingest remplacé parqueuedetin_progress;terminatedapparaît. - Erreurs : le champ
errorpasse d’une chaîne à un objet{ code, message, retryable }; les échecs d’inférence ne sont plus renvoyés comme des messages d’agent. - Streaming : les chunks NDJSON sont remplacés par des server-sent events.
- Champs cachés : ce que vous n’avez pas le droit de lire renvoie
"hidden"au lieu d’être omis.
Le SDK @notionhq/agents-client publié sur GitHub reste étiqueté alpha et utilise encore le vocabulaire thread/chatStream. Pour la bêta publique, appuyez-vous sur @notionhq/client, qui expose sessions.update, agents.retrieveInsights et agents.batch.
Les outils de session côté MCP
Depuis le 27 août 2026, le serveur MCP officiel de Notion expose les mêmes capacités sous forme d’outils : rechercher et interroger les sessions, démarrer une session, envoyer un suivi, vérifier ou attendre le statut d’un run, l’arrêter, lister et lire ses événements. Depuis le 10 septembre, ces outils acceptent la notation abrégée session://<id> et renvoient un 400 validation_error sur une URL malformée.
Deux précisions issues du changelog de septembre : un espace de travail sans accès aux Custom Agents reçoit une invite de mise à niveau plutôt qu’une erreur, et une connexion qui ne dispose pas de la capacité « View sessions and interact with agents » ne voit pas ces outils : elle doit être reconnectée ou réautorisée (changelog du 1er septembre). Enfin, un message envoyé pendant un run en cours renvoie une erreur de conflit : l’outil d’attente de session doit être appelé avant.
Ma position : le MCP est la voie courte pour qu’un assistant pilote vos agents ; l’Agent API est la voie durable pour qu’une application le fasse. Les deux reposent sur le même modèle de sessions, si bien que ce que vous apprenez sur l’un se transfère à l’autre.
Limites de débit, erreurs et bonnes pratiques
Depuis le 9 septembre 2026, la limite par connexion est de 600 requêtes par minute sur Business et Enterprise, et de 180 sur les autres plans, sur une fenêtre fixe de 60 secondes (changelog développeurs Notion). Un 429 rate_limited indique le délai d’attente dans le corps de la réponse, sous additional_data.retry_after, en plus de l’en-tête Retry-After qui ne dépasse jamais 60 secondes (comportement généralisé à toutes les réponses 429 et 529 le 24 septembre).
Les erreurs spécifiques aux agents sont explicites : 403 workspace_credits_exhausted et 403 agent_credit_limit_reached incluent un recovery_kind (open_workspace_credit_settings, request_agent_limit_increase, contact_workspace_owner) et parfois un recovery_url. Un 409 agent_deleted signale que l’agent ciblé a été supprimé depuis.
Les règles que je recommande avant une mise en production :
- Persistez uniquement les événements
event.committedet gardez leur identifiant pour la reprise. - Traitez
requires_actioncomme un état d’attente, pas comme une fin de run. - Stockez vos identifiants métier dans
metadataplutôt que dans le message. - Plafonnez chaque agent exposé par l’API via
credit_limitdès le premier jour. - Lisez les insights chaque semaine et désactivez les agents inactifs par lot.
Mon avis sur la Notion Agent API
Mon verdict : la Notion Agent API est la pièce qui manquait à la Developer Platform pour sortir les Custom Agents de l’application. Le modèle sessions-événements est cohérent, le streaming avec reprise est bien pensé, et l’API d’administration couvre des besoins réels d’équipes qui opèrent des dizaines d’agents.

Les réserves sont de deux ordres. L’API ne crée pas d’agent : le cycle de vie complet reste dépendant de l’interface. Et l’API a déjà connu un changement structurel entre l’alpha et la bêta publique ; il serait imprudent d’exclure un second ajustement avant la version stable, d’autant que Notion n’a annoncé aucune date de disponibilité générale.
Si vous opérez moins de cinq agents et que vos appelants sont des assistants IA, le serveur MCP suffit. Si vous construisez un bot Slack, un outil interne ou un tableau de bord de coûts, l’Agent API est prête pour un premier déploiement maîtrisé, avec des plafonds de crédits et une journalisation des événements dès le départ.