Trame · Documentation

SDK JavaScript#

Un SDK JS existe : sdk/trame.js, classe Trame. Il enveloppe l'API REST et le canal MCP avec l'authentification par clé API, et normalise les erreurs en trois classes distinctes. Il ne couvre pas les webhooks sortants : ceux-ci sont livrés à votre serveur, il n'y a rien à appeler.

Installation et usage#

Le nom de package (@trame/sdk ou autre) et sa publication sur un registre ne sont pas encore décidés — voir Statut en bas de page. En attendant, le fichier peut être importé directement depuis le dépôt.

js
import { Trame } from './sdk/trame.js';

const trame = new Trame({
  // Base de l'API, segment de montage compris — voir « Base de l'API » dans la Vue d'ensemble.
  baseUrl: 'https://<base-api>',
  apiKey: process.env.TRAME_API_KEY,
});

const { conversations } = await trame.conversations.list({ mailbox: 'contact@exemple.com' });

baseUrl attend le domaine seul : le SDK ajoute lui-même le segment /public à chaque appel. Ne le mettez donc pas deux fois.

Surface réelle#

js
// Conversations
await trame.conversations.list({ mailbox });
await trame.conversations.get(id, { mailbox });
await trame.conversations.assign(id, { mailbox, assignee, status, teamId }, options);
await trame.conversations.comment(id, { mailbox, text }, { idempotencyKey: 'clé-unique' });
await trame.conversations.labels(id, { mailbox, add: ['urgent'], remove: [] }, options);

// Recherche
await trame.search.query({ mailbox, q: 'facture' });

// Brouillons
await trame.drafts.list({ mailbox });
await trame.drafts.create({ mailbox, draft: { to: [...], subject, body } }, options);
await trame.drafts.update(id, { mailbox, draft: {...} }, options);
await trame.drafts.delete(id, { mailbox }, options);   // le 2e argument part en paramètres d'URL

// Contacts  (voir Endpoints REST pour les champs exacts : displayName, emails[{value,type}]…)
await trame.contacts.list({ bookId, q, sort });
await trame.contacts.get(id);
await trame.contacts.create({ bookId, displayName, emails: [{ value, type }] }, options);
await trame.contacts.update(id, { ...changements }, options);
await trame.contacts.delete(id, {}, options);

// Agenda  (dates en millisecondes depuis epoch : startMs / endMs, jamais de chaîne ISO)
await trame.calendar.listCalendars();
await trame.calendar.getCalendar(id);
await trame.calendar.createCalendar({ name, scope, color }, options);
await trame.calendar.updateCalendar(id, { ...changements }, options);
await trame.calendar.deleteCalendar(id, {}, options);
await trame.calendar.listEvents({ calendarId, from, to });
await trame.calendar.getEvent(id);
await trame.calendar.createEvent({ calendarId, title, startMs, endMs }, options);
await trame.calendar.updateEvent(id, { ...changements }, options);
await trame.calendar.deleteEvent(id, {}, options);

// Tâches
await trame.tasks.list({ status, assignee, q });
await trame.tasks.get(id);
await trame.tasks.create({ title, dueMs }, options);
await trame.tasks.update(id, { status: 'done' }, options);
await trame.tasks.delete(id, {}, options);

// Analytics
await trame.analytics.summary({ from: '2026-07-01', to: '2026-07-26' });

// MCP
await trame.mcp.initialize();
const { tools } = await trame.mcp.listTools();
await trame.mcp.callTool('trame_search', { query: 'facture', mailbox: 'contact@exemple.com' });
await trame.mcp.request('tools/list');   // appel JSON-RPC brut

trame.calendar.getCalendar et trame.calendar.updateCalendar existent dans le SDK mais ne correspondent à aucune route côté serveur : l'API n'expose ni la lecture ni la modification unitaire d'un calendrier (seules la liste, la création et la suppression le sont). Ces deux méthodes échouent en 405 { "error": "METHOD_NOT_ALLOWED" }.

Options d'appel — pas sur toutes les méthodes#

Les méthodes d'écriture (assign, comment, labels, create, update, delete) et les appels MCP acceptent un dernier argument d'options : idempotencyKey (transmis en en-tête Idempotency-Key), signal (AbortController), et headers.

Les méthodes de lecture (list, get, search.query, analytics.summary) n'ont pas cet argument : leur second paramètre est la requête, et rien d'autre n'est transmis. Pour annuler une lecture, appelez directement trame.request('/public/v1/...', { query, signal }).

Pas d'envoi de mail dans le SDK#

Aucune méthode send n'existe sur trame.conversations ou ailleurs — cohérent avec l'absence de route d'envoi accessible sans le scope dédié mail:send (voir Authentification et scopes). Un appel d'envoi devra passer par un appel HTTP direct à POST /v1/conversations/{id}/send ou POST /v1/send en attendant une éventuelle méthode dédiée du SDK.

Gestion des erreurs#

ClasseCas
TrameHttpErrorLa requête a atteint le serveur, réponse HTTP en erreur (status, details = corps JSON)
TrameNetworkErrorÉchec réseau — le serveur n'a pas répondu
TrameRpcErrorErreur JSON-RPC côté canal MCP (code, details)

Toutes héritent de TrameError (message, code, status, method, path, requestId).

Le message d'un TrameHttpError reprend le champ error de la réponse : sur les routes contacts, agenda et tâches, c'est donc un code machine (CONTACT_NOT_FOUND…) et non une phrase — voir Vue d'ensemble.

js
try {
  await trame.conversations.get('inconnu', { mailbox: 'contact@exemple.com' });
} catch (e) {
  if (e instanceof TrameHttpError && e.status === 404) {
    // conversation introuvable
  }
}

Statut : le SDK n'est pas encore publié sur un registre de paquets (nom de package, versionnement, canal de publication à décider) — utilisable aujourd'hui uniquement en copiant sdk/trame.js dans votre projet.