Cinq façons de nous décrire votre API. Un seul modèle en sortie.
Serveur MCP, OpenAPI, GraphQL, connecteur prêt à l'emploi ou saisie manuelle : tout aboutit au même catalogue, et rien n'est exposé sans coche.
# Signaler un évènement : Nodium vérifie et range, sans rien envoyercurl https://nodium.io/api/v1/templates/outbound \ -H "Authorization: Bearer nod_••••••••" \ -H "Content-Type: application/json" \ -d '{ "externalId": "order-2481-shipped", "eventType": "order.shipped", "phone": "+33 6 00 00 00 00", "templateName": "order_shipped", "payload": { "reference": "2481" } }'{ "event": { "externalId": "order-2481-shipped", "eventType": "order.shipped", "status": "scheduled", "skipReason": null, "estimatedCostUsd": null }, "duplicate": false, "caller": "machine", "skipReasons": []}Le parcours d'intégration
Six gestes, de la clé au premier évènement. Aucun ne rend visible ce que personne n'a coché.
Créer une clé d'API
Dans la console : Le compte › Avancé › Clés d'API. La clé n'est montrée qu'une fois, agit au nom de son créateur et porte un rôle plafonné par le sien.
Authorization: Bearer nod_…Brancher votre logiciel
Choisissez l'une des cinq sources et déposez son authentification : elle est chiffrée et ne ressort jamais d'une lecture.
Tester la connexion
Un échec revient avec un diagnostic lisible, pas une erreur. Une adresse qui mène à un réseau privé est refusée.
Décrire le catalogue
Automatique pour un serveur MCP et une description OpenAPI, à la main pour les autres : objets, champs, opérations.
POST /api/v1/connectors/:id/discoverCocher ce qui est permis
La découverte écrit tout à « non ». Votre client confirme ; une écriture naît éteinte et exige l'accord d'un humain.
Signaler vos évènements
Votre logiciel annonce un fait ; Nodium vérifie le contact, son accord, le modèle et le canal, estime le coût et range. Vos webhooks vous tiennent au courant.
POST /api/v1/templates/outbound
Les cinq sources
Ce que chacune demande, et ce qu'elle sait faire seule.
Connecteur prêt à l'emploi
Le domaine de votre boutique Shopify et un jeton.
Serveur MCP
L'adresse de votre point de terminaison MCP.
Description OpenAPI
L'adresse du fichier OpenAPI lui-même, pas celle de la page de documentation.
Schéma GraphQL
L'adresse du point de terminaison, celle qui reçoit les requêtes.
Saisie manuelle
Rien à publier : vos objets se décrivent une ligne par champ.
Pourquoi nous commençons par MCP
- Parce que les descriptions d'outils portent le sens et pas seulement la forme. C'est la faiblesse d'une description OpenAPI : elle dit comment appeler, sans dire ce que l'appel veut dire.
- Parce que le schéma d'entrée d'un outil MCP est déjà du JSON Schema, donc exactement notre format. Il est recopié tel quel : aucune conversion, donc aucune perte.
- Parce que la liste des outils est une découverte vivante. Vous ajoutez un outil, une nouvelle découverte l'ajoute — sans jamais décocher ce que votre client avait confirmé, ni renommer ce qu'il avait renommé.
L'écran de confirmation
La découverte propose, votre client confirme. Tout ce qui est trouvé est écrit à « non » : aucun champ n'est visible, aucune opération n'est appelable tant qu'on ne l'a pas cochée. L'écran arrive pré-coché sur une poignée de champs, écriture éteinte, et l'on peut passer à la suite sans rien toucher.
- Le champ qui sert de référence, et ceux qui identifient un client final.
- Les champs sensibles, jamais proposés exposés, et masqués dans les journaux.
- Les opérations autorisées, et celles qui exigent l'accord d'un humain.
- Une lecture devenue écriture à la découverte suivante est éteinte d'office : personne n'avait accepté celle-là.
Trois familles d'appel
À l'exécution, tout se ramène à ces trois-là.
searchChercher
Retrouver l'objet dont parle la conversation, à partir d'un numéro, d'une adresse électronique ou d'une référence.
readRelire
Lire à nouveau un objet déjà rattaché, pour répondre sur son état actuel et non sur un souvenir.
executeExécuter
Agir chez vous. Allumé opération par opération, avec une clé anti-doublon obligatoire : un appel rejoué n'encaisse jamais deux fois.
Éteint par défaut
Appeler Nodium depuis votre logiciel
Votre système n'a pas de session : il s'annonce avec une clé d'API et signale un évènement — une commande expédiée, une échéance qui approche. Nodium vérifie le contact, son consentement, l'existence d'un modèle approuvé, le canal, puis estime le coût. Cet appel n'envoie rien : il décide.
- Deux fois le même évènement ne part qu'une fois : l'appel est idempotent sur l'identifiant que vous fournissez, et rejoue la décision d'origine.
- Une clé présentée et mauvaise est refusée sur-le-champ. Jamais de repli discret sur une session : une clé expirée doit se voir tout de suite.
- Un refus dit tout ce qui manquait, pas seulement la première raison.
- Le coût est estimé avant l'envoi. Un tarif inconnu se dit « inconnu », jamais « gratuit ».
# HTTP 200 : l'évènement est rangé, rien n'est envoyé{ "event": { "externalId": "order-2482-shipped", "status": "skipped", "skipReason": "no_consent" }, "duplicate": false, "caller": "machine", "skipReasons": ["no_consent", "template_not_approved"]}Être prévenu : les webhooks
Un abonnement, créé dans la console ou par l'API, reçoit en POST les évènements qu'il a choisis. Chaque livraison est signée ; répondez par un code 2xx.
Les évènements
- message.received
- message.sent
- approval.requested
- approval.decided
- mission.closed
- dossier.changed
- timer.fired
Sans réponse 2xx, la livraison est reprise : six essais au plus, après 1 min, 5 min, 30 min, 2 h puis 12 h.
Le secret de signature n'est rendu qu'une fois, à la création de l'abonnement. La signature porte l'heure d'envoi et un HMAC-SHA256 de l'heure et du corps.
import { createHmac, timingSafeEqual } from 'node:crypto'// Refuser toute livraison dont la signature ne correspond pasexport function isFromNodium(header, rawBody, secret) { const sig = Object.fromEntries(header.split(',').map(p => p.split('='))) const expected = createHmac('sha256', secret) .update(`${sig.t}.${rawBody}`) .digest('hex') return sig.v1?.length === expected.length && timingSafeEqual(Buffer.from(sig.v1), Buffer.from(expected))}Référence rapide
Ce qui vaut pour chaque appel, dans les deux sens.
Appeler l'API de Nodium
- Adresse
https://nodium.io/api/v1/…Une route qui change de forme passera sous v2 sans casser v1.- Authentification
Authorization: Bearer nod_…Une clé agit au nom de son créateur, avec un rôle plafonné par le sien ; tout est journalisé en son nom.- Cloisonnement
- La clé désigne son espace. Une ressource d'un autre espace répond 404, jamais 403.
- Débit
- 600 appels par minute et par clé ; au-delà, 429 avec le délai à attendre.
- Idempotence
- Un évènement se rejoue sur son externalId, un envoi de message sur son idempotencyKey : la même clé rend le même résultat.
- Erreurs
- Du JSON avec statusCode et statusMessage : un message en français affichable tel quel, et un code quand un programme doit réagir autrement.
- Pagination
- Par curseur, jamais par numéro de page : une file bouge sous les doigts.
Quand Nodium appelle votre API
Cinq façons de s'authentifier, celles que les API emploient réellement : aucune authentification, un jeton présenté en « Authorization: Bearer », une clé dans un en-tête que vous nommez, un couple identifiant et mot de passe, ou un jeton OAuth 2 collé à la main.
Ce que nous faisons de vos secrets
- Le secret d'authentification est chiffré et ne ressort jamais. Une lecture dit seulement s'il y en a un.
- Une clé posée dans un champ qui n'est pas prévu pour elle est refusée, avec l'indication de l'endroit où la mettre.
- Rien ne franchit la cloison d'un espace. Un identifiant qui appartient à quelqu'un d'autre répond « introuvable », jamais « interdit ».
- Une adresse qui pointe vers un réseau privé est refusée au moment du test de connexion.
- Les champs marqués sensibles sont masqués dans les journaux d'appel.
Ce que nous ne savons pas encore faire
La liste est courte et tenue à jour. Une limite écrite coûte moins cher qu'une limite découverte.
- La découverte automatique n'existe que pour les serveurs MCP et les descriptions OpenAPI. Un schéma GraphQL se teste, mais son catalogue se décrit à la main.
- Le transport MCP ancien, à deux adresses, n'est pas géré.
- Aucun renouvellement de jeton OAuth 2.
- Chaque appel MCP rouvre une poignée de main : un peu plus lent, mais rien à réparer quand votre serveur redémarre.
- Une donnée sensible logée dans un champ que personne n'a marqué comme tel est journalisée en clair. La découverte propose le marquage, votre client le complète.
Branchez votre API
Enregistrer une source, la tester, puis découvrir son catalogue — trois gestes, depuis un écran.