Sviluppatori
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.
Specifica OpenAPI 3.1, senza chiave
https://app.blastack.com/api/openapi.json
Radice dell'API
https://app.blastack.com/api/v1
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
Otto dati. Con questi la richiesta si scrive senza leggere oltre.
| Cosa | Valore | Nota |
|---|---|---|
| Radice dell'API | https://app.blastack.com/api/v1 | Sta nell'applicazione, non su questo sito commerciale. Un indirizzo solo, e non cambia. |
| Specifica | https://app.blastack.com/api/openapi.json | Pubblica e senza chiave, perché un importatore possa leggerla prima ancora di avere le credenziali. |
| Autenticazione | Authorization: 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. |
| Formato | application/json; charset=utf-8 | JSON in entrata e in uscita. Niente XML e niente moduli. |
| Limite | 120 req/min · RateLimit-Remaining | Per chiave e al minuto. Ogni risposta dice quante ne restano e quando riparte il contatore. |
| Paginazione | page=1 · per_page=50 · ≤ 200 | La 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'è
Funzionano tutte e tre. Quello che manca sta più sotto, in una sezione sua e chiamato per nome.
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.
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.
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
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.
| Strumento | Legge la specifica? | Attivatore consigliato |
|---|---|---|
| n8n | Sì, per intero | Nodo «Webhook» + POST /webhooks |
| Make | Sì, nell'editor delle app proprie | «Custom webhook» + POST /webhooks |
| Zapier | No | «Catch Hook» + POST /webhooks |
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
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.
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
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 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
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
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.
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.
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.
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.
| Ambito | Che cosa apre |
|---|---|
| people:read | Leggere l'organico e i reparti e le sedi a cui si può indirizzare una comunicazione. È tutto quello che serve a un cruscotto. |
| people:write | Creare, modificare e disattivare persone. Disattivare chiude le loro sessioni, quindi non arriva in regalo con quello di lettura. |
| announcements:read | Leggere 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:write | Pubblicare in bacheca. Rispetta la coda di revisione dell'azienda, quindi una chiave non scavalca il percorso di approvazione di nessuno. |
| metrics:read | Gli indicatori aggregati. Qui non compare nessun nome. |
| webhooks:read | Vedere gli indirizzi registrati e il registro delle consegne. È ciò che risponde a «perché non arriva niente» senza aprire un ticket. |
| webhooks:write | Registrare, 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
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.
| Metodo | Percorso | Ambito | Che cosa fa |
|---|---|---|---|
| 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. |
| 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. |
| 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. |
| 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. |
| 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. |
| 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. |
| 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. |
| GET | /announcements/{id} | announcements:read | Una pubblicazione precisa. È il passo successivo all'identificativo restituito da una pubblicazione o portato da un evento in uscita. |
| 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. |
| 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. |
| 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. |
| 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é. |
| 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. |
| GET | /webhooks/{id} | webhooks:read | Un indirizzo preciso, con il suo stato di salute. |
| 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. |
| DELETE | /webhooks/{id} | webhooks:write | Lo cancella con il suo storico. Per smettere di ricevere per un po' senza perdere lo storico, meglio disattivarlo. |
| 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. |
Parametri
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.
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.
| Parametro | Tipo | Valori ammessi | Predefinito | Esempio | Che cosa fa |
|---|---|---|---|---|---|
| page | interomin. 1 | 1 | 2 | Page to return. The first page is 1, not 0. | |
| per_page | interomin. 1 · max. 200 · fuori intervallo viene ridotto invece che rifiutato | 50 | 100 | How many items per page. Anything above 200 is clamped to 200 rather than rejected: asking for more is a reasonable thing to want. | |
| sort | testo | created_at · updated_at · name · email | created_at | Field to sort by. Defaults to created_at. | |
| order | testo | asc · desc | asc | Sort direction. | |
| fields | testo · più valori separati da virgole | external_id · email · name · job_title · department · center · role · status · language · created_at · updated_at | external_id,department,status | Comma-separated list of fields to return. `id` is always included. Use it to avoid pulling personal data you do not need. | |
| status | testo · più valori separati da virgole | active · invited · disabled | active | Only people in these states. Several may be given. | |
| role | testo · più valori separati da virgole | owner · admin · gestor_personas · responsable_local · informatico · editor · revisor · analista · employee | Only people with these roles. Several may be given. | ||
| department | testo · più valori separati da virgole | Maintenance,Quality | Department name, or several separated by commas. Case-insensitive: your directory writing MANTENIMIENTO is not an error. | ||
| center | testo · più valori separati da virgole | Site name, or several separated by commas. Case-insensitive. | |||
| no_department | booleano | Only 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. | |||
| language | testo · più valori separati da virgole | es · ca · en · pt · fr · it · de · sv · nl · pl · ro · cs | Only people who picked this reading language. | ||
| testo | Exact email address, case-insensitive. | ||||
| external_id | testo | Exact external_id, as sent by your HR system over SCIM. | |||
| q | testo | garcia | Free text over name, email and job title. Case-insensitive, matches anywhere in the value. | ||
| updated_since | data ISO 8601 | 2026-08-01T00:00:00Z | Only 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_since | data ISO 8601 | Only people added at or after this instant. | |||
| created_until | data ISO 8601 | Only people added before this instant. |
people:read
Una persona precisa, cercata con il nostro identificativo o con il vostro. Serve per aggiornare una scheda senza percorrere tutto l'elenco.
| Parametro | Tipo | Valori ammessi | Predefinito | Esempio | Che cosa fa |
|---|---|---|---|---|---|
| idObbligatorio | testo | a3f1… | 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. |
| Parametro | Tipo | Valori ammessi | Predefinito | Esempio | Che cosa fa |
|---|---|---|---|---|---|
| fields | testo · più valori separati da virgole | external_id · email · name · job_title · department · center · role · status · language · created_at · updated_at | external_id,department,status | Comma-separated list of fields to return. `id` is always included. Use it to avoid pulling personal data you do not need. |
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.
| Parametro | Tipo | Valori ammessi | Predefinito | Esempio | Che cosa fa |
|---|---|---|---|---|---|
| nameObbligatorio | testolunghezza max. 120 | Ana García | Full name, as it should appear on the wall. | ||
| testolunghezza max. 200 | Work 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_id | testolunghezza max. 200 | EMP-0042 | The id this person has in your system. Store it and you can cross both lists later without matching names. | ||
| job_title | testolunghezza max. 120 | Job title. | |||
| department | testolunghezza max. 80 | Department name. Created if it does not exist. Without one, this person only ever sees company-wide announcements. | |||
| center | testolunghezza max. 80 | Site name. Created if it does not exist. | |||
| role | testo | admin · gestor_personas · responsable_local · informatico · editor · revisor · analista · employee | employee | What 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. | |
| status | testo | active · invited · disabled | active | `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. | |
| language | testo | es · ca · en · pt · fr · it · de · sv · nl · pl · ro · cs | Reading language. Leave it out and they read in the company's, which is what you want unless you actually know. |
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.
| Parametro | Tipo | Valori ammessi | Predefinito | Esempio | Che cosa fa |
|---|---|---|---|---|---|
| idObbligatorio | testo | a3f1… | 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. |
| Parametro | Tipo | Valori ammessi | Predefinito | Esempio | Che cosa fa |
|---|---|---|---|---|---|
| name | testolunghezza max. 120 | Full name. | |||
| testolunghezza max. 200 | Work email. | ||||
| external_id | testolunghezza max. 200 | The id this person has in your system. | |||
| job_title | testolunghezza max. 120 | Job title. | |||
| department | testolunghezza max. 80 | Department name. Created if it does not exist. | |||
| center | testolunghezza max. 80 | Site name. Created if it does not exist. | |||
| role | testo | admin · gestor_personas · responsable_local · informatico · editor · revisor · analista · employee | What they can do. `owner` cannot be given from the API. | ||
| status | testo | active · invited · disabled | Their state. `disabled` also closes their sessions. | ||
| language | testo | es · ca · en · pt · fr · it · de · sv · nl · pl · ro · cs | Reading language. |
people:write
Disattiva; non cancella mai. Le sessioni si chiudono subito, quindi chi esce di venerdì è fuori quel venerdì. Ciò che ha pubblicato resta.
| Parametro | Tipo | Valori ammessi | Predefinito | Esempio | Che cosa fa |
|---|---|---|---|---|---|
| idObbligatorio | testo | a3f1… | 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. |
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.
| Parametro | Tipo | Valori ammessi | Predefinito | Esempio | Che cosa fa |
|---|---|---|---|---|---|
| type | testo | all · departments · centers | all | Return only departments, only sites, or both. | |
| q | testo | Free text over the name. Case-insensitive. | |||
| with_people | booleano | Only 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. | |||
| sort | testo | name · people | name | Field to sort by. Defaults to name. | |
| order | testo | asc · desc | asc | Sort direction. |
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.
| Parametro | Tipo | Valori ammessi | Predefinito | Esempio | Che cosa fa |
|---|---|---|---|---|---|
| page | interomin. 1 | 1 | 2 | Page to return. The first page is 1, not 0. | |
| per_page | interomin. 1 · max. 200 · fuori intervallo viene ridotto invece che rifiutato | 50 | 100 | How many items per page. Anything above 200 is clamped to 200 rather than rejected: asking for more is a reasonable thing to want. | |
| sort | testo | published_at · created_at · updated_at · title | published_at | Field to sort by. Defaults to published_at. | |
| order | testo | asc · desc | asc | Sort direction. | |
| fields | testo · più valori separati da virgole | title · body · status · kind · language · audience · community · section · author · notify · comments_enabled · pinned · acknowledgements · reads · published_at · created_at · updated_at · url | external_id,department,status | Comma-separated list of fields to return. `id` is always included. Use it to avoid pulling personal data you do not need. | |
| status | testo · più valori separati da virgole | draft · pending_review · published · rejected · scheduled · archived | published,scheduled | Only these states. Several may be given. `scheduled` means it is written and waiting for its hour. | |
| author | testo | Who signs it: our id, their email or their external_id. Any of the three. | |||
| audience_type | testo | all · departments · centers | Only announcements aimed this way. | ||
| department | testo · più valori separati da virgole | Only announcements aimed at these departments, by name. Several may be given. | |||
| center | testo · più valori separati da virgole | Only announcements aimed at these sites, by name. | |||
| community | testo | Only announcements in this community, by id or by name. | |||
| requires_acknowledgement | booleano | Only required reading, or only the rest. This is the filter a compliance report is built on. | |||
| pinned | booleano | Only pinned announcements, or only the rest. | |||
| q | testo | Free text over title and body. Case-insensitive. | |||
| published_since | data ISO 8601 | Published at or after this instant. | |||
| published_until | data ISO 8601 | Published before this instant. | |||
| created_since | data ISO 8601 | Written at or after this instant. | |||
| updated_since | data ISO 8601 | Changed at or after this instant. |
announcements:read
Una pubblicazione precisa. È il passo successivo all'identificativo restituito da una pubblicazione o portato da un evento in uscita.
| Parametro | Tipo | Valori ammessi | Predefinito | Esempio | Che cosa fa |
|---|---|---|---|---|---|
| idObbligatorio | testo | The announcement id. |
| Parametro | Tipo | Valori ammessi | Predefinito | Esempio | Che cosa fa |
|---|---|---|---|---|---|
| fields | testo · più valori separati da virgole | title · body · status · kind · language · audience · community · section · author · notify · comments_enabled · pinned · acknowledgements · reads · published_at · created_at · updated_at · url | external_id,department,status | Comma-separated list of fields to return. `id` is always included. Use it to avoid pulling personal data you do not need. |
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.
| Parametro | Tipo | Valori ammessi | Predefinito | Esempio | Che cosa fa |
|---|---|---|---|---|---|
| bodyObbligatorio | testolunghezza max. 8000 | The text. Plain text; line breaks are kept. | |||
| authorObbligatorio | testo | EMP-0042 | Who signs it: our id, their email or their external_id. Must be an active person in this company. | ||
| title | testolunghezza max. 160 | Headline. | |||
| audience | oggetto | Who 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.type | testo | all · departments · centers | all | Aim at everyone, at departments or at sites. | |
| audience.ids | elenco | ["Maintenance","Quality"] | Department or site names, or their ids. Required unless type is `all`. | ||
| community | testo | Which 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. | |||
| section | testo | Which section it belongs to, by id or by name. It must belong to the same community. | |||
| publish_at | data ISO 8601 | 2026-09-01T06:00:00Z | Publish 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_acknowledgement | booleano | false | Required 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. | ||
| notify | booleano | true | Whether 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_enabled | booleano | true | Whether people can comment on it. | ||
| pinned | booleano | false | Keep it at the top of the wall. | ||
| language | testo | es · ca · en · pt · fr · it · de · sv · nl · pl · ro · cs | What 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. |
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.
| Parametro | Tipo | Valori ammessi | Predefinito | Esempio | Che cosa fa |
|---|---|---|---|---|---|
| idObbligatorio | testo | The announcement id. |
| Parametro | Tipo | Valori ammessi | Predefinito | Esempio | Che cosa fa |
|---|---|---|---|---|---|
| page | interomin. 1 | 1 | 2 | Page to return. The first page is 1, not 0. | |
| per_page | interomin. 1 · max. 200 · fuori intervallo viene ridotto invece che rifiutato | 50 | 100 | How many items per page. Anything above 200 is clamped to 200 rather than rejected: asking for more is a reasonable thing to want. | |
| state | testo | all · acknowledged · pending | all | Everyone, only those who confirmed, or only those still pending. | |
| department | testo · più valori separati da virgole | Only people in these departments, by name. | |||
| center | testo · più valori separati da virgole | Only people at these sites, by name. | |||
| sort | testo | name · acknowledged_at | name | Field to sort by. Defaults to name. | |
| order | testo | asc · desc | asc | Sort direction. |
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.
| Parametro | Tipo | Valori ammessi | Predefinito | Esempio | Che cosa fa |
|---|---|---|---|---|---|
| period_days | interomin. 1 · max. 365 | 30 | 90 | How many days back the period covers. Applies to every figure with a period, including the reach lists. | |
| include | testo · più valori separati da virgole | workforce · announcements · reach_by_announcement · reach_by_department | workforce,announcements | Which 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. |
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é.
| Parametro | Tipo | Valori ammessi | Predefinito | Esempio | Che cosa fa |
|---|---|---|---|---|---|
| page | interomin. 1 | 1 | 2 | Page to return. The first page is 1, not 0. | |
| per_page | interomin. 1 · max. 200 · fuori intervallo viene ridotto invece che rifiutato | 50 | 100 | How many items per page. Anything above 200 is clamped to 200 rather than rejected: asking for more is a reasonable thing to want. | |
| event | testo | announcement.published · announcement.pending_review · announcement.acknowledged · person.created · person.deactivated | Only endpoints subscribed to this event. | ||
| active | booleano | Only live endpoints, or only the switched-off and paused. |
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.
| Parametro | Tipo | Valori ammessi | Predefinito | Esempio | Che cosa fa |
|---|---|---|---|---|---|
| urlObbligatorio | testolunghezza max. 500 | https://hooks.example.com/blastack | Where we POST. https only, no credentials, no fragment. | ||
| eventsObbligatorio | elenco | announcement.published · announcement.pending_review · announcement.acknowledged · person.created · person.deactivated | ["announcement.published"] | Which events this endpoint wants. At least one. | |
| name | testolunghezza max. 120 | Zapier · switchboard | What it is for, in your words. It is the only thing that lets you delete the right one six months from now. | ||
| secret | testolunghezza max. 200 | Your own signing secret, if you would rather set it than have one generated. At least 32 characters. | |||
| active | booleano | true | Start delivering straight away. |
webhooks:read
Un indirizzo preciso, con il suo stato di salute.
| Parametro | Tipo | Valori ammessi | Predefinito | Esempio | Che cosa fa |
|---|---|---|---|---|---|
| idObbligatorio | testo | The webhook endpoint id. |
webhooks:write
Cambia quello che mandate. Rimettere l'indirizzo su attivo toglie anche la pausa applicata dopo errori ripetuti e azzera il contatore.
| Parametro | Tipo | Valori ammessi | Predefinito | Esempio | Che cosa fa |
|---|---|---|---|---|---|
| idObbligatorio | testo | The webhook endpoint id. |
| Parametro | Tipo | Valori ammessi | Predefinito | Esempio | Che cosa fa |
|---|---|---|---|---|---|
| url | testolunghezza max. 500 | Where we POST. https only. | |||
| events | elenco | announcement.published · announcement.pending_review · announcement.acknowledged · person.created · person.deactivated | Which events this endpoint wants. At least one. | ||
| name | testolunghezza max. 120 | What it is for. | |||
| active | booleano | Switch delivery on or off. Turning it on clears a pause. | |||
| rotate_secret | booleano | Generate a new signing secret and return it once in this reply. |
webhooks:write
Lo cancella con il suo storico. Per smettere di ricevere per un po' senza perdere lo storico, meglio disattivarlo.
| Parametro | Tipo | Valori ammessi | Predefinito | Esempio | Che cosa fa |
|---|---|---|---|---|---|
| idObbligatorio | testo | The webhook endpoint id. |
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.
| Parametro | Tipo | Valori ammessi | Predefinito | Esempio | Che cosa fa |
|---|---|---|---|---|---|
| idObbligatorio | testo | The webhook endpoint id. |
| Parametro | Tipo | Valori ammessi | Predefinito | Esempio | Che cosa fa |
|---|---|---|---|---|---|
| page | interomin. 1 | 1 | 2 | Page to return. The first page is 1, not 0. | |
| per_page | interomin. 1 · max. 200 · fuori intervallo viene ridotto invece che rifiutato | 50 | 100 | How many items per page. Anything above 200 is clamped to 200 rather than rejected: asking for more is a reasonable thing to want. | |
| status | testo | pending · delivered · given_up | Only deliveries in this state. | ||
| event | testo | announcement.published · announcement.pending_review · announcement.acknowledged · person.created · person.deactivated | Only deliveries of this event type. | ||
| since | data ISO 8601 | Only events that happened at or after this instant. |
Esempi
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 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
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
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
È 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.
| Evento | Quando parte |
|---|---|
| announcement.published | Qualcosa è 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_review | Una pubblicazione aspetta l'approvazione. Parte solo nelle aziende che hanno la coda di revisione accesa. |
| announcement.acknowledged | Qualcuno ha confermato una lettura obbligatoria. Un evento per persona, con chi e quando. |
| person.created | Qualcuno è stato creato, non importa da dove: provisioning, codice di accesso, accesso unico, schermata di amministrazione o questa API. |
| person.deactivated | Qualcuno è stato disattivato. Siccome qui non si cancella nessuno, questo è il segnale di uscita. |
{
"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.
| Intestazione | A che serve |
|---|---|
| blastack-event | Che cosa è successo. È il valore su cui si ramifica. |
| blastack-event-id | L'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-attempt | Quale tentativo è questo, a partire dal primo. |
| blastack-signature | La firma. È l'unica cosa che separa un invio nostro da uno inventato da chi scopre il vostro indirizzo. |
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.
Errori
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
| Codice | Quando esce |
|---|---|
| invalid_token | 401 · La chiave manca, è scritta male o è stata revocata. Quale delle tre, non lo diciamo. |
| insufficient_scope | 403 · La chiave è valida ma non ha l'ambito che quella chiamata richiede. La risposta dice quale serviva e quali ha. |
| module_required | 403 · L'azienda non ha attivato il modulo di identità aziendale, quello a cui appartiene l'API. |
| read_only | 403 · La prova gratuita è finita e l'azienda è in sola lettura. Riguarda solo ciò che scrive. |
| rate_limited | 429 · Più richieste del consentito in un minuto. La risposta dice quanti secondi aspettare. |
| invalid_request | 400 · Manca un campo, ce n'è uno di troppo o non si capisce. Il messaggio nomina il parametro esatto ed elenca i valori ammessi. |
| not_found | 404 · 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. |
| conflict | 409 · 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_error | 500 · Si è rotto qualcosa dalla nostra parte. Niente dell'errore esce nella risposta; per intero resta nel nostro registro. |
Limiti
Quello che non fa
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.
Per le macchine
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.
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.