Blastack

Sviluppatori

L'API e i tre strumenti con cui si collega

Diciassette operazioni su dieci percorsi, cinque eventi in uscita e una specifica OpenAPI 3.1 pubblica che Make e n8n importano da soli. Qui c'è tutto: ogni parametro uno per uno, esempi che funzionano così come sono e l'elenco di ciò che non fa.

Incollate il primo indirizzo nell'importatore di n8n o di Make e i nodi si creano da soli. Zapier non legge OpenAPI: proprio per questo i suoi passaggi sono scritti a parte, più sotto.

In sintesi

Quello che serve per la prima chiamata

Otto dati. Con questi la richiesta si scrive senza leggere oltre.

CosaValoreNota
Radice dell'APIhttps://app.blastack.com/api/v1Sta nell'applicazione, non su questo sito commerciale. Un indirizzo solo, e non cambia.
Specificahttps://app.blastack.com/api/openapi.jsonPubblica e senza chiave, perché un importatore possa leggerla prima ancora di avere le credenziali.
AutenticazioneAuthorization: Bearer blsk_<prefix>_<secret>Nell'intestazione, mai nell'indirizzo. Gli indirizzi finiscono nel registro del server, in quello del proxy davanti e nella cronologia di chi l'ha provata a mano.
Formatoapplication/json; charset=utf-8JSON in entrata e in uscita. Niente XML e niente moduli.
Limite120 req/min · RateLimit-RemainingPer chiave e al minuto. Ogni risposta dice quante ne restano e quando riparte il contatore.
Paginazionepage=1 · per_page=50 · ≤ 200La prima pagina è la 1, non la 0. Chiedere più di duecento viene ridotto invece che rifiutato.
Errori{ error: { status, code, message } }Sempre lo stesso oggetto, con un codice stabile pensato per scriverci sopra una condizione.
Ambiente di prova—Non esiste. Si lavora contro la produzione, ed è per questo che conviene partire con una chiave in sola lettura.
curl https://app.blastack.com/api/v1/people?per_page=1 \
  -H "Authorization: Bearer blsk_a1b2c3d4e5f6_YOUR_SECRET"

Che cosa c'è

Tre superfici, e nessuna fatta a metà

Funzionano tutte e tre. Quello che manca sta più sotto, in una sezione sua e chiamato per nome.

Provisioning SCIM 2.0

Perché il vostro gestionale HR crei le persone, le sposti di reparto e le disattivi senza che nessuno lo ricopi a mano. È la metà che conta davvero per un ufficio informatico: il giorno in cui licenziate qualcuno, l'account si disattiva da solo.

Filtri su userName ed externalId, paginazione e modifica parziale. Vengono letti il reparto e l'indirizzo di lavoro, quindi chi entra da qui nasce con reparto e sede già impostati. L'uscita disattiva, non cancella.

Accesso unico (OpenID Connect)

Entrare con l'account aziendale da Entra ID, Google Workspace o Okta. Convive con il codice di accesso, che è il modo in cui entra la parte dell'organico senza posta aziendale.

Si configura incollando l'indirizzo di scoperta del fornitore e viene verificata contro di lui prima di salvare. I domini di posta si verificano via DNS. Non c'è né SAML né LDAP.

API Blastack

Pubblicare dal programma che già sa che la linea 3 si ferma giovedì, disattivare chi esce dal gestionale HR, e farsi chiamare da noi quando succede qualcosa invece di dover chiedere ogni cinque minuti.

JSON su HTTPS, chiave API nell'intestazione, ambiti per chiave, errori con codice stabile ed eventi in uscita firmati. È quello che documenta il resto di questa pagina.

Automazione

Zapier, Make e n8n, passo per passo

I tre non si montano allo stesso modo, e dirlo risparmia il pomeriggio che si perde a scoprirlo. Make e n8n leggono la specifica e si configurano quasi da soli; Zapier non la legge, quindi lì ogni chiamata si scrive a mano. Funzionano tutti e tre; il lavoro non è lo stesso.

StrumentoLegge la specifica?Attivatore consigliato
n8nSì, per interoNodo «Webhook» + POST /webhooks
MakeSì, nell'editor delle app proprie«Custom webhook» + POST /webhooks
ZapierNo«Catch Hook» + POST /webhooks

n8n

La strada più corta delle tre. Si crea una credenziale di intestazione, si incolla l'indirizzo della specifica nell'importatore e resta un nodo per operazione con i parametri già al loro posto.

Passaggi

  1. 01Credenziali → nuova → «Header Auth». Il nome dell'intestazione è Authorization e il valore è Bearer, uno spazio e la vostra chiave.
  2. 02Nodo «HTTP Request», autenticazione «Generic Credential Type» → «Header Auth» e poi la credenziale appena creata. Metodo e percorso escono dalla tabella degli endpoint.
  3. 03Per non scrivere i parametri a mano, date all'importatore l'indirizzo della specifica: descrive ogni endpoint con i valori ammessi, quindi ciò che viene generato arriva con i menu a tendina invece che con caselle di testo libere.
  4. 04Per attivare: nodo «Webhook», copiate il suo indirizzo di produzione e registratelo con POST /webhooks scegliendo gli eventi. Chiedere ogni cinque minuti smette di servire.

Da tenere presente

Il nodo webhook risponde 200 prima di eseguire il resto del flusso, ed è esattamente ciò che serve qui: dopo dieci secondi rinunciamo e vale come un errore.

Make

Il modulo HTTP generico basta per tutto, e chi ha in mente molti scenari può caricare la specifica nell'editor delle app proprie e ottenere un modulo per operazione.

Passaggi

  1. 01Modulo «HTTP» → «Make an API Key Auth request». Nella connessione la chiave si chiama Authorization, il valore è Bearer più la vostra chiave, e va nell'intestazione.
  2. 02Metodo, percorso e corpo escono dalla tabella degli endpoint e dagli esempi più sotto. Il tipo di contenuto è application/json.
  3. 03Se costruite più scenari, l'editor delle app proprie accetta la specifica e genera un modulo per operazione: meno scenari scritti a mano e meno refusi nei nomi dei filtri.
  4. 04Per attivare: modulo «Webhooks» → «Custom webhook», copiate il suo indirizzo e registratelo con POST /webhooks. Make risponde subito ed elabora dopo, che qui è l'ordine giusto.

Da tenere presente

Make fattura a operazione: uno scenario che interroga ogni cinque minuti brucia ottomila operazioni al mese per non trovare quasi nulla. Con il webhook se ne spende una per evento.

Zapier

Zapier non importa OpenAPI. Si monta con i passaggi generici dei webhook, oppure costruendo un'integrazione privata sulla loro piattaforma per sviluppatori, dove ogni endpoint si dichiara a mano.

Passaggi

  1. 01Attivatore: «Webhooks by Zapier» → «Catch Hook». Copiate l'indirizzo che vi dà e registratelo con POST /webhooks scegliendo gli eventi.
  2. 02Azione: «Webhooks by Zapier» → «Custom Request». Metodo e indirizzo dalla tabella, intestazioni Authorization con Bearer più la vostra chiave e Content-Type con application/json, e il JSON nel campo dei dati.
  3. 03Aggiungete un passaggio «Code by Zapier» che verifichi la firma prima di fare qualsiasi cosa. Zapier non la verifica per voi e l'indirizzo dell'attivatore è pubblico: senza quel passaggio, chiunque lo scopra può inventarsi un fermo linea.
  4. 04Se preferite nodi con un nome invece di richieste generiche, bisogna costruire un'integrazione privata e dichiarare lì ogni endpoint con i suoi campi. È più lavoro, e la specifica non ne risparmia nulla.

Da tenere presente

I loro attivatori a interrogazione spendono un'attività a ogni passaggio, che trovino qualcosa o no. Il «Catch Hook» spende solo quando è successo davvero qualcosa.

Chiavi

Una chiave per integrazione, con lo stretto necessario

Oggi le emettiamo noi, a mano, e vi diciamo con quali ambiti. Non c'è una schermata self-service ed è detto più sotto, tra quello che manca. Ogni chiave è legata a un'unica azienda e nessuna rotta legge un identificativo di azienda dalla richiesta: non c'è dove sbagliare.

  1. 01

    Chiedeteci la chiave

    Diteci a cosa serve e cosa deve poter fare, e la emettiamo con quegli ambiti e nessun altro. Si mostra una volta sola: ne conserviamo solo un'impronta, quindi una chiave persa si revoca e se ne emette un'altra.

  2. 02

    Mandatela a ogni richiesta

    Nell'intestazione di autorizzazione, mai nell'indirizzo. Gli indirizzi finiscono nel registro del server, in quello del proxy davanti e nella cronologia di chi l'ha provata a mano.

  3. 03

    Conservatela dove tenete le altre

    Nel vostro gestore di segreti, non nel repository. Inizia con un prefisso riconoscibile proprio perché i rilevatori di segreti la peschino se scappa.

L'API rientra nel modulo di identità aziendale, lo stesso che apre l'accesso unico e il provisioning. Se l'azienda non l'ha attivato, la risposta lo dice con queste parole e non con un errore generico.

Gli ambiti, uno per uno

AmbitoChe cosa apre
people:readLeggere l'organico e i reparti e le sedi a cui si può indirizzare una comunicazione. È tutto quello che serve a un cruscotto.
people:writeCreare, modificare e disattivare persone. Disattivare chiude le loro sessioni, quindi non arriva in regalo con quello di lettura.
announcements:readLeggere ciò che è stato pubblicato e chi ha confermato una lettura obbligatoria. Sta a parte da quello delle persone: un elenco di nomi e mansioni è la rubrica, il testo delle comunicazioni no.
announcements:writePubblicare in bacheca. Rispetta la coda di revisione dell'azienda, quindi una chiave non scavalca il percorso di approvazione di nessuno.
metrics:readGli indicatori aggregati. Qui non compare nessun nome.
webhooks:readVedere gli indirizzi registrati e il registro delle consegne. È ciò che risponde a «perché non arriva niente» senza aprire un ticket.
webhooks:writeRegistrare, modificare e cancellare indirizzi di evento in uscita. Il più delicato dell'elenco: decide a quale server di internet mandiamo il contenuto delle vostre comunicazioni.

Endpoint

Diciassette operazioni su dieci percorsi

Raggruppate per famiglia. La colonna dell'ambito è quella da guardare quando si chiede la chiave: se manca, la risposta dice quale serviva e quali ha la vostra.

MetodoPercorsoAmbitoChe cosa fa
GET/peoplepeople:readL'organico, con il reparto, la sede e l'identificativo che ogni persona ha nel vostro gestionale HR. Diciassette parametri, tra cui il filtro sulla data dell'ultima modifica, quello che permette di sincronizzare ogni quarto d'ora senza scaricare tutto.
GET/people/{id}people:readUna persona precisa, cercata con il nostro identificativo o con il vostro. Serve per aggiornare una scheda senza percorrere tutto l'elenco.
POST/peoplepeople:writeCrea qualcuno. È per quando il vostro gestionale HR non parla SCIM; se lo parla, meglio SCIM, che gestisce anche le uscite. Reparto e sede si indicano per nome e vengono creati se non esistono.
PATCH/people/{id}people:writeCambia solo i campi che mandate. Uno che non mandate non viene toccato: una sincronizzazione che conosce solo la mansione non può cancellare la sede a nessuno.
DELETE/people/{id}people:writeDisattiva; non cancella mai. Le sessioni si chiudono subito, quindi chi esce di venerdì è fuori quel venerdì. Ciò che ha pubblicato resta.
GET/audiencespeople:readI reparti e le sedi che esistono, con quante persone ci sono in ciascuno. È da qui che escono i nomi a cui si può indirizzare una comunicazione, e il filtro dei gruppi vuoti è quello che trova una mappatura di provisioning rotta.
GET/announcementsannouncements:readTutto ciò che è stato pubblicato, con le letture e le conferme di ogni pezzo. Bozze e respinti sono inclusi perché un cruscotto possa disegnare l'imbuto intero.
GET/announcements/{id}announcements:readUna pubblicazione precisa. È il passo successivo all'identificativo restituito da una pubblicazione o portato da un evento in uscita.
POST/announcementsannouncements:writePubblica in bacheca. Bisogna dire chi firma e non c'è un valore predefinito. Se quella persona non può pubblicare senza revisione, la comunicazione entra in coda e la risposta lo dice.
GET/announcements/{id}/acknowledgementsannouncements:readChi ha confermato una lettura obbligatoria e chi no, con nome e ora. È l'unico elenco nominativo di tutta l'API, e lo è perché quello è proprio il senso della lettura obbligatoria: un atto volontario, firmato e datato che si può mostrare a un'ispezione.
GET/metricsmetrics:readL'organico di oggi, gli ingressi, le pubblicazioni e la copertura per pubblicazione e per reparto. Gli stessi numeri della schermata di analisi, calcolati dallo stesso codice.
GET/webhookswebhooks:readI vostri indirizzi registrati, ciascuno con il suo stato di salute: errori consecutivi, che cosa ha risposto il vostro server l'ultima volta e, se l'abbiamo messo in pausa, perché.
POST/webhookswebhooks:writeRegistra un indirizzo e gli eventi che vuole. La risposta porta il segreto di firma, ed è l'unica volta in cui si vede.
GET/webhooks/{id}webhooks:readUn indirizzo preciso, con il suo stato di salute.
PATCH/webhooks/{id}webhooks:writeCambia quello che mandate. Rimettere l'indirizzo su attivo toglie anche la pausa applicata dopo errori ripetuti e azzera il contatore.
DELETE/webhooks/{id}webhooks:writeLo cancella con il suo storico. Per smettere di ricevere per un po' senza perdere lo storico, meglio disattivarlo.
GET/webhooks/{id}/deliverieswebhooks:readTutto quello che abbiamo provato a mandarvi: tentativi, che cosa avete risposto e quando tocca il prossimo. L'identificativo è lo stesso che ha viaggiato nell'intestazione, quindi si incrocia con i vostri registri.

Parametri

Tutti, endpoint per endpoint

Nessun elenco qui è ridotto: sono gli stessi che controlla il server. Un parametro che non è qui non esiste, e scriverlo restituisce un errore che elenca quelli ammessi da quell'endpoint invece di ignorarlo in silenzio.

La colonna di destra è in inglese di proposito. Esce dal catalogo da cui viene generata anche la specifica, quindi è parola per parola ciò che n8n e Make mostrano dentro i loro nodi. Tradurla qui vorrebbe dire avere due versioni che un giorno direbbero cose diverse.

GET /people

people:read

L'organico, con il reparto, la sede e l'identificativo che ogni persona ha nel vostro gestionale HR. Diciassette parametri, tra cui il filtro sulla data dell'ultima modifica, quello che permette di sincronizzare ogni quarto d'ora senza scaricare tutto.

Nella query

ParametroTipoValori ammessiPredefinitoEsempioChe cosa fa
pageinteromin. 112Page to return. The first page is 1, not 0.
per_pageinteromin. 1 · max. 200 · fuori intervallo viene ridotto invece che rifiutato50100How many items per page. Anything above 200 is clamped to 200 rather than rejected: asking for more is a reasonable thing to want.
sorttestocreated_at · updated_at · name · emailcreated_atField to sort by. Defaults to created_at.
ordertestoasc · descascSort direction.
fieldstesto · più valori separati da virgoleexternal_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.
statustesto · più valori separati da virgoleactive · invited · disabledactiveOnly people in these states. Several may be given.
roletesto · più valori separati da virgoleowner · admin · gestor_personas · responsable_local · informatico · editor · revisor · analista · employeeOnly people with these roles. Several may be given.
departmenttesto · più valori separati da virgoleMaintenance,QualityDepartment name, or several separated by commas. Case-insensitive: your directory writing MANTENIMIENTO is not an error.
centertesto · più valori separati da virgoleSite name, or several separated by commas. Case-insensitive.
no_departmentbooleanoOnly 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.
languagetesto · più valori separati da virgolees · ca · en · pt · fr · it · de · sv · nl · pl · ro · csOnly people who picked this reading language.
emailtestoExact email address, case-insensitive.
external_idtestoExact external_id, as sent by your HR system over SCIM.
qtestogarciaFree text over name, email and job title. Case-insensitive, matches anywhere in the value.
updated_sincedata 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_sincedata ISO 8601Only people added at or after this instant.
created_untildata ISO 8601Only people added before this instant.

GET /people/{id}

people:read

Una persona precisa, cercata con il nostro identificativo o con il vostro. Serve per aggiornare una scheda senza percorrere tutto l'elenco.

Nel percorso

ParametroTipoValori ammessiPredefinitoEsempioChe cosa fa
idObbligatoriotestoa3f1…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.

Nella query

ParametroTipoValori ammessiPredefinitoEsempioChe cosa fa
fieldstesto · più valori separati da virgoleexternal_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

Crea qualcuno. È per quando il vostro gestionale HR non parla SCIM; se lo parla, meglio SCIM, che gestisce anche le uscite. Reparto e sede si indicano per nome e vengono creati se non esistono.

Nel corpo

ParametroTipoValori ammessiPredefinitoEsempioChe cosa fa
nameObbligatoriotestolunghezza max. 120Ana GarcíaFull name, as it should appear on the wall.
emailtestolunghezza 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_idtestolunghezza max. 200EMP-0042The id this person has in your system. Store it and you can cross both lists later without matching names.
job_titletestolunghezza max. 120Job title.
departmenttestolunghezza max. 80Department name. Created if it does not exist. Without one, this person only ever sees company-wide announcements.
centertestolunghezza max. 80Site name. Created if it does not exist.
roletestoadmin · 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.
statustestoactive · 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.
languagetestoes · 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

Cambia solo i campi che mandate. Uno che non mandate non viene toccato: una sincronizzazione che conosce solo la mansione non può cancellare la sede a nessuno.

Nel percorso

ParametroTipoValori ammessiPredefinitoEsempioChe cosa fa
idObbligatoriotestoa3f1…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.

Nel corpo

ParametroTipoValori ammessiPredefinitoEsempioChe cosa fa
nametestolunghezza max. 120Full name.
emailtestolunghezza max. 200Work email.
external_idtestolunghezza max. 200The id this person has in your system.
job_titletestolunghezza max. 120Job title.
departmenttestolunghezza max. 80Department name. Created if it does not exist.
centertestolunghezza max. 80Site name. Created if it does not exist.
roletestoadmin · gestor_personas · responsable_local · informatico · editor · revisor · analista · employeeWhat they can do. `owner` cannot be given from the API.
statustestoactive · invited · disabledTheir state. `disabled` also closes their sessions.
languagetestoes · ca · en · pt · fr · it · de · sv · nl · pl · ro · csReading language.

DELETE /people/{id}

people:write

Disattiva; non cancella mai. Le sessioni si chiudono subito, quindi chi esce di venerdì è fuori quel venerdì. Ciò che ha pubblicato resta.

Nel percorso

ParametroTipoValori ammessiPredefinitoEsempioChe cosa fa
idObbligatoriotestoa3f1…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

I reparti e le sedi che esistono, con quante persone ci sono in ciascuno. È da qui che escono i nomi a cui si può indirizzare una comunicazione, e il filtro dei gruppi vuoti è quello che trova una mappatura di provisioning rotta.

Nella query

ParametroTipoValori ammessiPredefinitoEsempioChe cosa fa
typetestoall · departments · centersallReturn only departments, only sites, or both.
qtestoFree text over the name. Case-insensitive.
with_peoplebooleanoOnly 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.
sorttestoname · peoplenameField to sort by. Defaults to name.
ordertestoasc · descascSort direction.

GET /announcements

announcements:read

Tutto ciò che è stato pubblicato, con le letture e le conferme di ogni pezzo. Bozze e respinti sono inclusi perché un cruscotto possa disegnare l'imbuto intero.

Nella query

ParametroTipoValori ammessiPredefinitoEsempioChe cosa fa
pageinteromin. 112Page to return. The first page is 1, not 0.
per_pageinteromin. 1 · max. 200 · fuori intervallo viene ridotto invece che rifiutato50100How many items per page. Anything above 200 is clamped to 200 rather than rejected: asking for more is a reasonable thing to want.
sorttestopublished_at · created_at · updated_at · titlepublished_atField to sort by. Defaults to published_at.
ordertestoasc · descascSort direction.
fieldstesto · più valori separati da virgoletitle · 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.
statustesto · più valori separati da virgoledraft · pending_review · published · rejected · scheduled · archivedpublished,scheduledOnly these states. Several may be given. `scheduled` means it is written and waiting for its hour.
authortestoWho signs it: our id, their email or their external_id. Any of the three.
audience_typetestoall · departments · centersOnly announcements aimed this way.
departmenttesto · più valori separati da virgoleOnly announcements aimed at these departments, by name. Several may be given.
centertesto · più valori separati da virgoleOnly announcements aimed at these sites, by name.
communitytestoOnly announcements in this community, by id or by name.
requires_acknowledgementbooleanoOnly required reading, or only the rest. This is the filter a compliance report is built on.
pinnedbooleanoOnly pinned announcements, or only the rest.
qtestoFree text over title and body. Case-insensitive.
published_sincedata ISO 8601Published at or after this instant.
published_untildata ISO 8601Published before this instant.
created_sincedata ISO 8601Written at or after this instant.
updated_sincedata ISO 8601Changed at or after this instant.

GET /announcements/{id}

announcements:read

Una pubblicazione precisa. È il passo successivo all'identificativo restituito da una pubblicazione o portato da un evento in uscita.

Nel percorso

ParametroTipoValori ammessiPredefinitoEsempioChe cosa fa
idObbligatoriotestoThe announcement id.

Nella query

ParametroTipoValori ammessiPredefinitoEsempioChe cosa fa
fieldstesto · più valori separati da virgoletitle · 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

Pubblica in bacheca. Bisogna dire chi firma e non c'è un valore predefinito. Se quella persona non può pubblicare senza revisione, la comunicazione entra in coda e la risposta lo dice.

Nel corpo

ParametroTipoValori ammessiPredefinitoEsempioChe cosa fa
bodyObbligatoriotestolunghezza max. 8000The text. Plain text; line breaks are kept.
authorObbligatoriotestoEMP-0042Who signs it: our id, their email or their external_id. Must be an active person in this company.
titletestolunghezza max. 160Headline.
audienceoggettoWho 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.typetestoall · departments · centersallAim at everyone, at departments or at sites.
audience.idselenco["Maintenance","Quality"]Department or site names, or their ids. Required unless type is `all`.
communitytestoWhich 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.
sectiontestoWhich section it belongs to, by id or by name. It must belong to the same community.
publish_atdata 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_acknowledgementbooleanofalseRequired 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.
notifybooleanotrueWhether 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_enabledbooleanotrueWhether people can comment on it.
pinnedbooleanofalseKeep it at the top of the wall.
languagetestoes · 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

Chi ha confermato una lettura obbligatoria e chi no, con nome e ora. È l'unico elenco nominativo di tutta l'API, e lo è perché quello è proprio il senso della lettura obbligatoria: un atto volontario, firmato e datato che si può mostrare a un'ispezione.

Nel percorso

ParametroTipoValori ammessiPredefinitoEsempioChe cosa fa
idObbligatoriotestoThe announcement id.

Nella query

ParametroTipoValori ammessiPredefinitoEsempioChe cosa fa
pageinteromin. 112Page to return. The first page is 1, not 0.
per_pageinteromin. 1 · max. 200 · fuori intervallo viene ridotto invece che rifiutato50100How many items per page. Anything above 200 is clamped to 200 rather than rejected: asking for more is a reasonable thing to want.
statetestoall · acknowledged · pendingallEveryone, only those who confirmed, or only those still pending.
departmenttesto · più valori separati da virgoleOnly people in these departments, by name.
centertesto · più valori separati da virgoleOnly people at these sites, by name.
sorttestoname · acknowledged_atnameField to sort by. Defaults to name.
ordertestoasc · descascSort direction.

GET /metrics

metrics:read

L'organico di oggi, gli ingressi, le pubblicazioni e la copertura per pubblicazione e per reparto. Gli stessi numeri della schermata di analisi, calcolati dallo stesso codice.

Nella query

ParametroTipoValori ammessiPredefinitoEsempioChe cosa fa
period_daysinteromin. 1 · max. 3653090How many days back the period covers. Applies to every figure with a period, including the reach lists.
includetesto · più valori separati da virgoleworkforce · 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

I vostri indirizzi registrati, ciascuno con il suo stato di salute: errori consecutivi, che cosa ha risposto il vostro server l'ultima volta e, se l'abbiamo messo in pausa, perché.

Nella query

ParametroTipoValori ammessiPredefinitoEsempioChe cosa fa
pageinteromin. 112Page to return. The first page is 1, not 0.
per_pageinteromin. 1 · max. 200 · fuori intervallo viene ridotto invece che rifiutato50100How many items per page. Anything above 200 is clamped to 200 rather than rejected: asking for more is a reasonable thing to want.
eventtestoannouncement.published · announcement.pending_review · announcement.acknowledged · person.created · person.deactivatedOnly endpoints subscribed to this event.
activebooleanoOnly live endpoints, or only the switched-off and paused.

POST /webhooks

webhooks:write

Registra un indirizzo e gli eventi che vuole. La risposta porta il segreto di firma, ed è l'unica volta in cui si vede.

Nel corpo

ParametroTipoValori ammessiPredefinitoEsempioChe cosa fa
urlObbligatoriotestolunghezza max. 500https://hooks.example.com/blastackWhere we POST. https only, no credentials, no fragment.
eventsObbligatorioelencoannouncement.published · announcement.pending_review · announcement.acknowledged · person.created · person.deactivated["announcement.published"]Which events this endpoint wants. At least one.
nametestolunghezza 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.
secrettestolunghezza max. 200Your own signing secret, if you would rather set it than have one generated. At least 32 characters.
activebooleanotrueStart delivering straight away.

GET /webhooks/{id}

webhooks:read

Un indirizzo preciso, con il suo stato di salute.

Nel percorso

ParametroTipoValori ammessiPredefinitoEsempioChe cosa fa
idObbligatoriotestoThe webhook endpoint id.

PATCH /webhooks/{id}

webhooks:write

Cambia quello che mandate. Rimettere l'indirizzo su attivo toglie anche la pausa applicata dopo errori ripetuti e azzera il contatore.

Nel percorso

ParametroTipoValori ammessiPredefinitoEsempioChe cosa fa
idObbligatoriotestoThe webhook endpoint id.

Nel corpo

ParametroTipoValori ammessiPredefinitoEsempioChe cosa fa
urltestolunghezza max. 500Where we POST. https only.
eventselencoannouncement.published · announcement.pending_review · announcement.acknowledged · person.created · person.deactivatedWhich events this endpoint wants. At least one.
nametestolunghezza max. 120What it is for.
activebooleanoSwitch delivery on or off. Turning it on clears a pause.
rotate_secretbooleanoGenerate a new signing secret and return it once in this reply.

DELETE /webhooks/{id}

webhooks:write

Lo cancella con il suo storico. Per smettere di ricevere per un po' senza perdere lo storico, meglio disattivarlo.

Nel percorso

ParametroTipoValori ammessiPredefinitoEsempioChe cosa fa
idObbligatoriotestoThe webhook endpoint id.

GET /webhooks/{id}/deliveries

webhooks:read

Tutto quello che abbiamo provato a mandarvi: tentativi, che cosa avete risposto e quando tocca il prossimo. L'identificativo è lo stesso che ha viaggiato nell'intestazione, quindi si incrocia con i vostri registri.

Nel percorso

ParametroTipoValori ammessiPredefinitoEsempioChe cosa fa
idObbligatoriotestoThe webhook endpoint id.

Nella query

ParametroTipoValori ammessiPredefinitoEsempioChe cosa fa
pageinteromin. 112Page to return. The first page is 1, not 0.
per_pageinteromin. 1 · max. 200 · fuori intervallo viene ridotto invece che rifiutato50100How many items per page. Anything above 200 is clamped to 200 rather than rejected: asking for more is a reasonable thing to want.
statustestopending · delivered · given_upOnly deliveries in this state.
eventtestoannouncement.published · announcement.pending_review · announcement.acknowledged · person.created · person.deactivatedOnly deliveries of this event type.
sincedata ISO 8601Only events that happened at or after this instant.

Esempi

Tre cose che una fabbrica automatizza il primo mese

Con la richiesta intera e la risposta intera. Cambiate la chiave e i nomi; il resto funziona così com'è.

Quando la manutenzione chiude l'ordine di fermo

Il gestionale registra un fermo linea e la bacheca lo scopre da sola

È il caso che chiedono sempre. Il vostro sistema sa già che la linea 3 si ferma giovedì; con questa chiamata lo pubblica lui, indirizzato ai reparti interessati e chiedendo la conferma di lettura, senza che nessuno scriva niente due volte.

Richiesta

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": "Fermo della linea 3 giovedì",
       "body": "Giovedì 4 alle 06:00 la linea 3 si ferma per manutenzione programmata. Il turno del mattino entra all'ora di sempre e passa alla linea 2.",
       "audience": {
         "type": "departments",
         "ids": [
           "Manutenzione",
           "Qualità"
         ]
       },
       "requires_acknowledgement": true,
       "notify": true,
       "language": "it"
     }'

Risposta · 201

{
  "id": "6b1f0f1e-0c2a-4c5e-9a3d-2f5b8c7d1e40",
  "title": "Fermo della linea 3 giovedì",
  "body": "Giovedì 4 alle 06:00 la linea 3 si ferma per manutenzione programmata. Il turno del mattino entra all'ora di sempre e passa alla linea 2.",
  "status": "published",
  "kind": "news",
  "language": "it",
  "audience": {
    "type": "departments",
    "ids": [
      "9c1d7e5f-2a3b-4c5d-8e9f-0a1b2c3d4e5f",
      "44ab7e5f-2a3b-4c5d-8e9f-0a1b2c3d4e5f"
    ],
    "names": [
      "Manutenzione",
      "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 destinazione va per nome e non per identificativo, perché il nome è quello che il vostro sistema ha sottomano. Se il nome non esiste, la risposta dice quale era e non pubblica niente: mezza pubblicazione sarebbe peggio.

Quando il gestionale HR segna l'uscita

Qualcuno esce dal gestionale HR e resta fuori lo stesso giorno

Se il vostro sistema parla SCIM, questo accade già da solo e questa chiamata non serve. Se non lo parla — che in una fabbrica è la norma —, con una riga la persona resta disattivata e con le sessioni chiuse all'istante. Il percorso accetta il vostro identificativo, quindi non serve mantenere una tabella di corrispondenze.

Richiesta

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

Risposta · 200

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

Disattiva; non cancella. Ciò che ha pubblicato resta, perché una bacheca piena di buchi non aiuta nessuno. Chiamare due volte non è un errore.

Ogni mattina, o il giorno prima di un audit

Chi ha confermato il protocollo, dentro un foglio di calcolo

Uno scenario di Make o un flusso di n8n che chiede quelli in sospeso e li scrive in un foglio: nome, reparto e se hanno confermato. È il rapporto che chiede un audit, e quello che evita di rincorrere qualcuno per il corridoio.

Richiesta

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

Risposta · 200

{
  "announcement": {
    "id": "6b1f0f1e-0c2a-4c5e-9a3d-2f5b8c7d1e40",
    "title": "Fermo della linea 3 giovedì"
  },
  "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": "Manutenzione",
        "center": "Capannone 2"
      },
      "acknowledged": false,
      "acknowledged_at": null
    }
  ],
  "page": 1,
  "per_page": 200,
  "total": 7
}

Il riepilogo si conta sulla popolazione intera e non sulla pagina né sul filtro, perché il «12 su 30» continui a significare qualcosa. L'ora della conferma è quella della prima volta e non si tocca mai più.

Eventi in uscita

Chiamiamo noi, in meno di un minuto

È quello che rende la cosa davvero collegabile. Senza eventi in uscita, l'attivatore del vostro scenario deve essere «ogni cinque minuti, chiedi», ed è lento, si paga a passaggio e quasi mai trova qualcosa.

EventoQuando parte
announcement.publishedQualcosa è uscito in bacheca, da qualunque strada sia arrivato: il compositore, l'editor completo, questa API, la coda di revisione o una pubblicazione programmata arrivata alla sua ora. Il tipo viaggia dentro, nel caso vi interessino solo le comunicazioni semplici e non i sondaggi o gli eventi.
announcement.pending_reviewUna pubblicazione aspetta l'approvazione. Parte solo nelle aziende che hanno la coda di revisione accesa.
announcement.acknowledgedQualcuno ha confermato una lettura obbligatoria. Un evento per persona, con chi e quando.
person.createdQualcuno è stato creato, non importa da dove: provisioning, codice di accesso, accesso unico, schermata di amministrazione o questa API.
person.deactivatedQualcuno è stato disattivato. Siccome qui non si cancella nessuno, questo è il segnale di uscita.

La busta, uguale per tutti e cinque

{
  "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"
    }
  }
}

Quello che c'è dentro cambia con l'evento; la busta no. L'identificativo non cambia tra un tentativo e l'altro, quindi scartare un doppione è una condizione di una riga dalla vostra parte.

Le intestazioni di ogni invio

IntestazioneA che serve
blastack-eventChe cosa è successo. È il valore su cui si ramifica.
blastack-event-idL'identificativo dell'evento. Non cambia tra un tentativo e l'altro: è quello su cui basarsi per non eseguire due volte la stessa cosa.
blastack-delivery-attemptQuale tentativo è questo, a partire dal primo.
blastack-signatureLa firma. È l'unica cosa che separa un invio nostro da uno inventato da chi scopre il vostro indirizzo.

Verificare la firma

La firma è un HMAC-SHA256 sulla marca temporale, un punto e il corpo grezzo, non interpretato. È lo stesso formato che usano i gestori di pagamento, cioè quello che con ogni probabilità avete già scritto una volta.

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;
}

Confrontate a tempo costante e rifiutate tutto ciò che ha una marca temporale di più di qualche minuto. Senza quella seconda verifica, una copia di un invio vecchio può esservi rispedita per anni e la firma continuerà a risultare valida.

Ritentativi, pausa e perché non arriva niente

  • Va bene qualsiasi risposta 2xx. Non leggiamo il corpo: rispondete in fretta e fate il lavoro dopo, perché dopo dieci secondi rinunciamo e vale come un errore.
  • Sei tentativi con attesa crescente — un minuto, cinque, quindici, un'ora, tre e sei — distribuiti su circa dieci ore e mezza. Copre il rilascio notturno e la manutenzione del fine settimana.
  • Trenta errori di fila mettono in pausa l'indirizzo, e il motivo resta scritto. Si toglie rimettendolo su attivo, cosa che azzera anche il contatore.
  • Chiamiamo solo indirizzi https pubblici. Si verifica al momento della registrazione e di nuovo prima di ogni invio, perché un nome che oggi risolve verso internet pubblico domani può risolvere verso la vostra rete interna.
  • Un indirizzo registrato oggi non riceve quelli di ieri: un abbonamento conta da quando viene creato, perché montare il primo scenario non faccia partire quaranta esecuzioni in una volta.

Errori

Sempre la stessa forma

Ogni errore restituisce lo stesso oggetto, con un codice pensato per scriverci sopra una condizione. I codici non si rinominano mai: si aggiungono. Il messaggio accanto è per chi legge il registro, e quello sì che può cambiare.

{
  "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 parametro sconosciuto viene rifiutato, non ignorato. Un filtro scartato in silenzio vi restituisce più dati di quelli chiesti e niente ve lo dice.

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

CodiceQuando esce
invalid_token401 · La chiave manca, è scritta male o è stata revocata. Quale delle tre, non lo diciamo.
insufficient_scope403 · La chiave è valida ma non ha l'ambito che quella chiamata richiede. La risposta dice quale serviva e quali ha.
module_required403 · L'azienda non ha attivato il modulo di identità aziendale, quello a cui appartiene l'API.
read_only403 · La prova gratuita è finita e l'azienda è in sola lettura. Riguarda solo ciò che scrive.
rate_limited429 · Più richieste del consentito in un minuto. La risposta dice quanti secondi aspettare.
invalid_request400 · Manca un campo, ce n'è uno di troppo o non si capisce. Il messaggio nomina il parametro esatto ed elenca i valori ammessi.
not_found404 · Non c'è niente di vostro con quell'identificativo. È anche ciò che si riceve per qualcosa di un'altra azienda: distinguere i due casi sarebbe un modo per scoprire che cosa esiste altrove.
conflict409 · Va a sbattere contro qualcosa che c'è già: due persone con la stessa posta, due indirizzi di evento uguali. La risposta porta l'identificativo di ciò che c'era, per poter proseguire.
server_error500 · Si è rotto qualcosa dalla nostra parte. Niente dell'errore esce nella risposta; per intero resta nel nostro registro.

Limiti

Quello che conviene sapere prima di scrivere il ciclo

  • Centoventi richieste al minuto per chiave. Ogni risposta porta quante ne restano e fra quanti secondi riparte il contatore; un 429 porta anche quanto aspettare.
  • Gli elenchi arrivano a cinquanta per volta e accettano fino a duecento per pagina. La prima pagina è la 1, non la 0. Chiedere più di duecento viene ridotto invece che rifiutato.
  • Il periodo degli indicatori arriva a trecentosessantacinque giorni e si chiede per parametro. La copertura per pubblicazione è il blocco costoso: si può lasciare fuori se il vostro cruscotto disegna solo le cifre di testa.
  • Venti indirizzi di evento in uscita per azienda. Non è un limite commerciale: ogni evento si accoda una volta per indirizzo, e chi ne ha bisogno di più sta distribuendo nel posto sbagliato.
  • Gli eventi in uscita impiegano fino a un minuto: si rilevano leggendo la base dati e non dal pulsante di pubblicazione, perché il server lento di un'integrazione non possa frenare la bacheca di nessuno.
  • Si annunciano solo le ultime ventiquattro ore. Se la nostra attività a orologio restasse ferma un giorno intero, non vi scarichiamo il trimestre in una volta: le vostre automazioni girerebbero su dati dell'altro ieri come se fossero di adesso.

Quello che non fa

Detto qui perché non lo scopriate a metà strada

Chi deve integrare ha bisogno dei limiti prima di iniziare, non quando ha già montato mezzo scenario. Questo elenco è ciò che uno sviluppatore cercherà senza trovarlo, e si aggiorna quando qualcosa smette di essere vero.

  • Non c'è una schermata per creare chiavi. Oggi si emettono da console con npm run clave:api, e le emettiamo noi. Una schermata onesta avrebbe bisogno dei suoi testi nelle dodici lingue dell'applicazione, e mezza schermata tradotta non si pubblica.
  • Gli eventi in uscita hanno bisogno di una riga di cron sul server. Senza non si rompe niente, ed è proprio questo il problema: tutto il resto continua a funzionare e semplicemente non esce nulla. Si vede nel registro delle consegne, che sarebbe vuoto.
  • Il segreto di firma si mostra una volta sola: quando si crea l'indirizzo o quando lo si ruota. Non si può rileggere, solo ruotare. Conservatelo in quel momento.
  • Ruotare il segreto non ha nessun periodo di grazia. L'invio successivo è già firmato con quello nuovo: cambiatelo prima sul vostro server e chiedete la rotazione dopo.
  • Venti indirizzi di evento in uscita per azienda. Se ve ne servono di più, la distribuzione deve avvenire nel vostro strumento a partire da una sola consegna.
  • Non si arriva alla chat, né ai sondaggi, né agli eventi, né ai riconoscimenti, né agli album. Compaiono nell'elenco delle pubblicazioni e negli eventi in uscita con il loro tipo, ma non si creano né si leggono per conto loro.
  • Non si arriva ai documenti e non si caricano file. Nemmeno immagini dentro una pubblicazione: il corpo è testo semplice.
  • Una pubblicazione già fatta non si modifica né si cancella, e i commenti non si scrivono né si leggono.
  • Non si cercano le persone con una ricerca parziale sulla posta, e nessuno viene davvero cancellato: la cancellazione è una richiesta scritta che gestiamo noi, e anonimizza invece di eliminare.
  • Gli indicatori sono aggregati e non c'è modo di estrarre chi ha letto cosa. L'unico elenco con i nomi è quello delle letture obbligatorie, che esiste per poterlo mostrare a un'ispezione.
  • Non c'è un ambiente di prova separato, né librerie ufficiali per nessun linguaggio, né paginazione a cursore. È JSON su HTTPS e si chiama con quello che avete.

Per le macchine

Se a leggere questo è un assistente

Metà della valutazione d'acquisto oggi consiste nel chiedere a un assistente se questa cosa si collega a qualcosa. Quindi la risposta è scritta per essere leggibile senza account e senza indovinare niente.

  • La specifica OpenAPI 3.1 sta a un indirizzo pubblico e stabile, senza chiave, con l'origine incrociata permessa e senza toccare la base dati nemmeno una volta. Descrive i diciassette endpoint con i loro parametri, i valori ammessi, la forma di ogni risposta e i cinque eventi in uscita.
  • Non è scritta a mano: si genera dallo stesso catalogo con cui ogni endpoint controlla ciò che gli arriva, e le forme delle risposte escono eseguendo lo stesso codice che serve le richieste. Non può dire qualcosa di diverso da quello che fa.
  • Questa pagina ha la stessa struttura nelle sei lingue, con titoli che dicono che cosa c'è sotto e con tabelle vere, non immagini né finte colonne.
  • C'è inoltre un llms.txt con la versione corta, con la sezione di integrazione scritta a parte e con gli indirizzi e gli ambiti in testo semplice.

Se vi manca qualcosa di quell'elenco, ditelo

Quello che viene chiesto di più è la cosa successiva che si scrive. E se qualcosa di questa pagina non torna con quello che risponde il server, è un errore nostro e vogliamo saperlo lo stesso giorno.