Trame · Documentation

Vue d'ensemble — Developers#

L'API Developers de Trame permet de brancher un espace Trame (tenant) à des outils externes : scripts internes, no-code (Zapier/Make/n8n), CRM, ou agents IA. Elle expose quatre surfaces qui partagent la même authentification par clé et la même isolation par tenant :

  • une API REST (/v1/...) pour lire et écrire sur les conversations, brouillons, contacts, agenda, tâches et l'analytics ;
  • des webhooks sortants signés, pour être notifié en temps réel des événements métier ;
  • un serveur MCP (POST /mcp), pour qu'un agent IA agisse avec exactement les mêmes droits qu'une clé API classique — jamais plus ;
  • un SDK JavaScript minimal qui enveloppe l'API REST et le canal MCP. Il ne couvre pas les webhooks : ceux-ci arrivent chez vous, il n'y a rien à appeler.

Base de l'API#

https://<base-api>/public

L'URL réelle de votre espace vous est fournie à l'activation. Le segment /public fait partie de la base, il n'est pas décoratif : toutes les routes se concatènent à cette base, GET /v1/conversations s'appelant donc https://<base-api>/public/v1/conversations. Une URL qui omet ce segment ne joint pas l'API : elle retombe sur l'application web et ne renverra jamais de JSON. Le point d'entrée MCP suit la même règle : https://<base-api>/public/mcp.

Authentification#

Toutes les routes /v1/... et /mcp s'authentifient par un en-tête X-Api-Key (une clé API créée depuis les réglages de votre espace). Il n'y a ni cookie, ni session utilisateur : chaque requête est indépendante et porte sa propre clé. Détail complet : voir Authentification et scopes.

Concepts clés#

  • Tenant : votre espace Trame. Une clé API est scopée à un seul tenant — une requête ne peut jamais lire ou écrire les données d'un autre tenant, quel que soit l'identifiant fourni.
  • Boîte (mailbox) : chaque requête portant sur une conversation cible une boîte précise (paramètre mailbox) ; la clé doit avoir accès à cette boîte, en lecture ou en écriture selon la route. Les routes contacts, agenda et tâches ne portent pas de mailbox : elles sont à l'échelle de l'espace, et exigent que la clé soit rattachée à un membre identifié (sinon 403).
  • Scope : chaque route ou outil MCP exige un scope précis, porté par la clé (ex. read:conversations, mail:send). Une clé ne peut agir que dans la limite de ses scopes.
  • Idempotence : les écritures qui produisent un effet sensible (commentaire, envoi de message, écriture agent) exigent un en-tête Idempotency-Key — un rejeu avec la même clé ne produit jamais un second effet. Utilisez une valeur unique par message : la portée exacte de cette garantie, et le seul cas où un envoi peut être perdu sans erreur, sont décrits dans Authentification et scopes.

Format des réponses et des erreurs#

Toutes les réponses sont application/json. Le corps d'une erreur porte toujours un champ error, mais sa nature dépend de la famille de routes :

FamillesFormeÀ savoir
Conversations, envoi, brouillons, signatures, analytics, webhooks, MCP{ "error": "message lisible en français" }Un texte destiné à un humain — n'écrivez pas de test dessus, il peut être reformulé.
Contacts, agenda, tâches{ "error": "CODE_EN_MAJUSCULES" }Un identifiant stable (BOOK_NOT_FOUND, TITLE_REQUIRED, SOURCE_FORBIDDEN…) — testez-le tel quel, ne l'affichez pas à un utilisateur final. Liste complète : Endpoints REST.

Codes HTTP utilisés : 400 (requête invalide), 401 (clé absente/invalide), 403 (scope manquant, boîte non autorisée, interrupteur d'envoi fermé, clé de type agent sur une route d'envoi, ou clé non rattachée à un membre), 404 (route ou ressource introuvable), 409 (conflit d'idempotence ou avertissement à confirmer), 413 (pièces jointes hors plafond, routes d'envoi), 429 (plafond de fréquence dépassé), 500 (erreur interne — jamais de détail d'implémentation), 502 (reçu d'envoi indisponible, issue ambiguë), 503 (service indisponible, requête réessayable).

Les refus 401 et 429 sont tracés (journal du service, et journal d'audit de votre espace quand la clé est reconnue comme une clé de cet espace) sans que la réponse rendue change en quoi que ce soit : voir Authentification et scopes.

Une écriture demandée par une clé de type agent à approbation requise ne renvoie pas le statut de succès de la route mais 202 { "approvalRequired": true, "approval": { ... } } : rien n'a été écrit, une validation humaine a été demandée. Les en-têtes CORS sont ouverts en lecture (l'auth est la clé, pas l'origine de la requête).

Limites de fréquence#

PortéePlafondRemarque
Toutes les routes (par défaut)120 requêtes/min par clévaleur par défaut, susceptible d'évoluer (pas encore de grille tarifaire figée)
mail:send (envoi de message)10 requêtes/min par clécompteur indépendant — saturer l'envoi ne bloque jamais vos routes de lecture

Le plafond est appliqué par fenêtre glissante de 60 s, par clé, et par famille de route (rateScope) — un dépassement renvoie 429 { "error": "quota dépassé (rate-limit)" }.

Ces plafonds sont comptés par instance de service. Le service pouvant être répliqué sous charge, le débit agrégé effectivement accepté peut dépasser ces valeurs : traitez-les comme un garde-fou anti-emballement, jamais comme une garantie de débit maximal. Un plafond global partagé est une évolution prévue.

Les routes d'envoi appliquent en plus des plafonds de charge utile : pièces jointes, longueur d'une adresse, et deux bornes indépendantes sur le nombre d'adresses — une par champ (to, cc, bcc) et une par message (les trois réunis). Chaque champ peut être sous son plafond et le message être refusé quand même. Voir Endpoints REST, section « Plafonds des routes d'envoi ».