Vous développez une application interne, un CRM ou un flux Power Automate qui envoie des courriels par Microsoft Graph ? L'API ATOM Signatures vous donne le HTML de la signature d'un employé, tel qu'Outlook l'insérerait, pour que vos courriels automatiques portent la même signature que ceux écrits à la main. Cette page décrit l'activation, l'authentification, les routes, les erreurs et les limites, avec des exemples prêts à copier.
/api/v1 qui ne modifient ni signature, ni coordonnées, ni assignation — quatre pour les signatures (whoami, signatures, signature, signature/send) et trois pour les résultats des sondages de satisfaction (feedback/*) —, une authentification par clé d'API, un format d'erreur unique, et des limites de débit claires. L'API est désactivée par défaut : un administrateur de votre organisation l'active dans Réglages. La spécification OpenAPI est publique : /api/openapi.json.
Comment activer l'API ?
L'API est désactivée par défaut. Un administrateur de votre organisation l'active dans la console, sous Réglages → « API pour développeurs ». Tant qu'elle est désactivée, toute requête authentifiée reçoit une erreur 403 API_DISABLED.
La même carte permet de créer et de révoquer les clés d'API (réservé aux administrateurs).
L'API est destinée aux appels de serveur à serveur : elle n'est pas appelable depuis un navigateur, et une requête portant un en-tête Origin d'un autre site est refusée (403). Elle ne modifie ni signature, ni coordonnées, ni assignation ; seuls le siège de l'utilisateur et le compteur d'envois sont mis à jour (voir Sièges et facturation).
Authentification par clé d'API
Chaque requête porte un en-tête Authorization: Bearer atom_live_… avec une clé d'API. C'est le seul mode d'authentification : tout autre identifiant est refusé.
- Créez-la dans Réglages → « API pour développeurs » → Nouvelle clé, en lui donnant un nom (par exemple « Intégration CRM »).
- Elle n'est montrée qu'une seule fois, à la création. Copiez-la dans un coffre de secrets : ATOM n'en conserve qu'une empreinte et ne peut pas la retrouver.
- Une organisation peut avoir 10 clés actives au plus. Chaque clé affiche sa date de création et sa dernière utilisation ; la révocation est immédiate.
- Une clé donne accès aux signatures de tous les utilisateurs de votre organisation : ne la placez jamais dans une page web ni dans un dépôt de code.
- Elle est indépendante du complément Outlook : renouveler l'un ne touche pas l'autre.
Les routes de signature
Base : https://signatures.atomsolutions.ca. Toutes les réponses sont en JSON et portent Cache-Control: no-store.
GET /api/v1/whoami
Vérifie les identifiants et renvoie votre organisation, et le nom de la clé utilisée.
Réponse : { "tenant": { "id": "11111111-2222-3333-4444-555555555555", "name": "Cabinet Exemple inc." }, "auth": "key", "keyName": "Intégration CRM", "apiEnabled": true }. tenant.id est l'identifiant de votre organisation Microsoft 365 ; auth vaut toujours key.
GET /api/v1/signatures — les signatures d'un utilisateur
Liste les signatures attribuées à un utilisateur, pour laisser choisir laquelle utiliser. Le paramètre user suit les mêmes règles que pour l'aperçu (obligatoire, une adresse d'un domaine de votre organisation). Les signatures sont dans l'ordre de priorité ; seuls l'identifiant et le nom sont renvoyés, jamais le HTML.
Réponse : { "signatures": [ { "id": 12, "name": "…", "isDefault": true } ], "defaultSignatureId": 12 }. isDefault marque la signature que GET /api/v1/signature renverrait sans signatureId ni destinataires ; si aucune ne convient, defaultSignatureId vaut null. Cet appel ne compte ni siège ni envoi.
L'identifiant d'une signature se trouve aussi dans la console : la liste des signatures affiche une colonne « ID » quand l'API est activée, et un clic sur l'identifiant le copie.
GET /api/v1/signature — aperçu
Renvoie la signature HTML d'un utilisateur, telle qu'Outlook la recevrait. Paramètres :
user: l'adresse de l'utilisateur. Obligatoire, d'un domaine de votre organisation. Une adresse d'un autre domaine donne404 USER_NOT_FOUND.compose:new(par défaut),replyouforward. Une signature peut avoir une version courte ou différente pour les réponses et les transferts.recipients: les domaines des destinataires, séparés par des virgules (50 au plus), pour les signatures dont le contenu dépend du destinataire.signatureId: facultatif, l'identifiant d'une signature précise, pris dansGET /api/v1/signatures. Sans lui, la signature habituelle de l'utilisateur est renvoyée. Elle doit être attribuée à l'utilisateur, sinon404 SIGNATURE_NOT_FOUND; une valeur qui n'est pas un entier positif donne400 INVALID_REQUEST.
L'aperçu renvoie une signature utilisable telle quelle : il occupe le siège de l'utilisateur (voir Sièges et facturation), mais ne compte aucun envoi.
Réponse : { "matched": true, "html": "…", "signatureId": 12, "name": "…", "mode": "full" }. Le champ mode indique la version rendue (full, compact, custom ou none) ; avec none, html est vide et il n'y a rien à ajouter au message.
POST /api/v1/signature/send — signature pour un envoi
Même réponse que l'aperçu, avec un corps JSON { "user", "compose", "recipients", "signatureId" }. Le signatureId est facultatif : un entier ou une chaîne de chiffres, avec les mêmes règles que pour l'aperçu. Un signatureId refusé (404) n'occupe aucun siège. La différence est comptable : en plus du siège de l'utilisateur, cet appel compte l'envoi, exactement comme un courriel envoyé depuis Outlook (voir Sièges et facturation). Appelez-le une fois par courriel réellement envoyé.
Résultats des sondages de satisfaction
Si votre organisation ajoute un sondage de satisfaction à ses signatures, l'API en renvoie les résultats agrégés, par exemple pour les afficher dans un tableau de bord interne.
Elles ne renvoient que des totaux : jamais de commentaire, d'adresse de répondant ni de résultat par employé ou par signature. Un résultat qui porte sur moins de 10 réponses n'est pas détaillé : il ne contient que "insufficient": true, sans effectif ni valeur.
GET /api/v1/feedback/surveys
La liste des sondages de l'organisation : { "surveys": [ { "id": 12, "name": "…", "scale": "csat3", "status": "active", "created_at": "…" } ] }. L'échelle (scale) est csat3 (trois visages, notes 1 à 3), nps (0 à 10) ou stars5 (1 à 5 étoiles) ; le statut est active, paused ou archived.
GET /api/v1/feedback/summary — résultat d'une période
Paramètres :
survey: l'identifiant numérique du sondage. Obligatoire. Un sondage inexistant ou d'une autre organisation donne404 SURVEY_NOT_FOUND.from(inclus) etto(exclu) : facultatifs, au format ISO 8601 : une date (2026-10-01, lue en UTC) ou une date-heure avec fuseau (2026-10-01T00:00:00Zou2026-10-01T00:00:00-04:00). Une date-heure sans fuseau est refusée (400), tout comme une période oùfromne précède pasto.
Réponse : { "survey": 12, "scale": "csat3", "insufficient": false, "count": 48, "value": 0.7916666666666666, "distribution": { "1": 3, "2": 7, "3": 38 } }. Le sens de value dépend de l'échelle : pour csat3, la part des notes « satisfait » (une fraction de 0 à 1, non arrondie) ; pour nps, le score NPS (de -100 à 100, avec promoters, passives et detractors) ; pour stars5, la moyenne des étoiles.
GET /api/v1/feedback/timeseries — évolution dans le temps
Mêmes paramètres, plus interval : day (par défaut) ou week. La réponse contient un tableau series, avec un résultat par jour ou par semaine ayant reçu des réponses (bucket = premier jour de l'intervalle, le lundi pour une semaine, heure de l'Est). Chaque intervalle suit la même règle des 10 réponses.
# Liste des sondages
curl -s -H "Authorization: Bearer $ATOM_API_KEY" \
https://signatures.atomsolutions.ca/api/v1/feedback/surveys
# Résultat du sondage 12 depuis le 1er octobre, puis semaine par semaine
curl -s -H "Authorization: Bearer $ATOM_API_KEY" \
"https://signatures.atomsolutions.ca/api/v1/feedback/summary?survey=12&from=2026-10-01"
curl -s -H "Authorization: Bearer $ATOM_API_KEY" \
"https://signatures.atomsolutions.ca/api/v1/feedback/timeseries?survey=12&interval=week"Ces routes ne comptent ni siège ni envoi.
Exemples
Avec une clé d'API en variable d'environnement :
# Vérifier la clé
curl -s -H "Authorization: Bearer $ATOM_API_KEY" \
https://signatures.atomsolutions.ca/api/v1/whoami
# Aperçu de la signature d'un utilisateur
curl -s -H "Authorization: Bearer $ATOM_API_KEY" \
"https://signatures.atomsolutions.ca/api/v1/signature?user=marie.tremblay@exemple.ca"
# Signature pour un envoi réel
curl -s -X POST -H "Authorization: Bearer $ATOM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"user":"marie.tremblay@exemple.ca","compose":"new"}' \
https://signatures.atomsolutions.ca/api/v1/signature/sendPour choisir une signature précise, listez d'abord celles de l'utilisateur, puis passez l'identifiant retenu en signatureId :
# Les signatures proposées à l'utilisateur
curl -s -H "Authorization: Bearer $ATOM_API_KEY" \
"https://signatures.atomsolutions.ca/api/v1/signatures?user=marie.tremblay@exemple.ca"
# Aperçu de la signature 12, puis signature 12 pour un envoi réel
curl -s -H "Authorization: Bearer $ATOM_API_KEY" \
"https://signatures.atomsolutions.ca/api/v1/signature?user=marie.tremblay@exemple.ca&signatureId=12"
curl -s -X POST -H "Authorization: Bearer $ATOM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"user":"marie.tremblay@exemple.ca","signatureId":12}' \
https://signatures.atomsolutions.ca/api/v1/signature/sendLe cas typique : ajouter la signature à un courriel envoyé par Microsoft Graph. En Node.js (version 18 ou plus) :
const res = await fetch('https://signatures.atomsolutions.ca/api/v1/signature/send', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.ATOM_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ user: 'marie.tremblay@exemple.ca', compose: 'new' }),
});
if (!res.ok) throw new Error((await res.json()).error.code);
const { html: signature } = await res.json();
// Corps du courriel Graph (POST /users/{upn}/sendMail)
const body = { contentType: 'HTML', content: `<p>Bonjour,</p>${signature}` };La spécification OpenAPI décrit chaque route et peut être importée dans un outil comme Postman ou dans un générateur de client.
Codes d'erreur
Toute erreur a la même forme : { "error": { "code": "…", "message": "…" } }, à une exception près : le refus d'un en-tête Origin d'un autre site (voir le tableau).
| HTTP | Code | Signification |
|---|---|---|
| 401 | INVALID_CREDENTIALS | En-tête absent, clé inconnue ou révoquée, identifiant qui n'est pas une clé d'API, ou organisation inactive. La réponse est la même pour toutes ces causes. |
| 403 | API_DISABLED | Identifiants valides, mais l'API n'est pas activée dans Réglages. |
| 403 | — | Requête portant un en-tête Origin d'un autre site (appel depuis un navigateur). Le corps de cette réponse n'est pas au format d'erreur ci-dessus. |
| 400 | INVALID_REQUEST | user manquant, compose ou recipients invalide, signatureId qui n'est pas un entier positif, JSON illisible ; pour feedback/* : survey manquant, date ou interval invalide. |
| 413 | INVALID_REQUEST | Corps de la requête trop volumineux (plus de 500 ko). Un corps qui ne peut pas être lu autrement (encodage non pris en charge, par exemple) donne aussi INVALID_REQUEST, avec le statut 4xx correspondant. |
| 404 | USER_NOT_FOUND | Utilisateur introuvable ou sans signature assignée. La réponse est identique pour un utilisateur d'une autre organisation. |
| 404 | SIGNATURE_NOT_FOUND | signatureId qui n'est pas attribué à cet utilisateur. La réponse est la même pour un identifiant inexistant et pour celui d'une autre organisation. |
| 404 | NOT_FOUND | Route inconnue sous /api/v1. |
| 404 | SURVEY_NOT_FOUND | Sondage introuvable. La réponse est identique pour un sondage d'une autre organisation. |
| 402 | BILLING_INACTIVE | L'abonnement de l'organisation n'est pas actif. |
| 409 | SEAT_LIMIT | La limite de sièges est atteinte pour cet utilisateur. |
| 429 | RATE_LIMITED | Trop de requêtes ; l'en-tête Retry-After donne le délai en secondes. |
| 500 | INTERNAL_ERROR | Erreur côté serveur. |
Quelles sont les limites de débit ?
Sur une fenêtre d'une minute :
- 120 requêtes par clé d'API ;
- 600 requêtes par organisation, toutes clés confondues ;
- 300 requêtes par adresse IP, avant l'authentification.
Au-delà, l'API répond 429 RATE_LIMITED avec un en-tête Retry-After. Une signature change rarement : mettez l'aperçu en cache de votre côté et réservez signature/send aux courriels réellement envoyés.
Sièges et facturation
Le modèle est celui du complément Outlook : un utilisateur distinct qui envoie des courriels signés occupe un siège.
- La liste (
GET /api/v1/signatures) ne compte rien : elle ne renvoie que des identifiants et des noms, jamais le HTML. - L'aperçu (
GET /api/v1/signature) occupe le siège de l'utilisateur, sans compter d'envoi. - L'envoi (
POST /api/v1/signature/send) occupe le siège de l'utilisateur et compte l'envoi, comme un courriel parti d'Outlook. - Un utilisateur déjà compté n'occupe pas un second siège. Si la limite de sièges de l'abonnement est atteinte pour un utilisateur qui ne l'est pas encore, l'aperçu comme l'envoi répondent
409 SEAT_LIMIT. - Si l'abonnement de l'organisation n'est pas actif, la réponse est
402 BILLING_INACTIVE.
Pour le prix et la gestion des sièges, voir les tarifs.
Questions fréquentes
L'API est-elle activée par défaut ?
Non. Un administrateur de l'organisation l'active dans Réglages → « API pour développeurs ». Tant qu'elle est désactivée, toute requête authentifiée reçoit l'erreur API_DISABLED.
Qui peut créer une clé d'API ?
Seuls les administrateurs de l'organisation, dans Réglages. Une organisation peut avoir 10 clés actives au plus. La clé n'est montrée qu'une fois, à sa création ; elle se révoque à tout moment.
Comment l'API authentifie-t-elle les appels ?
Par une clé d'API, créée par un administrateur dans Réglages et transmise dans l'en-tête Authorization: Bearer. C'est le seul mode : la clé convient à un script, à un CRM ou à un flux automatisé, et se révoque à tout moment.
L'API peut-elle modifier une signature ?
Non. Elle ne modifie aucune signature, coordonnée ni assignation, ni rien dans votre annuaire : elle renvoie la signature d'un utilisateur. Seuls le siège de l'utilisateur et le compteur d'envois sont mis à jour.
L'API compte-t-elle un siège ?
Oui. Toute signature renvoyée occupe le siège de l'utilisateur, aperçu (GET /signature) compris : un utilisateur déjà compté n'en occupe pas un second. Seul l'appel d'envoi (signature/send) compte en plus l'envoi, comme un courriel envoyé depuis Outlook. La liste des signatures ne compte rien.
Comment choisir quelle signature est renvoyée ?
Appelez GET /api/v1/signatures?user=… pour lister les signatures attribuées à l'utilisateur, puis passez l'identifiant retenu en signatureId à GET /api/v1/signature ou à POST /api/v1/signature/send. Sans signatureId, l'API renvoie la signature habituelle de l'utilisateur. L'identifiant se copie aussi dans la colonne ID de la liste des signatures de la console, quand l'API est activée.
L'API donne-t-elle accès aux réponses des sondages de satisfaction ?
Seulement à des résultats agrégés : nombre de réponses, score et répartition des notes, pour une période ou jour par jour. Jamais de commentaire, d'adresse de répondant ni de résultat par employé, et un résultat de moins de 10 réponses n'est pas détaillé.
Où trouver la spécification OpenAPI ?
À l'adresse https://signatures.atomsolutions.ca/api/openapi.json. Elle décrit chaque route (signatures et sondages de satisfaction), les schémas d'erreur et l'authentification par clé d'API (Bearer).
Des signatures cohérentes, même pour les courriels automatiques. Activez l'API dans Réglages, créez une clé et récupérez la signature de vos employés en quelques lignes.
Pour approfondir : la signature dynamique avec Microsoft Graph et confiance et sécurité.