Blastack

Développeurs

L'API, et les trois outils qui s'y branchent

Dix-sept opérations sur dix chemins, cinq événements sortants et une spécification OpenAPI 3.1 publique que Make et n8n importent tout seuls. Tout est ici : chaque paramètre un par un, des exemples qui fonctionnent tels quels, et la liste de ce que l'API ne fait pas.

Collez la première adresse dans l'importateur de n8n ou de Make et les nœuds apparaissent seuls. Zapier ne lit pas OpenAPI : c'est précisément pour cela que ses étapes sont écrites à part, plus bas.

En un coup d'œil

Ce qu'il faut pour le premier appel

Huit informations. Avec elles, la requête s'écrit sans lire plus loin.

QuoiValeurRemarque
Racine de l'APIhttps://app.blastack.com/api/v1Elle vit dans l'application, pas sur ce site commercial. Une seule adresse, et elle ne change pas.
Spécificationhttps://app.blastack.com/api/openapi.jsonPublique et sans clé, pour qu'un importateur puisse la lire avant même d'avoir des identifiants.
AuthentificationAuthorization: Bearer blsk_<prefix>_<secret>Dans l'en-tête, jamais dans l'adresse. Les adresses finissent dans le journal du serveur, dans celui du proxy devant lui et dans l'historique de qui l'a essayée à la main.
Formatapplication/json; charset=utf-8Du JSON à l'aller comme au retour. Ni XML ni formulaire.
Limite120 req/min · RateLimit-RemainingPar clé et par minute. Chaque réponse indique combien il en reste et quand le compteur repart.
Paginationpage=1 · per_page=50 · ≤ 200La première page est la 1, pas la 0. Demander plus de deux cents est ramené à deux cents au lieu d'être refusé.
Erreurs{ error: { status, code, message } }Toujours le même objet, avec un code stable pensé pour écrire une condition dessus.
Environnement de test—Il n'y en a pas. On travaille contre la production, d'où l'intérêt de commencer avec une clé en lecture seule.
curl https://app.blastack.com/api/v1/people?per_page=1 \
  -H "Authorization: Bearer blsk_a1b2c3d4e5f6_YOUR_SECRET"

Ce qui existe

Trois surfaces, aucune à moitié faite

Les trois fonctionnent. Ce qui manque est plus bas, dans sa propre section et nommé à voix haute.

Provisioning SCIM 2.0

Pour que votre SIRH crée les personnes, les change de service et les désactive sans que personne ne le recopie à la main. C'est la moitié qui compte vraiment pour un service informatique : le jour où vous vous séparez de quelqu'un, le compte se désactive tout seul.

Filtres sur userName et externalId, pagination et modification partielle. Le service et l'adresse de travail sont lus, donc qui entre par là naît avec son service et son site déjà renseignés. La sortie désactive, elle ne supprime pas.

Authentification unique (OpenID Connect)

Entrer avec le compte de l'entreprise depuis Entra ID, Google Workspace ou Okta. Cela cohabite avec le code d'accès, par lequel entre la partie de l'effectif sans messagerie professionnelle.

On la configure en collant l'adresse de découverte du fournisseur, et elle est vérifiée auprès de lui avant d'être enregistrée. Les domaines de messagerie sont vérifiés par DNS. Il n'y a ni SAML ni LDAP.

API Blastack

Publier depuis le programme qui sait déjà que la ligne 3 s'arrête jeudi, désactiver qui sort du SIRH, et être appelé par nous quand quelque chose arrive au lieu de devoir demander toutes les cinq minutes.

Du JSON sur HTTPS, une clé d'API en en-tête, des portées par clé, des erreurs à code stable et des événements sortants signés. C'est ce que documente le reste de cette page.

Automatisation

Zapier, Make et n8n, étape par étape

Les trois ne se montent pas de la même façon, et le dire épargne l'après-midi qu'on perd à le découvrir. Make et n8n lisent la spécification et se configurent presque seuls ; Zapier ne la lit pas, donc là-bas chaque appel s'écrit à la main. Les trois marchent ; le travail n'est pas le même.

OutilLit-il la spécification ?Déclencheur conseillé
n8nOui, en entierNœud « Webhook » + POST /webhooks
MakeOui, dans l'éditeur d'applications propres« Custom webhook » + POST /webhooks
ZapierNon« Catch Hook » + POST /webhooks

n8n

Le chemin le plus court des trois. On crée un identifiant d'en-tête, on colle l'adresse de la spécification dans l'importateur, et il reste un nœud par opération avec ses paramètres déjà en place.

Étapes

  1. 01Identifiants → nouveau → « Header Auth ». Le nom de l'en-tête est Authorization et la valeur est Bearer suivi d'une espace et de votre clé.
  2. 02Nœud « HTTP Request », authentification « Generic Credential Type » → « Header Auth », puis l'identifiant créé juste avant. Méthode et chemin sortent du tableau des points d'entrée.
  3. 03Pour ne pas saisir les paramètres à la main, donnez à l'importateur l'adresse de la spécification : elle décrit chaque point d'entrée avec ses valeurs admises, donc ce qui est généré arrive avec des listes déroulantes au lieu de champs libres.
  4. 04Pour déclencher : nœud « Webhook », copiez son adresse de production et enregistrez-la avec POST /webhooks en choisissant les événements. Interroger toutes les cinq minutes cesse d'être nécessaire.

À savoir

Le nœud de webhook répond 200 avant d'exécuter la suite du flux, ce qui est exactement ce qu'il faut ici : nous abandonnons au bout de dix secondes et cela compte comme un échec.

Make

Le module HTTP générique suffit à tout, et qui va monter beaucoup de scénarios peut charger la spécification dans l'éditeur d'applications propres et obtenir un module par opération.

Étapes

  1. 01Module « HTTP » → « Make an API Key Auth request ». Dans la connexion, la clé s'appelle Authorization, la valeur est Bearer plus votre clé, et elle va dans l'en-tête.
  2. 02Méthode, chemin et corps sortent du tableau des points d'entrée et des exemples plus bas. Le type de contenu est application/json.
  3. 03Si vous montez plusieurs scénarios, l'éditeur d'applications propres accepte la spécification et génère un module par opération : moins de scénarios écrits à la main et moins de fautes de frappe dans les noms de filtres.
  4. 04Pour déclencher : module « Webhooks » → « Custom webhook », copiez son adresse et enregistrez-la avec POST /webhooks. Make répond aussitôt et traite ensuite, ce qui est le bon ordre ici.

À savoir

Make facture à l'opération : un scénario qui interroge toutes les cinq minutes brûle huit mille opérations par mois pour ne presque rien trouver. Avec le webhook, on en dépense une par événement.

Zapier

Zapier n'importe pas OpenAPI. On le monte avec les étapes génériques de webhooks, ou en construisant une intégration privée sur leur plateforme de développement, où chaque point d'entrée se déclare à la main.

Étapes

  1. 01Déclencheur : « Webhooks by Zapier » → « Catch Hook ». Copiez l'adresse donnée et enregistrez-la avec POST /webhooks en choisissant les événements.
  2. 02Action : « Webhooks by Zapier » → « Custom Request ». Méthode et adresse du tableau, en-têtes Authorization avec Bearer plus votre clé et Content-Type avec application/json, et le JSON dans le champ de données.
  3. 03Ajoutez une étape « Code by Zapier » qui vérifie la signature avant toute chose. Zapier ne la vérifie pas pour vous et l'adresse du déclencheur est publique : sans cette étape, quiconque la découvre peut inventer un arrêt de ligne.
  4. 04Si vous préférez des nœuds nommés à des requêtes génériques, il faut construire une intégration privée et y déclarer chaque point d'entrée avec ses champs. C'est plus de travail, et la spécification n'en épargne rien.

À savoir

Leurs déclencheurs par interrogation dépensent une tâche à chaque passage, qu'ils trouvent quelque chose ou non. Le « Catch Hook » ne dépense que quand il s'est vraiment passé quelque chose.

Clés

Une clé par intégration, avec le strict nécessaire

Aujourd'hui nous les émettons à la main et nous vous disons quelles portées elles portent. Il n'y a pas d'écran en libre-service et c'est dit plus bas, parmi ce qui manque. Chaque clé est liée à une entreprise, et aucune route ne lit un identifiant d'entreprise dans la requête : il n'y a nulle part où se tromper.

  1. 01

    Demandez-nous la clé

    Dites-nous à quoi elle sert et ce qu'elle doit pouvoir faire, et nous l'émettons avec ces portées et aucune autre. Elle est montrée une seule fois : nous n'en gardons qu'une empreinte, donc une clé perdue se révoque et se réémet.

  2. 02

    Envoyez-la à chaque requête

    Dans l'en-tête d'autorisation, jamais dans l'adresse. Les adresses finissent dans le journal du serveur, dans celui du proxy devant lui et dans l'historique de qui l'a essayée à la main.

  3. 03

    Rangez-la où vous rangez les autres

    Dans votre gestionnaire de secrets, pas dans le dépôt. Elle commence par un préfixe reconnaissable précisément pour que les détecteurs de secrets l'attrapent si elle s'échappe.

L'API relève du module d'identité d'entreprise, celui qui ouvre aussi l'authentification unique et le provisioning. Si l'entreprise ne l'a pas souscrit, la réponse le dit avec ces mots-là et non par une erreur générique.

Les portées, une par une

PortéeCe qu'elle ouvre
people:readLire l'effectif et les services et sites auxquels une publication peut être adressée. C'est tout ce dont un tableau de bord a besoin.
people:writeCréer, modifier et désactiver des personnes. Désactiver ferme leurs sessions : cela ne vient donc pas en cadeau avec la lecture.
announcements:readLire ce qui a été publié et qui a confirmé une lecture obligatoire. C'est séparé de la portée des personnes : une liste de noms et de postes, c'est l'annuaire, et le texte des publications ne l'est pas.
announcements:writePublier sur le panneau d'affichage. La file de relecture de l'entreprise est respectée : une clé ne saute le circuit d'approbation de personne.
metrics:readLes indicateurs agrégés. Personne n'y apparaît nommément.
webhooks:readVoir les adresses enregistrées et le journal des livraisons. C'est ce qui répond à « pourquoi rien n'arrive » sans ouvrir de ticket.
webhooks:writeEnregistrer, modifier et supprimer des adresses d'événement sortant. La plus délicate de la liste : elle décide à quel serveur d'internet nous envoyons le contenu de vos publications.

Points d'entrée

Dix-sept opérations sur dix chemins

Groupées par famille. La colonne de la portée est celle à regarder au moment de demander la clé : si elle manque, la réponse dit laquelle il fallait et lesquelles la vôtre porte.

MéthodeCheminPortéeCe que cela fait
GET/peoplepeople:readL'effectif, avec son service, son site et l'identifiant que chaque personne porte dans votre SIRH. Dix-sept paramètres, dont le filtre sur la date de dernière modification, qui est celui qui permet de synchroniser tous les quarts d'heure sans tout retélécharger.
GET/people/{id}people:readUne personne précise, cherchée par notre identifiant ou par le vôtre. De quoi rafraîchir une fiche sans parcourir toute la liste.
POST/peoplepeople:writeCrée quelqu'un. C'est pour quand votre SIRH ne parle pas SCIM ; s'il le parle, préférez SCIM, qui gère aussi les sorties. Le service et le site se donnent par leur nom et sont créés s'ils n'existent pas.
PATCH/people/{id}people:writeNe change que les champs envoyés. Un champ omis n'est pas touché : une synchronisation qui ne connaît que le poste ne peut effacer le site de personne.
DELETE/people/{id}people:writeDésactive ; ne supprime jamais. Les sessions sont fermées sur-le-champ, donc qui part un vendredi est dehors ce vendredi. Ce qu'il a publié reste.
GET/audiencespeople:readLes services et les sites qui existent, avec combien de personnes dans chacun. C'est de là que sortent les noms auxquels une publication peut être adressée, et le filtre des groupes vides est celui qui trouve un mappage de provisioning cassé.
GET/announcementsannouncements:readTout ce qui a été publié, avec les lectures et les confirmations de chaque élément. Les brouillons et les refusés sont inclus pour qu'un tableau de bord puisse dessiner l'entonnoir entier.
GET/announcements/{id}announcements:readUne publication précise. C'est l'étape suivante de l'identifiant renvoyé par une publication ou apporté par un événement sortant.
POST/announcementsannouncements:writePublie sur le panneau d'affichage. Il faut dire qui signe et il n'y a pas de valeur par défaut. Si cette personne ne peut pas publier sans relecture, la publication entre dans la file et la réponse le dit.
GET/announcements/{id}/acknowledgementsannouncements:readQui a confirmé une lecture obligatoire et qui ne l'a pas fait, avec nom et heure. C'est la seule liste nominative de toute l'API, et elle l'est parce que c'est justement l'objet de la lecture obligatoire : un acte volontaire, signé et daté que l'on peut montrer à une inspection.
GET/metricsmetrics:readL'effectif du jour, les arrivées, les publications et la portée par publication et par service. Les mêmes chiffres que l'écran d'analyse, calculés par le même code.
GET/webhookswebhooks:readVos adresses enregistrées, chacune avec sa santé : échecs consécutifs, ce que votre serveur a répondu la dernière fois et, si nous l'avons mise en pause, pourquoi.
POST/webhookswebhooks:writeEnregistre une adresse et les événements qu'elle veut. La réponse apporte le secret de signature, et c'est la seule fois où il se voit.
GET/webhooks/{id}webhooks:readUne adresse précise, avec sa santé.
PATCH/webhooks/{id}webhooks:writeChange ce que vous envoyez. Remettre l'adresse en actif lève aussi la pause appliquée après des échecs répétés et remet le compteur à zéro.
DELETE/webhooks/{id}webhooks:writeLa supprime avec son historique. Pour cesser de recevoir un moment sans perdre l'historique, il vaut mieux la désactiver.
GET/webhooks/{id}/deliverieswebhooks:readTout ce que nous avons tenté de vous envoyer : tentatives, ce que vous avez répondu et quand a lieu la suivante. L'identifiant est le même que celui parti dans l'en-tête : il se recoupe avec vos propres journaux.

Paramètres

Tous, point d'entrée par point d'entrée

Aucune liste n'est abrégée : ce sont celles que le serveur vérifie. Un paramètre absent d'ici n'existe pas, et l'écrire renvoie une erreur qui nomme ceux que ce point d'entrée accepte au lieu de l'ignorer en silence.

La colonne de droite est en anglais à dessein. Elle vient du catalogue dont la spécification est également générée : c'est donc mot pour mot ce que n8n et Make affichent dans leurs nœuds. La traduire ici reviendrait à avoir deux versions qui, un jour, diraient des choses différentes.

GET /people

people:read

L'effectif, avec son service, son site et l'identifiant que chaque personne porte dans votre SIRH. Dix-sept paramètres, dont le filtre sur la date de dernière modification, qui est celui qui permet de synchroniser tous les quarts d'heure sans tout retélécharger.

Dans la requête

ParamètreTypeValeurs admisesPar défautExempleCe que cela fait
pageentiermin. 112Page to return. The first page is 1, not 0.
per_pageentiermin. 1 · max. 200 · hors bornes, la valeur est ramenée au lieu d'échouer50100How many items per page. Anything above 200 is clamped to 200 rather than rejected: asking for more is a reasonable thing to want.
sorttextecreated_at · updated_at · name · emailcreated_atField to sort by. Defaults to created_at.
ordertexteasc · descascSort direction.
fieldstexte · plusieurs, séparés par des virgulesexternal_id · email · name · job_title · department · center · role · status · language · created_at · updated_atexternal_id,department,statusComma-separated list of fields to return. `id` is always included. Use it to avoid pulling personal data you do not need.
statustexte · plusieurs, séparés par des virgulesactive · invited · disabledactiveOnly people in these states. Several may be given.
roletexte · plusieurs, séparés par des virgulesowner · admin · gestor_personas · responsable_local · informatico · editor · revisor · analista · employeeOnly people with these roles. Several may be given.
departmenttexte · plusieurs, séparés par des virgulesMaintenance,QualityDepartment name, or several separated by commas. Case-insensitive: your directory writing MANTENIMIENTO is not an error.
centertexte · plusieurs, séparés par des virgulesSite name, or several separated by commas. Case-insensitive.
no_departmentbooléenOnly people with no department. These are the ones who never see a targeted announcement, so this is the filter that finds a broken provisioning mapping.
languagetexte · plusieurs, séparés par des virguleses · ca · en · pt · fr · it · de · sv · nl · pl · ro · csOnly people who picked this reading language.
emailtexteExact email address, case-insensitive.
external_idtexteExact external_id, as sent by your HR system over SCIM.
qtextegarciaFree text over name, email and job title. Case-insensitive, matches anywhere in the value.
updated_sincedate ISO 86012026-08-01T00:00:00ZOnly people changed at or after this instant. This is the one that lets you sync every fifteen minutes without pulling two thousand rows every time.
created_sincedate ISO 8601Only people added at or after this instant.
created_untildate ISO 8601Only people added before this instant.

GET /people/{id}

people:read

Une personne précise, cherchée par notre identifiant ou par le vôtre. De quoi rafraîchir une fiche sans parcourir toute la liste.

Dans le chemin

ParamètreTypeValeurs admisesPar défautExempleCe que cela fait
idObligatoiretextea3f1…Blastack id (a uuid) or the person's external_id from your HR system. A Blastack id is always a uuid and yours almost never is, so they cannot be confused; if one ever were, ours wins.

Dans la requête

ParamètreTypeValeurs admisesPar défautExempleCe que cela fait
fieldstexte · plusieurs, séparés par des virgulesexternal_id · email · name · job_title · department · center · role · status · language · created_at · updated_atexternal_id,department,statusComma-separated list of fields to return. `id` is always included. Use it to avoid pulling personal data you do not need.

POST /people

people:write

Crée quelqu'un. C'est pour quand votre SIRH ne parle pas SCIM ; s'il le parle, préférez SCIM, qui gère aussi les sorties. Le service et le site se donnent par leur nom et sont créés s'ils n'existent pas.

Dans le corps

ParamètreTypeValeurs admisesPar défautExempleCe que cela fait
nameObligatoiretextelongueur max. 120Ana GarcíaFull name, as it should appear on the wall.
emailtextelongueur max. 200Work email. Optional: most of the workforce this product is for has none, and they get in with an invite code instead. Unique within the company.
external_idtextelongueur max. 200EMP-0042The id this person has in your system. Store it and you can cross both lists later without matching names.
job_titletextelongueur max. 120Job title.
departmenttextelongueur max. 80Department name. Created if it does not exist. Without one, this person only ever sees company-wide announcements.
centertextelongueur max. 80Site name. Created if it does not exist.
roletexteadmin · gestor_personas · responsable_local · informatico · editor · revisor · analista · employeeemployeeWhat they can do. `owner` cannot be given from the API: a key pasted in a cron job must not be able to mint an account that can cancel the subscription.
statustexteactive · invited · disabledactive`active` can sign in; `invited` is created but not counted as signed up yet; `disabled` is created already deactivated, which is what a backfill of former staff needs.
languagetextees · ca · en · pt · fr · it · de · sv · nl · pl · ro · csReading language. Leave it out and they read in the company's, which is what you want unless you actually know.

PATCH /people/{id}

people:write

Ne change que les champs envoyés. Un champ omis n'est pas touché : une synchronisation qui ne connaît que le poste ne peut effacer le site de personne.

Dans le chemin

ParamètreTypeValeurs admisesPar défautExempleCe que cela fait
idObligatoiretextea3f1…Blastack id (a uuid) or the person's external_id from your HR system. A Blastack id is always a uuid and yours almost never is, so they cannot be confused; if one ever were, ours wins.

Dans le corps

ParamètreTypeValeurs admisesPar défautExempleCe que cela fait
nametextelongueur max. 120Full name.
emailtextelongueur max. 200Work email.
external_idtextelongueur max. 200The id this person has in your system.
job_titletextelongueur max. 120Job title.
departmenttextelongueur max. 80Department name. Created if it does not exist.
centertextelongueur max. 80Site name. Created if it does not exist.
roletexteadmin · gestor_personas · responsable_local · informatico · editor · revisor · analista · employeeWhat they can do. `owner` cannot be given from the API.
statustexteactive · invited · disabledTheir state. `disabled` also closes their sessions.
languagetextees · ca · en · pt · fr · it · de · sv · nl · pl · ro · csReading language.

DELETE /people/{id}

people:write

Désactive ; ne supprime jamais. Les sessions sont fermées sur-le-champ, donc qui part un vendredi est dehors ce vendredi. Ce qu'il a publié reste.

Dans le chemin

ParamètreTypeValeurs admisesPar défautExempleCe que cela fait
idObligatoiretextea3f1…Blastack id (a uuid) or the person's external_id from your HR system. A Blastack id is always a uuid and yours almost never is, so they cannot be confused; if one ever were, ours wins.

GET /audiences

people:read

Les services et les sites qui existent, avec combien de personnes dans chacun. C'est de là que sortent les noms auxquels une publication peut être adressée, et le filtre des groupes vides est celui qui trouve un mappage de provisioning cassé.

Dans la requête

ParamètreTypeValeurs admisesPar défautExempleCe que cela fait
typetexteall · departments · centersallReturn only departments, only sites, or both.
qtexteFree text over the name. Case-insensitive.
with_peoplebooléenOnly groups that have at least one active person. A department with nobody in it is almost always an old name left behind, and it is the usual cause of an announcement that reaches no one.
sorttextename · peoplenameField to sort by. Defaults to name.
ordertexteasc · descascSort direction.

GET /announcements

announcements:read

Tout ce qui a été publié, avec les lectures et les confirmations de chaque élément. Les brouillons et les refusés sont inclus pour qu'un tableau de bord puisse dessiner l'entonnoir entier.

Dans la requête

ParamètreTypeValeurs admisesPar défautExempleCe que cela fait
pageentiermin. 112Page to return. The first page is 1, not 0.
per_pageentiermin. 1 · max. 200 · hors bornes, la valeur est ramenée au lieu d'échouer50100How many items per page. Anything above 200 is clamped to 200 rather than rejected: asking for more is a reasonable thing to want.
sorttextepublished_at · created_at · updated_at · titlepublished_atField to sort by. Defaults to published_at.
ordertexteasc · descascSort direction.
fieldstexte · plusieurs, séparés par des virgulestitle · body · status · kind · language · audience · community · section · author · notify · comments_enabled · pinned · acknowledgements · reads · published_at · created_at · updated_at · urlexternal_id,department,statusComma-separated list of fields to return. `id` is always included. Use it to avoid pulling personal data you do not need.
statustexte · plusieurs, séparés par des virgulesdraft · pending_review · published · rejected · scheduled · archivedpublished,scheduledOnly these states. Several may be given. `scheduled` means it is written and waiting for its hour.
authortexteWho signs it: our id, their email or their external_id. Any of the three.
audience_typetexteall · departments · centersOnly announcements aimed this way.
departmenttexte · plusieurs, séparés par des virgulesOnly announcements aimed at these departments, by name. Several may be given.
centertexte · plusieurs, séparés par des virgulesOnly announcements aimed at these sites, by name.
communitytexteOnly announcements in this community, by id or by name.
requires_acknowledgementbooléenOnly required reading, or only the rest. This is the filter a compliance report is built on.
pinnedbooléenOnly pinned announcements, or only the rest.
qtexteFree text over title and body. Case-insensitive.
published_sincedate ISO 8601Published at or after this instant.
published_untildate ISO 8601Published before this instant.
created_sincedate ISO 8601Written at or after this instant.
updated_sincedate ISO 8601Changed at or after this instant.

GET /announcements/{id}

announcements:read

Une publication précise. C'est l'étape suivante de l'identifiant renvoyé par une publication ou apporté par un événement sortant.

Dans le chemin

ParamètreTypeValeurs admisesPar défautExempleCe que cela fait
idObligatoiretexteThe announcement id.

Dans la requête

ParamètreTypeValeurs admisesPar défautExempleCe que cela fait
fieldstexte · plusieurs, séparés par des virgulestitle · body · status · kind · language · audience · community · section · author · notify · comments_enabled · pinned · acknowledgements · reads · published_at · created_at · updated_at · urlexternal_id,department,statusComma-separated list of fields to return. `id` is always included. Use it to avoid pulling personal data you do not need.

POST /announcements

announcements:write

Publie sur le panneau d'affichage. Il faut dire qui signe et il n'y a pas de valeur par défaut. Si cette personne ne peut pas publier sans relecture, la publication entre dans la file et la réponse le dit.

Dans le corps

ParamètreTypeValeurs admisesPar défautExempleCe que cela fait
bodyObligatoiretextelongueur max. 8000The text. Plain text; line breaks are kept.
authorObligatoiretexteEMP-0042Who signs it: our id, their email or their external_id. Must be an active person in this company.
titletextelongueur max. 160Headline.
audienceobjetWho it goes to. Leave it out and it goes to everyone. Names work as well as ids, case-insensitively, because your ERP has 'Maintenance' and not a uuid of ours. Nothing is created here: an unknown name is a typo in a script, and the reply tells you which one it was.
audience.typetexteall · departments · centersallAim at everyone, at departments or at sites.
audience.idsliste["Maintenance","Quality"]Department or site names, or their ids. Required unless type is `all`.
communitytexteWhich community it belongs to, by id or by name. Leave it out and it goes on the main wall, which everybody sees. The author has to belong to the community, or be posting to the default one: an API key is not a way into a community its signer is not in.
sectiontexteWhich section it belongs to, by id or by name. It must belong to the same community.
publish_atdate ISO 86012026-09-01T06:00:00ZPublish later, at this instant. It must be in the future. The reply comes back with `status: scheduled` and the wall shows it when the hour arrives. Leave it out to publish now. Note this means two clocks are involved — yours and ours — so if your system already schedules, prefer calling us at the right moment.
requires_acknowledgementbooléenfalseRequired reading: everyone it reaches gets a notification with a confirm button, and who confirmed is on record. Only signers who can publish without review may ask for it.
notifybooléentrueWhether it makes a sound. Written the right way round on purpose: the screen has a 'publish without notifying' checkbox because a form that loses a field should still notify, but here you write the whole JSON and a field called `silent` reads wrong at three in the morning. Default is true.
comments_enabledbooléentrueWhether people can comment on it.
pinnedbooléenfalseKeep it at the top of the wall.
languagetextees · ca · en · pt · fr · it · de · sv · nl · pl · ro · csWhat language the text is written in. Leave it out and the company's is used. Getting this right matters: a Catalan original labelled as Spanish is shown to a Spanish reader without the 'not translated' notice that tells them nothing is broken.

GET /announcements/{id}/acknowledgements

announcements:read

Qui a confirmé une lecture obligatoire et qui ne l'a pas fait, avec nom et heure. C'est la seule liste nominative de toute l'API, et elle l'est parce que c'est justement l'objet de la lecture obligatoire : un acte volontaire, signé et daté que l'on peut montrer à une inspection.

Dans le chemin

ParamètreTypeValeurs admisesPar défautExempleCe que cela fait
idObligatoiretexteThe announcement id.

Dans la requête

ParamètreTypeValeurs admisesPar défautExempleCe que cela fait
pageentiermin. 112Page to return. The first page is 1, not 0.
per_pageentiermin. 1 · max. 200 · hors bornes, la valeur est ramenée au lieu d'échouer50100How many items per page. Anything above 200 is clamped to 200 rather than rejected: asking for more is a reasonable thing to want.
statetexteall · acknowledged · pendingallEveryone, only those who confirmed, or only those still pending.
departmenttexte · plusieurs, séparés par des virgulesOnly people in these departments, by name.
centertexte · plusieurs, séparés par des virgulesOnly people at these sites, by name.
sorttextename · acknowledged_atnameField to sort by. Defaults to name.
ordertexteasc · descascSort direction.

GET /metrics

metrics:read

L'effectif du jour, les arrivées, les publications et la portée par publication et par service. Les mêmes chiffres que l'écran d'analyse, calculés par le même code.

Dans la requête

ParamètreTypeValeurs admisesPar défautExempleCe que cela fait
period_daysentiermin. 1 · max. 3653090How many days back the period covers. Applies to every figure with a period, including the reach lists.
includetexte · plusieurs, séparés par des virgulesworkforce · announcements · reach_by_announcement · reach_by_departmentworkforce,announcementsWhich blocks to compute, comma-separated. Leave it out for all of them. `reach_by_announcement` is the expensive one: skip it if your dashboard only draws the headline figures.

GET /webhooks

webhooks:read

Vos adresses enregistrées, chacune avec sa santé : échecs consécutifs, ce que votre serveur a répondu la dernière fois et, si nous l'avons mise en pause, pourquoi.

Dans la requête

ParamètreTypeValeurs admisesPar défautExempleCe que cela fait
pageentiermin. 112Page to return. The first page is 1, not 0.
per_pageentiermin. 1 · max. 200 · hors bornes, la valeur est ramenée au lieu d'échouer50100How many items per page. Anything above 200 is clamped to 200 rather than rejected: asking for more is a reasonable thing to want.
eventtexteannouncement.published · announcement.pending_review · announcement.acknowledged · person.created · person.deactivatedOnly endpoints subscribed to this event.
activebooléenOnly live endpoints, or only the switched-off and paused.

POST /webhooks

webhooks:write

Enregistre une adresse et les événements qu'elle veut. La réponse apporte le secret de signature, et c'est la seule fois où il se voit.

Dans le corps

ParamètreTypeValeurs admisesPar défautExempleCe que cela fait
urlObligatoiretextelongueur max. 500https://hooks.example.com/blastackWhere we POST. https only, no credentials, no fragment.
eventsObligatoirelisteannouncement.published · announcement.pending_review · announcement.acknowledged · person.created · person.deactivated["announcement.published"]Which events this endpoint wants. At least one.
nametextelongueur max. 120Zapier · switchboardWhat it is for, in your words. It is the only thing that lets you delete the right one six months from now.
secrettextelongueur max. 200Your own signing secret, if you would rather set it than have one generated. At least 32 characters.
activebooléentrueStart delivering straight away.

GET /webhooks/{id}

webhooks:read

Une adresse précise, avec sa santé.

Dans le chemin

ParamètreTypeValeurs admisesPar défautExempleCe que cela fait
idObligatoiretexteThe webhook endpoint id.

PATCH /webhooks/{id}

webhooks:write

Change ce que vous envoyez. Remettre l'adresse en actif lève aussi la pause appliquée après des échecs répétés et remet le compteur à zéro.

Dans le chemin

ParamètreTypeValeurs admisesPar défautExempleCe que cela fait
idObligatoiretexteThe webhook endpoint id.

Dans le corps

ParamètreTypeValeurs admisesPar défautExempleCe que cela fait
urltextelongueur max. 500Where we POST. https only.
eventslisteannouncement.published · announcement.pending_review · announcement.acknowledged · person.created · person.deactivatedWhich events this endpoint wants. At least one.
nametextelongueur max. 120What it is for.
activebooléenSwitch delivery on or off. Turning it on clears a pause.
rotate_secretbooléenGenerate a new signing secret and return it once in this reply.

DELETE /webhooks/{id}

webhooks:write

La supprime avec son historique. Pour cesser de recevoir un moment sans perdre l'historique, il vaut mieux la désactiver.

Dans le chemin

ParamètreTypeValeurs admisesPar défautExempleCe que cela fait
idObligatoiretexteThe webhook endpoint id.

GET /webhooks/{id}/deliveries

webhooks:read

Tout ce que nous avons tenté de vous envoyer : tentatives, ce que vous avez répondu et quand a lieu la suivante. L'identifiant est le même que celui parti dans l'en-tête : il se recoupe avec vos propres journaux.

Dans le chemin

ParamètreTypeValeurs admisesPar défautExempleCe que cela fait
idObligatoiretexteThe webhook endpoint id.

Dans la requête

ParamètreTypeValeurs admisesPar défautExempleCe que cela fait
pageentiermin. 112Page to return. The first page is 1, not 0.
per_pageentiermin. 1 · max. 200 · hors bornes, la valeur est ramenée au lieu d'échouer50100How many items per page. Anything above 200 is clamped to 200 rather than rejected: asking for more is a reasonable thing to want.
statustextepending · delivered · given_upOnly deliveries in this state.
eventtexteannouncement.published · announcement.pending_review · announcement.acknowledged · person.created · person.deactivatedOnly deliveries of this event type.
sincedate ISO 8601Only events that happened at or after this instant.

Exemples

Trois choses qu'une usine automatise le premier mois

Avec la requête entière et la réponse entière. Changez la clé et les noms ; le reste fonctionne tel quel.

Quand la GMAO clôt l'ordre d'arrêt

L'ERP enregistre un arrêt de ligne et le panneau l'apprend tout seul

C'est le cas qu'on demande toujours. Votre système sait déjà que la ligne 3 s'arrête jeudi ; avec cet appel, il le publie lui-même, adressé aux services concernés et en demandant une confirmation de lecture, sans que personne ne saisisse rien deux fois.

Requête

curl -X POST https://app.blastack.com/api/v1/announcements \
  -H "Authorization: Bearer blsk_a1b2c3d4e5f6_YOUR_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
       "author": "EMP-0042",
       "title": "Arrêt de la ligne 3 jeudi",
       "body": "Jeudi 4 à 06:00, arrêt de la ligne 3 pour maintenance programmée. L'équipe du matin embauche à l'heure habituelle et passe sur la ligne 2.",
       "audience": {
         "type": "departments",
         "ids": [
           "Maintenance",
           "Qualité"
         ]
       },
       "requires_acknowledgement": true,
       "notify": true,
       "language": "fr"
     }'

Réponse · 201

{
  "id": "6b1f0f1e-0c2a-4c5e-9a3d-2f5b8c7d1e40",
  "title": "Arrêt de la ligne 3 jeudi",
  "body": "Jeudi 4 à 06:00, arrêt de la ligne 3 pour maintenance programmée. L'équipe du matin embauche à l'heure habituelle et passe sur la ligne 2.",
  "status": "published",
  "kind": "news",
  "language": "fr",
  "audience": {
    "type": "departments",
    "ids": [
      "9c1d7e5f-2a3b-4c5d-8e9f-0a1b2c3d4e5f",
      "44ab7e5f-2a3b-4c5d-8e9f-0a1b2c3d4e5f"
    ],
    "names": [
      "Maintenance",
      "Qualité"
    ]
  },
  "community": null,
  "section": null,
  "author": {
    "id": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c",
    "name": "Ana García",
    "email": "ana.garcia@empresa.com",
    "external_id": "EMP-0042"
  },
  "notify": true,
  "comments_enabled": true,
  "pinned": false,
  "acknowledgements": {
    "required": true,
    "confirmed": 0
  },
  "reads": 0,
  "published_at": "2026-09-01T06:00:00.000Z",
  "created_at": "2026-09-01T06:00:00.000Z",
  "updated_at": "2026-09-01T06:00:00.000Z",
  "url": "https://app.blastack.com/inicio#post-6b1f0f1e-0c2a-4c5e-9a3d-2f5b8c7d1e40"
}

La cible se donne par nom et non par identifiant, parce que c'est ce que votre système a sous la main. Si le nom n'existe pas, la réponse dit lequel et rien n'est publié : une demi-publication serait pire.

Quand le SIRH marque le départ

Quelqu'un sort du SIRH et se retrouve dehors le jour même

Si votre système parle SCIM, cela se fait déjà tout seul et cet appel est inutile. S'il ne le parle pas — ce qui est la norme dans une usine —, une ligne suffit pour désactiver la personne et fermer ses sessions sur-le-champ. Le chemin accepte votre propre identifiant : aucune table d'équivalences à maintenir.

Requête

curl -X DELETE https://app.blastack.com/api/v1/people/EMP-0042 \
  -H "Authorization: Bearer blsk_a1b2c3d4e5f6_YOUR_SECRET"

Réponse · 200

{
  "id": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c",
  "external_id": "EMP-0042",
  "email": "ana.garcia@empresa.com",
  "name": "Ana García",
  "job_title": "Chef d'équipe",
  "department": "Maintenance",
  "center": "Atelier 2",
  "role": "editor",
  "status": "disabled",
  "language": null,
  "created_at": "2026-02-11T08:14:00.000Z",
  "updated_at": "2026-09-01T07:40:22.000Z"
}

Cela désactive ; cela ne supprime pas. Ce qu'elle a publié reste, parce qu'un panneau plein de trous n'aide personne. Appeler deux fois n'est pas une erreur.

Chaque matin, ou la veille d'un audit

Qui a confirmé le protocole, dans une feuille de calcul

Un scénario Make ou un flux n8n qui demande les personnes en attente et les écrit dans une feuille : nom, service et confirmation ou non. C'est le rapport qu'un audit réclame, et celui qui évite de courir après quelqu'un dans un couloir.

Requête

curl -G https://app.blastack.com/api/v1/announcements/6b1f0f1e-0c2a-4c5e-9a3d-2f5b8c7d1e40/acknowledgements \
  --data-urlencode "state=pending" \
  --data-urlencode "department=Maintenance" \
  --data-urlencode "per_page=200" \
  -H "Authorization: Bearer blsk_a1b2c3d4e5f6_YOUR_SECRET"

Réponse · 200

{
  "announcement": {
    "id": "6b1f0f1e-0c2a-4c5e-9a3d-2f5b8c7d1e40",
    "title": "Arrêt de la ligne 3 jeudi"
  },
  "summary": {
    "recipients": 34,
    "acknowledged": 27,
    "pending": 7
  },
  "data": [
    {
      "person": {
        "id": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c",
        "name": "Ana García",
        "email": "ana.garcia@empresa.com",
        "external_id": "EMP-0042",
        "department": "Maintenance",
        "center": "Atelier 2"
      },
      "acknowledged": false,
      "acknowledged_at": null
    }
  ],
  "page": 1,
  "per_page": 200,
  "total": 7
}

Le résumé se compte sur la population entière et non sur la page ni sur le filtre, pour que le « 12 sur 30 » veuille encore dire quelque chose. L'heure de la confirmation est celle de la première fois et n'est plus jamais touchée.

Événements sortants

C'est nous qui appelons, en moins d'une minute

C'est ce qui rend tout cela vraiment connectable. Sans événements sortants, le déclencheur de votre scénario doit être « toutes les cinq minutes, demande », et c'est lent, facturé au passage et presque toujours pour rien.

ÉvénementQuand il part
announcement.publishedQuelque chose est paru sur le panneau, quel que soit le chemin emprunté : le compositeur, l'éditeur complet, cette API, la file de relecture ou une publication programmée arrivée à son heure. Le type voyage à l'intérieur, au cas où seules les publications simples vous intéressent et pas les sondages ou les événements.
announcement.pending_reviewUne publication attend une approbation. Cela ne part que dans les entreprises dont la file de relecture est activée.
announcement.acknowledgedQuelqu'un a confirmé une lecture obligatoire. Un événement par personne, avec qui et quand.
person.createdQuelqu'un a été créé, peu importe par où : provisioning, code d'accès, authentification unique, écran d'administration ou cette API.
person.deactivatedQuelqu'un a été désactivé. Comme personne n'est jamais supprimé ici, c'est le signal de sortie.

L'enveloppe, la même pour les cinq

{
  "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
  "type": "announcement.published",
  "occurred_at": "2026-09-01T06:00:00.000Z",
  "organization_id": "0a9b8c7d-6e5f-4a3b-8c9d-0e1f2a3b4c5d",
  "data": {
    "announcement": {
      "id": "6b1f0f1e-0c2a-4c5e-9a3d-2f5b8c7d1e40",
      "title": "Parada de la línea 3 el jueves",
      "body": "El jueves 4 a las 06:00 para la línea 3 por mantenimiento programado.",
      "kind": "news",
      "language": "es",
      "requires_acknowledgement": true,
      "audience": {
        "type": "departments",
        "names": [
          "Mantenimiento",
          "Calidad"
        ]
      },
      "community": "Planta de Getafe",
      "author": {
        "id": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c",
        "name": "Ana García",
        "email": "ana.garcia@empresa.com",
        "external_id": "EMP-0042"
      },
      "url": "https://app.blastack.com/inicio#post-6b1f0f1e-0c2a-4c5e-9a3d-2f5b8c7d1e40",
      "status": "published"
    }
  }
}

Ce qu'il y a dedans change avec l'événement ; l'enveloppe, non. L'identifiant ne change pas entre les tentatives : écarter un doublon tient en une ligne de votre côté.

Les en-têtes de chaque envoi

En-têteÀ quoi cela sert
blastack-eventCe qui s'est passé. C'est la valeur sur laquelle on branche.
blastack-event-idL'identifiant de l'événement. Il ne change pas entre les tentatives : c'est celui qui sert à ne jamais exécuter deux fois la même chose.
blastack-delivery-attemptDe quelle tentative il s'agit, en commençant par la première.
blastack-signatureLa signature. C'est la seule chose qui sépare un envoi de nous d'un envoi inventé par qui découvre votre adresse.

Vérifier la signature

La signature est un HMAC-SHA256 sur l'horodatage, un point et le corps brut, non analysé. C'est le format qu'utilisent les passerelles de paiement, donc celui que vous avez probablement déjà écrit une fois.

import { createHmac, timingSafeEqual } from "node:crypto";

export function verify(rawBody, headers, secret) {
  const sent = headers["blastack-signature"] ?? "";
  const t = /t=(\d+)/.exec(sent)?.[1];
  const v1 = /v1=([0-9a-f]+)/.exec(sent)?.[1];
  if (!t || !v1) return false;

  const mine = createHmac("sha256", secret)
    .update(`${t}.${rawBody}`, "utf8")
    .digest("hex");

  if (v1.length !== mine.length) return false;
  if (!timingSafeEqual(Buffer.from(v1, "hex"), Buffer.from(mine, "hex"))) {
    return false;
  }
  return Math.abs(Date.now() / 1000 - Number(t)) < 300;
}

Comparez en temps constant et rejetez tout horodatage vieux de plus de quelques minutes. Sans cette seconde vérification, une copie d'un envoi ancien peut vous être renvoyée pendant des années avec une signature toujours valable.

Reprises, mise en pause, et pourquoi rien n'arrive

  • N'importe quelle réponse 2xx convient. Nous ne lisons pas le corps : répondez vite et faites le travail après, car nous abandonnons au bout de dix secondes et cela compte comme un échec.
  • Six tentatives avec attente croissante — une minute, cinq, quinze, une heure, trois et six — réparties sur environ dix heures et demie. De quoi couvrir un déploiement de nuit et une maintenance de week-end.
  • Trente échecs consécutifs mettent l'adresse en pause, et la raison est consignée. On la relève en la remettant en actif, ce qui remet aussi le compteur à zéro.
  • Nous n'appelons que des adresses https publiques. C'est vérifié à l'enregistrement et de nouveau avant chaque envoi, parce qu'un nom qui résout aujourd'hui vers l'internet public peut résoudre demain vers votre réseau interne.
  • Une adresse enregistrée aujourd'hui ne reçoit pas les événements d'hier : un abonnement compte à partir de sa création, pour que monter votre premier scénario ne déclenche pas quarante exécutions d'un coup.

Erreurs

Toujours la même forme

Toute erreur renvoie le même objet, avec un code pensé pour écrire une condition dessus. Les codes ne sont jamais renommés : ils sont ajoutés. Le message d'à côté est pour qui lit le journal, et celui-là peut changer.

{
  "error": {
    "status": 403,
    "code": "insufficient_scope",
    "message": "This API key does not have the \"metrics:read\" scope.",
    "required_scope": "metrics:read",
    "granted_scopes": [
      "people:read"
    ]
  },
  "documentation": "https://blastack.com/en/developers"
}

Un paramètre inconnu est refusé, pas ignoré. Un filtre écarté en silence vous renvoie plus de données que demandé et rien ne vous prévient.

RateLimit-Limit · RateLimit-Remaining · RateLimit-Reset · Retry-After

CodeQuand il sort
invalid_token401 · La clé manque, est mal écrite ou a été révoquée. Nous ne disons pas laquelle des trois.
insufficient_scope403 · La clé est valide mais ne porte pas la portée que cet appel demande. La réponse dit laquelle il fallait et lesquelles elle a.
module_required403 · L'entreprise n'a pas souscrit le module d'identité d'entreprise, celui dont relève l'API.
read_only403 · La période d'essai est terminée et l'entreprise est en lecture seule. Cela ne touche que ce qui écrit.
rate_limited429 · Plus de requêtes que permis en une minute. La réponse dit combien de secondes attendre.
invalid_request400 · Un champ manque, est en trop ou n'est pas compris. Le message nomme le paramètre exact et liste les valeurs admises.
not_found404 · Rien à vous avec cet identifiant. C'est aussi ce que l'on reçoit pour quelque chose appartenant à une autre entreprise : distinguer les deux serait un moyen de découvrir ce qui existe ailleurs.
conflict409 · Cela entre en conflit avec ce qui existe déjà : deux personnes avec la même adresse, deux adresses d'événement identiques. La réponse apporte l'identifiant de ce qui bloquait, pour pouvoir continuer.
server_error500 · Quelque chose a cassé chez nous. Rien de l'erreur ne sort dans la réponse ; l'ensemble reste dans notre journal.

Limites

Ce qu'il faut savoir avant d'écrire la boucle

  • Cent vingt requêtes par minute et par clé. Chaque réponse porte combien il en reste et dans combien de secondes le compteur repart ; un 429 porte en plus le temps d'attente.
  • Les listes arrivent par cinquante et acceptent jusqu'à deux cents par page. La première page est la 1, pas la 0. Demander plus de deux cents est ramené au lieu d'être refusé.
  • La période des indicateurs va jusqu'à trois cent soixante-cinq jours et se demande par paramètre. La portée par publication est le bloc coûteux : à laisser de côté si votre tableau de bord ne dessine que les chiffres de tête.
  • Vingt adresses d'événement sortant par entreprise. Ce n'est pas une limite commerciale : chaque événement est mis en file une fois par adresse, et qui en a besoin de davantage répartit au mauvais endroit.
  • Les événements sortants mettent jusqu'à une minute : ils sont détectés en lisant la base et non depuis le bouton de publication, pour que le serveur lent d'une intégration ne puisse freiner le panneau de personne.
  • Seules les dernières vingt-quatre heures sont annoncées. Si notre tâche d'horloge restait arrêtée un jour entier, nous ne vous lâchons pas le trimestre d'un coup : vos automatisations tourneraient sur des données d'avant-hier comme si elles étaient d'à présent.

Ce que l'API ne fait pas

Dit ici pour que vous ne le découvriez pas à mi-chemin

Qui va intégrer a besoin des limites avant de commencer, pas quand un demi-scénario est déjà monté. Cette liste est ce qu'un développeur va chercher sans le trouver, et elle est mise à jour dès que quelque chose cesse d'être vrai.

  • Il n'y a pas d'écran pour créer des clés. Aujourd'hui elles s'émettent en console avec npm run clave:api, et c'est nous qui les émettons. Un écran honnête aurait besoin de ses textes dans les douze langues de l'application, et un demi-écran traduit ne se publie pas.
  • Les événements sortants ont besoin d'une ligne de cron sur le serveur. Sans elle rien ne casse, et c'est là le problème : tout le reste continue de fonctionner et simplement rien ne part. Cela se voit dans le journal des livraisons, qui serait vide.
  • Le secret de signature est montré une seule fois : à la création de l'adresse ou à sa rotation. Il ne peut pas être relu, seulement changé. Rangez-le à ce moment-là.
  • La rotation du secret n'a aucune période de grâce. L'envoi suivant est déjà signé avec le nouveau : changez-le d'abord sur votre serveur et demandez la rotation ensuite.
  • Vingt adresses d'événement sortant par entreprise. S'il vous en faut davantage, la répartition doit se faire dans votre propre outil à partir d'une seule livraison.
  • On n'atteint ni la messagerie, ni les sondages, ni les événements, ni les remerciements, ni les albums. Ils apparaissent dans la liste des publications et dans les événements sortants avec leur type, mais ils ne se créent ni ne se lisent pour eux-mêmes.
  • On n'atteint pas les documents et on ne téléverse aucun fichier. Ni d'images dans une publication : le corps est du texte brut.
  • Une publication déjà faite ne se modifie ni ne se supprime, et les commentaires ne s'écrivent ni ne se lisent.
  • On ne cherche pas les personnes par adresse partielle, et personne ne se supprime vraiment : la suppression est une demande écrite que nous traitons, et elle anonymise au lieu d'effacer.
  • Les indicateurs sont agrégés et il n'y a aucun moyen de sortir qui a lu quoi. La seule liste nominative est celle des lectures obligatoires, qui existe pour pouvoir être montrée à une inspection.
  • Il n'y a ni environnement de test séparé, ni bibliothèques officielles pour aucun langage, ni pagination par curseur. C'est du JSON sur HTTPS et on l'appelle avec ce qu'on a.

Pour les machines

Si c'est un assistant qui lit ceci

La moitié d'une évaluation d'achat consiste aujourd'hui à demander à un assistant si cela se connecte à quelque chose. La réponse est donc écrite pour être lisible sans compte et sans rien deviner.

  • La spécification OpenAPI 3.1 se trouve à une adresse publique et stable, sans clé, avec l'origine croisée autorisée et sans toucher la base de données. Elle décrit les dix-sept points d'entrée avec leurs paramètres, leurs valeurs admises, la forme de chaque réponse et les cinq événements sortants.
  • Elle n'est pas écrite à la main : elle est générée depuis le même catalogue que celui contre lequel chaque point d'entrée vérifie ce qui arrive, et les formes de réponse sortent de l'exécution du code même qui sert les requêtes. Elle ne peut pas dire autre chose que ce qu'elle fait.
  • Cette page a la même structure dans les six langues, avec des titres qui annoncent ce qu'il y a dessous et de vrais tableaux, pas des images ni de fausses colonnes.
  • Il existe aussi un llms.txt avec la version courte, dont la section d'intégration est écrite à part et où les adresses et les portées sont en texte brut.

S'il vous manque quelque chose de cette liste, dites-le

Ce qu'on nous demande le plus est ce qui s'écrit ensuite. Et si quelque chose de cette page ne colle pas avec ce que répond le serveur, c'est une faute de notre part et nous voulons le savoir le jour même.