Entwickler
Siebzehn Operationen auf zehn Pfaden, fünf ausgehende Ereignisse und eine öffentliche OpenAPI-3.1-Spezifikation, die Make und n8n von allein importieren. Hier steht alles: jeder Parameter einzeln, Beispiele, die so wie sie dastehen funktionieren, und die Liste dessen, was die API nicht kann.
OpenAPI-3.1-Spezifikation, ohne Schlüssel
https://app.blastack.com/api/openapi.json
Wurzel der API
https://app.blastack.com/api/v1
Fügen Sie die erste Adresse in den Importer von n8n oder Make ein, und die Knoten entstehen von selbst. Zapier liest kein OpenAPI: genau deshalb stehen seine Schritte weiter unten getrennt.
Auf einen Blick
Acht Angaben. Damit lässt sich die Anfrage schreiben, ohne weiterzulesen.
| Was | Wert | Hinweis |
|---|---|---|
| Wurzel der API | https://app.blastack.com/api/v1 | Sie liegt in der Anwendung, nicht auf dieser Website. Eine einzige Adresse, und sie ändert sich nicht. |
| Spezifikation | https://app.blastack.com/api/openapi.json | Öffentlich und ohne Schlüssel, damit ein Importer sie lesen kann, bevor es überhaupt Zugangsdaten gibt. |
| Authentifizierung | Authorization: Bearer blsk_<prefix>_<secret> | Im Kopfzeilenfeld, nie in der Adresse. Adressen landen im Protokoll des Servers, in dem des vorgelagerten Proxys und in der Historie dessen, der sie von Hand ausprobiert hat. |
| Format | application/json; charset=utf-8 | JSON hin wie zurück. Kein XML und keine Formulardaten. |
| Grenze | 120 req/min · RateLimit-Remaining | Pro Schlüssel und Minute. Jede Antwort sagt, wie viele übrig sind und wann der Zähler neu beginnt. |
| Seiten | page=1 · per_page=50 · ≤ 200 | Die erste Seite ist die 1, nicht die 0. Mehr als zweihundert wird gekappt statt abgelehnt. |
| Fehler | { error: { status, code, message } } | Immer dasselbe Objekt, mit einem stabilen Code, auf den man eine Bedingung schreiben soll. |
| Testumgebung | — | Gibt es nicht. Gearbeitet wird gegen die Produktion, weshalb es sich lohnt, mit einem Nur-Lese-Schlüssel anzufangen. |
curl https://app.blastack.com/api/v1/people?per_page=1 \
-H "Authorization: Bearer blsk_a1b2c3d4e5f6_YOUR_SECRET"Was es gibt
Alle drei laufen. Was fehlt, steht weiter unten in einem eigenen Abschnitt und wird beim Namen genannt.
Damit Ihr HR-System Personen anlegt, die Abteilung wechselt und deaktiviert, ohne dass es jemand von Hand abtippt. Das ist die Hälfte, auf die es der IT wirklich ankommt: an dem Tag, an dem Sie sich von jemandem trennen, deaktiviert sich das Konto von selbst.
Filter über userName und externalId, Seiten und teilweise Änderung. Abteilung und Arbeitsadresse werden gelesen, wer hier hereinkommt, hat Abteilung und Standort also von Anfang an gesetzt. Der Austritt deaktiviert, er löscht nicht.
Mit dem Firmenkonto aus Entra ID, Google Workspace oder Okta hereinkommen. Das steht neben dem Beitrittscode, über den der Teil der Belegschaft ohne Firmen-E-Mail hereinkommt.
Wird eingerichtet, indem man die Discovery-Adresse des Anbieters einfügt, und vor dem Speichern gegen ihn geprüft. E-Mail-Domänen werden per DNS bestätigt. SAML und LDAP gibt es nicht.
Aus dem Programm heraus veröffentlichen, das ohnehin weiß, dass Linie 3 am Donnerstag stillsteht, wer aus dem HR-System ausscheidet deaktivieren, und von uns angerufen werden, wenn etwas passiert, statt alle fünf Minuten fragen zu müssen.
JSON über HTTPS, ein API-Schlüssel im Kopfzeilenfeld, Bereiche pro Schlüssel, Fehler mit stabilem Code und signierte ausgehende Ereignisse. Das dokumentiert der Rest dieser Seite.
Automatisierung
Die drei baut man nicht gleich auf, und das zu sagen spart den Nachmittag, an dem man es sonst herausfindet. Make und n8n lesen die Spezifikation und richten sich fast von selbst ein; Zapier liest sie nicht, dort wird jeder Aufruf von Hand geschrieben. Alle drei funktionieren; die Arbeit ist nicht dieselbe.
| Werkzeug | Liest es die Spezifikation? | Empfohlener Auslöser |
|---|---|---|
| n8n | Ja, vollständig | Knoten «Webhook» + POST /webhooks |
| Make | Ja, im Editor für eigene Apps | «Custom webhook» + POST /webhooks |
| Zapier | Nein | «Catch Hook» + POST /webhooks |
Der kürzeste der drei Wege. Man legt eine Header-Zugangsdatei an, fügt die Adresse der Spezifikation in den Importer ein, und übrig bleibt ein Knoten pro Operation mit bereits gesetzten Parametern.
Schritte
Zu beachten
Der Webhook-Knoten antwortet mit 200, bevor der restliche Ablauf läuft, und genau das braucht es hier: nach zehn Sekunden geben wir auf, und das zählt als Fehlschlag.
Das allgemeine HTTP-Modul reicht für alles, und wer viele Szenarien bauen will, kann die Spezifikation in den Editor für eigene Apps laden und bekommt ein Modul pro Operation.
Schritte
Zu beachten
Make rechnet pro Operation ab: ein Szenario, das alle fünf Minuten nachfragt, verbrennt achttausend Operationen im Monat, um fast nichts zu finden. Mit dem Webhook ist es eine pro Ereignis.
Zapier importiert kein OpenAPI. Gebaut wird mit den allgemeinen Webhook-Schritten oder als private Integration auf ihrer Entwicklerplattform, wo jeder Endpunkt von Hand deklariert wird.
Schritte
Zu beachten
Ihre abfragenden Auslöser verbrauchen bei jedem Durchgang eine Aufgabe, ob sie etwas finden oder nicht. Der «Catch Hook» verbraucht nur, wenn wirklich etwas passiert ist.
Schlüssel
Heute geben wir sie von Hand aus und sagen Ihnen, welche Bereiche sie tragen. Es gibt keinen Selbstbedienungsbildschirm, und das steht weiter unten bei dem, was fehlt. Jeder Schlüssel hängt an genau einer Firma, und keine Route liest eine Firmenkennung aus der Anfrage: es gibt keine Stelle, an der man sich vertun könnte.
Sagen Sie uns, wofür er ist und was er können muss, und wir geben ihn mit genau diesen Bereichen aus und keinem weiteren. Er wird einmal gezeigt: wir behalten nur eine Prüfsumme, ein verlorener Schlüssel wird also gesperrt und neu ausgegeben.
In der Autorisierungskopfzeile, nie in der Adresse. Adressen landen im Protokoll des Servers, in dem des vorgelagerten Proxys und in der Historie dessen, der sie von Hand ausprobiert hat.
In Ihre Geheimnisverwaltung, nicht ins Repository. Er beginnt mit einem erkennbaren Präfix, gerade damit Secret-Scanner ihn erwischen, falls er entwischt.
Die API gehört zum Modul Unternehmensidentität, demselben, das auch Single Sign-on und die Provisionierung öffnet. Hat die Firma es nicht gebucht, sagt die Antwort das mit diesen Worten und nicht mit einem allgemeinen Fehler.
| Bereich | Was er öffnet |
|---|---|
| people:read | Die Belegschaft lesen sowie die Abteilungen und Standorte, an die sich ein Aushang richten kann. Mehr braucht ein Dashboard nicht. |
| people:write | Personen anlegen, ändern und deaktivieren. Deaktivieren schließt ihre Sitzungen, das kommt also nicht als Zugabe zum Lesen. |
| announcements:read | Lesen, was veröffentlicht wurde, und wer eine Pflichtlektüre bestätigt hat. Getrennt vom Personenbereich: eine Liste von Namen und Positionen ist das Verzeichnis, der Text der Aushänge ist es nicht. |
| announcements:write | Am Schwarzen Brett veröffentlichen. Die Freigabe-Warteschlange der Firma wird eingehalten, ein Schlüssel überspringt also niemandes Freigabeweg. |
| metrics:read | Die zusammengefassten Kennzahlen. Hier wird niemand namentlich genannt. |
| webhooks:read | Die registrierten Adressen und das Zustellprotokoll ansehen. Das beantwortet «warum kommt nichts an», ohne ein Ticket zu öffnen. |
| webhooks:write | Adressen für ausgehende Ereignisse registrieren, ändern und löschen. Der heikelste der Liste: er entscheidet, an welchen Server im Internet wir den Inhalt Ihrer Aushänge schicken. |
Endpunkte
Nach Familien gruppiert. Die Bereichsspalte ist die, auf die es beim Anfordern des Schlüssels ankommt: fehlt er, sagt die Antwort, welcher nötig war und welche Ihrer trägt.
| Methode | Pfad | Bereich | Was er tut |
|---|---|---|---|
| GET | /people | people:read | Die Belegschaft, mit Abteilung, Standort und der Kennung, die jede Person in Ihrem HR-System trägt. Siebzehn Parameter, darunter der Filter auf das Datum der letzten Änderung — der, mit dem man alle Viertelstunde abgleichen kann, ohne alles neu zu holen. |
| GET | /people/{id} | people:read | Eine einzelne Person, gesucht über unsere Kennung oder über Ihre. Damit lässt sich ein Datensatz auffrischen, ohne die ganze Liste durchzugehen. |
| POST | /people | people:write | Legt jemanden an. Für den Fall, dass Ihr HR-System kein SCIM spricht; spricht es SCIM, nehmen Sie besser SCIM, das auch Austritte erledigt. Abteilung und Standort werden über den Namen angegeben und angelegt, falls es sie noch nicht gibt. |
| PATCH | /people/{id} | people:write | Ändert nur die Felder, die Sie schicken. Ein weggelassenes Feld wird nicht angefasst: ein Abgleich, der nur die Position kennt, kann niemandem den Standort löschen. |
| DELETE | /people/{id} | people:write | Deaktiviert; löscht nie. Die Sitzungen werden sofort geschlossen, wer also am Freitag geht, ist am Freitag draußen. Was die Person veröffentlicht hat, bleibt. |
| GET | /audiences | people:read | Die Abteilungen und Standorte, die es gibt, mit der Zahl der Personen in jedem. Von hier kommen die Namen, an die sich ein Aushang richten kann, und der Filter auf leere Gruppen ist der, der eine kaputte Provisionierungszuordnung findet. |
| GET | /announcements | announcements:read | Alles Veröffentlichte, mit den Lesungen und Bestätigungen jedes Stücks. Entwürfe und Abgelehntes sind enthalten, damit ein Dashboard den ganzen Trichter zeichnen kann. |
| GET | /announcements/{id} | announcements:read | Ein einzelner Aushang. Der nächste Schritt nach der Kennung, die eine Veröffentlichung zurückgibt oder ein ausgehendes Ereignis mitbringt. |
| POST | /announcements | announcements:write | Veröffentlicht am Schwarzen Brett. Sie müssen sagen, wer unterschreibt, einen Standardwert gibt es nicht. Darf diese Person nicht ohne Freigabe veröffentlichen, landet der Aushang in der Warteschlange und die Antwort sagt es. |
| GET | /announcements/{id}/acknowledgements | announcements:read | Wer eine Pflichtlektüre bestätigt hat und wer nicht, mit Namen und Uhrzeit. Die einzige namentliche Liste der ganzen API, und sie ist es, weil genau das der Sinn der Pflichtlektüre ist: eine freiwillige, unterschriebene und datierte Handlung, die man einer Prüfung zeigen kann. |
| GET | /metrics | metrics:read | Die heutige Belegschaft, die Zugänge, die Veröffentlichungen und die Reichweite pro Aushang und pro Abteilung. Dieselben Zahlen wie der Auswertungsbildschirm, vom selben Code berechnet. |
| GET | /webhooks | webhooks:read | Ihre registrierten Adressen, jede mit ihrem Zustand: aufeinanderfolgende Fehlschläge, was Ihr Server zuletzt geantwortet hat und, falls wir sie pausiert haben, warum. |
| POST | /webhooks | webhooks:write | Registriert eine Adresse und die Ereignisse, die sie will. Die Antwort bringt das Signaturgeheimnis mit, und das ist das einzige Mal, dass es zu sehen ist. |
| GET | /webhooks/{id} | webhooks:read | Eine einzelne Adresse, mit ihrem Zustand. |
| PATCH | /webhooks/{id} | webhooks:write | Ändert, was Sie schicken. Die Adresse wieder auf aktiv zu setzen hebt auch eine Pause auf, die wir nach wiederholten Fehlschlägen verhängt haben, und setzt den Zähler zurück. |
| DELETE | /webhooks/{id} | webhooks:write | Löscht sie samt Verlauf. Wer eine Weile nichts empfangen will, ohne den Verlauf zu verlieren, schaltet sie besser ab. |
| GET | /webhooks/{id}/deliveries | webhooks:read | Alles, was wir Ihnen zu schicken versucht haben: Versuche, was Sie geantwortet haben und wann der nächste ansteht. Die Kennung ist dieselbe, die in der Kopfzeile mitreiste, sie lässt sich also mit Ihren eigenen Protokollen abgleichen. |
Parameter
Keine Liste hier ist gekürzt: es sind dieselben, die der Server prüft. Ein Parameter, der hier fehlt, existiert nicht, und ihn zu schreiben liefert einen Fehler, der die von diesem Endpunkt akzeptierten aufzählt, statt ihn stillschweigend zu verwerfen.
Die rechte Spalte ist mit Absicht auf Englisch. Sie kommt aus dem Katalog, aus dem auch die Spezifikation erzeugt wird, ist also Wort für Wort das, was n8n und Make in ihren Knoten anzeigen. Sie hier zu übersetzen hieße zwei Fassungen zu haben, die eines Tages Verschiedenes sagen.
people:read
Die Belegschaft, mit Abteilung, Standort und der Kennung, die jede Person in Ihrem HR-System trägt. Siebzehn Parameter, darunter der Filter auf das Datum der letzten Änderung — der, mit dem man alle Viertelstunde abgleichen kann, ohne alles neu zu holen.
| Parameter | Typ | Zulässige Werte | Standard | Beispiel | Was er tut |
|---|---|---|---|---|---|
| page | Ganzzahlmin. 1 | 1 | 2 | Page to return. The first page is 1, not 0. | |
| per_page | Ganzzahlmin. 1 · max. 200 · außerhalb des Bereichs wird gekappt statt abgelehnt | 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 | Text | created_at · updated_at · name · email | created_at | Field to sort by. Defaults to created_at. | |
| order | Text | asc · desc | asc | Sort direction. | |
| fields | Text · mehrere, durch Kommas getrennt | 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 | Text · mehrere, durch Kommas getrennt | active · invited · disabled | active | Only people in these states. Several may be given. | |
| role | Text · mehrere, durch Kommas getrennt | owner · admin · gestor_personas · responsable_local · informatico · editor · revisor · analista · employee | Only people with these roles. Several may be given. | ||
| department | Text · mehrere, durch Kommas getrennt | Maintenance,Quality | Department name, or several separated by commas. Case-insensitive: your directory writing MANTENIMIENTO is not an error. | ||
| center | Text · mehrere, durch Kommas getrennt | Site name, or several separated by commas. Case-insensitive. | |||
| no_department | Wahrheitswert | 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 | Text · mehrere, durch Kommas getrennt | es · ca · en · pt · fr · it · de · sv · nl · pl · ro · cs | Only people who picked this reading language. | ||
| Text | Exact email address, case-insensitive. | ||||
| external_id | Text | Exact external_id, as sent by your HR system over SCIM. | |||
| q | Text | garcia | Free text over name, email and job title. Case-insensitive, matches anywhere in the value. | ||
| updated_since | Datum 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 | Datum ISO 8601 | Only people added at or after this instant. | |||
| created_until | Datum ISO 8601 | Only people added before this instant. |
people:read
Eine einzelne Person, gesucht über unsere Kennung oder über Ihre. Damit lässt sich ein Datensatz auffrischen, ohne die ganze Liste durchzugehen.
| Parameter | Typ | Zulässige Werte | Standard | Beispiel | Was er tut |
|---|---|---|---|---|---|
| idPflicht | Text | 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. |
| Parameter | Typ | Zulässige Werte | Standard | Beispiel | Was er tut |
|---|---|---|---|---|---|
| fields | Text · mehrere, durch Kommas getrennt | 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
Legt jemanden an. Für den Fall, dass Ihr HR-System kein SCIM spricht; spricht es SCIM, nehmen Sie besser SCIM, das auch Austritte erledigt. Abteilung und Standort werden über den Namen angegeben und angelegt, falls es sie noch nicht gibt.
| Parameter | Typ | Zulässige Werte | Standard | Beispiel | Was er tut |
|---|---|---|---|---|---|
| namePflicht | Textmax. Länge 120 | Ana García | Full name, as it should appear on the wall. | ||
| Textmax. Länge 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 | Textmax. Länge 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 | Textmax. Länge 120 | Job title. | |||
| department | Textmax. Länge 80 | Department name. Created if it does not exist. Without one, this person only ever sees company-wide announcements. | |||
| center | Textmax. Länge 80 | Site name. Created if it does not exist. | |||
| role | Text | 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 | Text | 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 | Text | 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
Ändert nur die Felder, die Sie schicken. Ein weggelassenes Feld wird nicht angefasst: ein Abgleich, der nur die Position kennt, kann niemandem den Standort löschen.
| Parameter | Typ | Zulässige Werte | Standard | Beispiel | Was er tut |
|---|---|---|---|---|---|
| idPflicht | Text | 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. |
| Parameter | Typ | Zulässige Werte | Standard | Beispiel | Was er tut |
|---|---|---|---|---|---|
| name | Textmax. Länge 120 | Full name. | |||
| Textmax. Länge 200 | Work email. | ||||
| external_id | Textmax. Länge 200 | The id this person has in your system. | |||
| job_title | Textmax. Länge 120 | Job title. | |||
| department | Textmax. Länge 80 | Department name. Created if it does not exist. | |||
| center | Textmax. Länge 80 | Site name. Created if it does not exist. | |||
| role | Text | admin · gestor_personas · responsable_local · informatico · editor · revisor · analista · employee | What they can do. `owner` cannot be given from the API. | ||
| status | Text | active · invited · disabled | Their state. `disabled` also closes their sessions. | ||
| language | Text | es · ca · en · pt · fr · it · de · sv · nl · pl · ro · cs | Reading language. |
people:write
Deaktiviert; löscht nie. Die Sitzungen werden sofort geschlossen, wer also am Freitag geht, ist am Freitag draußen. Was die Person veröffentlicht hat, bleibt.
| Parameter | Typ | Zulässige Werte | Standard | Beispiel | Was er tut |
|---|---|---|---|---|---|
| idPflicht | Text | 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
Die Abteilungen und Standorte, die es gibt, mit der Zahl der Personen in jedem. Von hier kommen die Namen, an die sich ein Aushang richten kann, und der Filter auf leere Gruppen ist der, der eine kaputte Provisionierungszuordnung findet.
| Parameter | Typ | Zulässige Werte | Standard | Beispiel | Was er tut |
|---|---|---|---|---|---|
| type | Text | all · departments · centers | all | Return only departments, only sites, or both. | |
| q | Text | Free text over the name. Case-insensitive. | |||
| with_people | Wahrheitswert | 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 | Text | name · people | name | Field to sort by. Defaults to name. | |
| order | Text | asc · desc | asc | Sort direction. |
announcements:read
Alles Veröffentlichte, mit den Lesungen und Bestätigungen jedes Stücks. Entwürfe und Abgelehntes sind enthalten, damit ein Dashboard den ganzen Trichter zeichnen kann.
| Parameter | Typ | Zulässige Werte | Standard | Beispiel | Was er tut |
|---|---|---|---|---|---|
| page | Ganzzahlmin. 1 | 1 | 2 | Page to return. The first page is 1, not 0. | |
| per_page | Ganzzahlmin. 1 · max. 200 · außerhalb des Bereichs wird gekappt statt abgelehnt | 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 | Text | published_at · created_at · updated_at · title | published_at | Field to sort by. Defaults to published_at. | |
| order | Text | asc · desc | asc | Sort direction. | |
| fields | Text · mehrere, durch Kommas getrennt | 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 | Text · mehrere, durch Kommas getrennt | 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 | Text | Who signs it: our id, their email or their external_id. Any of the three. | |||
| audience_type | Text | all · departments · centers | Only announcements aimed this way. | ||
| department | Text · mehrere, durch Kommas getrennt | Only announcements aimed at these departments, by name. Several may be given. | |||
| center | Text · mehrere, durch Kommas getrennt | Only announcements aimed at these sites, by name. | |||
| community | Text | Only announcements in this community, by id or by name. | |||
| requires_acknowledgement | Wahrheitswert | Only required reading, or only the rest. This is the filter a compliance report is built on. | |||
| pinned | Wahrheitswert | Only pinned announcements, or only the rest. | |||
| q | Text | Free text over title and body. Case-insensitive. | |||
| published_since | Datum ISO 8601 | Published at or after this instant. | |||
| published_until | Datum ISO 8601 | Published before this instant. | |||
| created_since | Datum ISO 8601 | Written at or after this instant. | |||
| updated_since | Datum ISO 8601 | Changed at or after this instant. |
announcements:read
Ein einzelner Aushang. Der nächste Schritt nach der Kennung, die eine Veröffentlichung zurückgibt oder ein ausgehendes Ereignis mitbringt.
| Parameter | Typ | Zulässige Werte | Standard | Beispiel | Was er tut |
|---|---|---|---|---|---|
| idPflicht | Text | The announcement id. |
| Parameter | Typ | Zulässige Werte | Standard | Beispiel | Was er tut |
|---|---|---|---|---|---|
| fields | Text · mehrere, durch Kommas getrennt | 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
Veröffentlicht am Schwarzen Brett. Sie müssen sagen, wer unterschreibt, einen Standardwert gibt es nicht. Darf diese Person nicht ohne Freigabe veröffentlichen, landet der Aushang in der Warteschlange und die Antwort sagt es.
| Parameter | Typ | Zulässige Werte | Standard | Beispiel | Was er tut |
|---|---|---|---|---|---|
| bodyPflicht | Textmax. Länge 8000 | The text. Plain text; line breaks are kept. | |||
| authorPflicht | Text | EMP-0042 | Who signs it: our id, their email or their external_id. Must be an active person in this company. | ||
| title | Textmax. Länge 160 | Headline. | |||
| audience | Objekt | 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 | Text | all · departments · centers | all | Aim at everyone, at departments or at sites. | |
| audience.ids | Liste | ["Maintenance","Quality"] | Department or site names, or their ids. Required unless type is `all`. | ||
| community | Text | 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 | Text | Which section it belongs to, by id or by name. It must belong to the same community. | |||
| publish_at | Datum 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 | Wahrheitswert | 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 | Wahrheitswert | 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 | Wahrheitswert | true | Whether people can comment on it. | ||
| pinned | Wahrheitswert | false | Keep it at the top of the wall. | ||
| language | Text | 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
Wer eine Pflichtlektüre bestätigt hat und wer nicht, mit Namen und Uhrzeit. Die einzige namentliche Liste der ganzen API, und sie ist es, weil genau das der Sinn der Pflichtlektüre ist: eine freiwillige, unterschriebene und datierte Handlung, die man einer Prüfung zeigen kann.
| Parameter | Typ | Zulässige Werte | Standard | Beispiel | Was er tut |
|---|---|---|---|---|---|
| idPflicht | Text | The announcement id. |
| Parameter | Typ | Zulässige Werte | Standard | Beispiel | Was er tut |
|---|---|---|---|---|---|
| page | Ganzzahlmin. 1 | 1 | 2 | Page to return. The first page is 1, not 0. | |
| per_page | Ganzzahlmin. 1 · max. 200 · außerhalb des Bereichs wird gekappt statt abgelehnt | 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 | Text | all · acknowledged · pending | all | Everyone, only those who confirmed, or only those still pending. | |
| department | Text · mehrere, durch Kommas getrennt | Only people in these departments, by name. | |||
| center | Text · mehrere, durch Kommas getrennt | Only people at these sites, by name. | |||
| sort | Text | name · acknowledged_at | name | Field to sort by. Defaults to name. | |
| order | Text | asc · desc | asc | Sort direction. |
metrics:read
Die heutige Belegschaft, die Zugänge, die Veröffentlichungen und die Reichweite pro Aushang und pro Abteilung. Dieselben Zahlen wie der Auswertungsbildschirm, vom selben Code berechnet.
| Parameter | Typ | Zulässige Werte | Standard | Beispiel | Was er tut |
|---|---|---|---|---|---|
| period_days | Ganzzahlmin. 1 · max. 365 | 30 | 90 | How many days back the period covers. Applies to every figure with a period, including the reach lists. | |
| include | Text · mehrere, durch Kommas getrennt | 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
Ihre registrierten Adressen, jede mit ihrem Zustand: aufeinanderfolgende Fehlschläge, was Ihr Server zuletzt geantwortet hat und, falls wir sie pausiert haben, warum.
| Parameter | Typ | Zulässige Werte | Standard | Beispiel | Was er tut |
|---|---|---|---|---|---|
| page | Ganzzahlmin. 1 | 1 | 2 | Page to return. The first page is 1, not 0. | |
| per_page | Ganzzahlmin. 1 · max. 200 · außerhalb des Bereichs wird gekappt statt abgelehnt | 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 | Text | announcement.published · announcement.pending_review · announcement.acknowledged · person.created · person.deactivated | Only endpoints subscribed to this event. | ||
| active | Wahrheitswert | Only live endpoints, or only the switched-off and paused. |
webhooks:write
Registriert eine Adresse und die Ereignisse, die sie will. Die Antwort bringt das Signaturgeheimnis mit, und das ist das einzige Mal, dass es zu sehen ist.
| Parameter | Typ | Zulässige Werte | Standard | Beispiel | Was er tut |
|---|---|---|---|---|---|
| urlPflicht | Textmax. Länge 500 | https://hooks.example.com/blastack | Where we POST. https only, no credentials, no fragment. | ||
| eventsPflicht | Liste | announcement.published · announcement.pending_review · announcement.acknowledged · person.created · person.deactivated | ["announcement.published"] | Which events this endpoint wants. At least one. | |
| name | Textmax. Länge 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 | Textmax. Länge 200 | Your own signing secret, if you would rather set it than have one generated. At least 32 characters. | |||
| active | Wahrheitswert | true | Start delivering straight away. |
webhooks:read
Eine einzelne Adresse, mit ihrem Zustand.
| Parameter | Typ | Zulässige Werte | Standard | Beispiel | Was er tut |
|---|---|---|---|---|---|
| idPflicht | Text | The webhook endpoint id. |
webhooks:write
Ändert, was Sie schicken. Die Adresse wieder auf aktiv zu setzen hebt auch eine Pause auf, die wir nach wiederholten Fehlschlägen verhängt haben, und setzt den Zähler zurück.
| Parameter | Typ | Zulässige Werte | Standard | Beispiel | Was er tut |
|---|---|---|---|---|---|
| idPflicht | Text | The webhook endpoint id. |
| Parameter | Typ | Zulässige Werte | Standard | Beispiel | Was er tut |
|---|---|---|---|---|---|
| url | Textmax. Länge 500 | Where we POST. https only. | |||
| events | Liste | announcement.published · announcement.pending_review · announcement.acknowledged · person.created · person.deactivated | Which events this endpoint wants. At least one. | ||
| name | Textmax. Länge 120 | What it is for. | |||
| active | Wahrheitswert | Switch delivery on or off. Turning it on clears a pause. | |||
| rotate_secret | Wahrheitswert | Generate a new signing secret and return it once in this reply. |
webhooks:write
Löscht sie samt Verlauf. Wer eine Weile nichts empfangen will, ohne den Verlauf zu verlieren, schaltet sie besser ab.
| Parameter | Typ | Zulässige Werte | Standard | Beispiel | Was er tut |
|---|---|---|---|---|---|
| idPflicht | Text | The webhook endpoint id. |
webhooks:read
Alles, was wir Ihnen zu schicken versucht haben: Versuche, was Sie geantwortet haben und wann der nächste ansteht. Die Kennung ist dieselbe, die in der Kopfzeile mitreiste, sie lässt sich also mit Ihren eigenen Protokollen abgleichen.
| Parameter | Typ | Zulässige Werte | Standard | Beispiel | Was er tut |
|---|---|---|---|---|---|
| idPflicht | Text | The webhook endpoint id. |
| Parameter | Typ | Zulässige Werte | Standard | Beispiel | Was er tut |
|---|---|---|---|---|---|
| page | Ganzzahlmin. 1 | 1 | 2 | Page to return. The first page is 1, not 0. | |
| per_page | Ganzzahlmin. 1 · max. 200 · außerhalb des Bereichs wird gekappt statt abgelehnt | 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 | Text | pending · delivered · given_up | Only deliveries in this state. | ||
| event | Text | announcement.published · announcement.pending_review · announcement.acknowledged · person.created · person.deactivated | Only deliveries of this event type. | ||
| since | Datum ISO 8601 | Only events that happened at or after this instant. |
Beispiele
Mit der vollständigen Anfrage und der vollständigen Antwort. Tauschen Sie Schlüssel und Namen aus; der Rest funktioniert so, wie er dasteht.
Wenn die Instandhaltung den Stillstandsauftrag schließt
Der Fall, nach dem immer gefragt wird. Ihr System weiß längst, dass Linie 3 am Donnerstag stillsteht; mit diesem Aufruf veröffentlicht es das selbst, gerichtet an die betroffenen Abteilungen und mit Bitte um Lesebestätigung, ohne dass jemand irgendetwas zweimal tippt.
Anfrage
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": "Linie 3 steht am Donnerstag still",
"body": "Am Donnerstag, dem 4., steht Linie 3 ab 06:00 Uhr wegen geplanter Instandhaltung still. Die Frühschicht fängt wie immer an und wechselt auf Linie 2.",
"audience": {
"type": "departments",
"ids": [
"Instandhaltung",
"Qualität"
]
},
"requires_acknowledgement": true,
"notify": true,
"language": "de"
}'Antwort · 201
{
"id": "6b1f0f1e-0c2a-4c5e-9a3d-2f5b8c7d1e40",
"title": "Linie 3 steht am Donnerstag still",
"body": "Am Donnerstag, dem 4., steht Linie 3 ab 06:00 Uhr wegen geplanter Instandhaltung still. Die Frühschicht fängt wie immer an und wechselt auf Linie 2.",
"status": "published",
"kind": "news",
"language": "de",
"audience": {
"type": "departments",
"ids": [
"9c1d7e5f-2a3b-4c5d-8e9f-0a1b2c3d4e5f",
"44ab7e5f-2a3b-4c5d-8e9f-0a1b2c3d4e5f"
],
"names": [
"Instandhaltung",
"Qualität"
]
},
"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"
}Das Ziel wird über den Namen angegeben und nicht über eine Kennung, weil der Name das ist, was Ihr System zur Hand hat. Gibt es den Namen nicht, sagt die Antwort welchen, und es wird nichts veröffentlicht: ein halber Aushang wäre schlimmer.
Wenn das HR-System den Austritt setzt
Spricht Ihr System SCIM, passiert das schon von allein und dieser Aufruf erübrigt sich. Spricht es kein SCIM — in einer Fabrik der Normalfall —, genügt eine Zeile, um die Person zu deaktivieren und ihre Sitzungen sofort zu schließen. Der Pfad nimmt Ihre eigene Kennung an, eine Zuordnungstabelle ist also nicht nötig.
Anfrage
curl -X DELETE https://app.blastack.com/api/v1/people/EMP-0042 \
-H "Authorization: Bearer blsk_a1b2c3d4e5f6_YOUR_SECRET"Antwort · 200
{
"id": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c",
"external_id": "EMP-0042",
"email": "ana.garcia@empresa.com",
"name": "Ana García",
"job_title": "Schichtleiterin",
"department": "Instandhaltung",
"center": "Halle 2",
"role": "editor",
"status": "disabled",
"language": null,
"created_at": "2026-02-11T08:14:00.000Z",
"updated_at": "2026-09-01T07:40:22.000Z"
}Es deaktiviert; es löscht nicht. Was die Person veröffentlicht hat, bleibt, denn ein Brett voller Lücken hilft niemandem. Zweimal aufzurufen ist kein Fehler.
Jeden Morgen, oder am Tag vor einer Prüfung
Ein Make-Szenario oder ein n8n-Ablauf, der die Offenen abfragt und in ein Blatt schreibt: Name, Abteilung und ob bestätigt wurde. Das ist der Bericht, den eine Prüfung verlangt, und der, der einem das Hinterherlaufen auf dem Flur erspart.
Anfrage
curl -G https://app.blastack.com/api/v1/announcements/6b1f0f1e-0c2a-4c5e-9a3d-2f5b8c7d1e40/acknowledgements \
--data-urlencode "state=pending" \
--data-urlencode "department=Instandhaltung" \
--data-urlencode "per_page=200" \
-H "Authorization: Bearer blsk_a1b2c3d4e5f6_YOUR_SECRET"Antwort · 200
{
"announcement": {
"id": "6b1f0f1e-0c2a-4c5e-9a3d-2f5b8c7d1e40",
"title": "Linie 3 steht am Donnerstag still"
},
"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": "Instandhaltung",
"center": "Halle 2"
},
"acknowledged": false,
"acknowledged_at": null
}
],
"page": 1,
"per_page": 200,
"total": 7
}Die Zusammenfassung zählt über die ganze Grundgesamtheit und nicht über die Seite oder den Filter, damit das «12 von 30» weiter etwas bedeutet. Die Uhrzeit der Bestätigung ist die des ersten Mals und wird nie wieder angefasst.
Ausgehende Ereignisse
Das ist es, was die Sache wirklich anschlussfähig macht. Ohne ausgehende Ereignisse muss der Auslöser Ihres Szenarios «alle fünf Minuten nachfragen» heißen, und das ist langsam, wird pro Durchgang abgerechnet und findet fast nie etwas.
| Ereignis | Wann es losgeht |
|---|---|
| announcement.published | Etwas ist am Brett erschienen, auf welchem Weg auch immer: der Schnelleditor, der vollständige Editor, diese API, die Freigabe-Warteschlange oder ein geplanter Aushang, der seine Stunde erreicht. Die Art reist mit, falls Sie nur schlichte Aushänge wollen und keine Umfragen oder Veranstaltungen. |
| announcement.pending_review | Ein Aushang wartet auf Freigabe. Geht nur in Firmen los, bei denen die Freigabe-Warteschlange eingeschaltet ist. |
| announcement.acknowledged | Jemand hat eine Pflichtlektüre bestätigt. Ein Ereignis pro Person, mit wer und wann. |
| person.created | Jemand wurde angelegt, gleich auf welchem Weg: Provisionierung, Beitrittscode, Single Sign-on, Verwaltungsbildschirm oder diese API. |
| person.deactivated | Jemand wurde deaktiviert. Da hier niemand gelöscht wird, ist das das Austrittssignal. |
{
"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"
}
}
}Der Inhalt ändert sich mit dem Ereignis; der Umschlag nicht. Die Kennung ändert sich zwischen Wiederholungen nicht, ein Duplikat zu verwerfen ist auf Ihrer Seite also eine einzige Bedingung.
| Kopfzeile | Wofür |
|---|---|
| blastack-event | Was passiert ist. Der Wert, auf den man verzweigt. |
| blastack-event-id | Die Ereigniskennung. Sie ändert sich zwischen Wiederholungen nicht: die, auf die man abstellt, um nie zweimal dasselbe auszuführen. |
| blastack-delivery-attempt | Der wievielte Versuch das ist, beginnend beim ersten. |
| blastack-signature | Die Signatur. Das Einzige, was eine Zustellung von uns von einer unterscheidet, die sich jemand ausgedacht hat, der Ihre Adresse findet. |
Die Signatur ist HMAC-SHA256 über den Zeitstempel, einen Punkt und den rohen, nicht geparsten Rumpf. Dasselbe Format, das die Zahlungsanbieter verwenden, also das, das Sie vermutlich schon einmal geschrieben haben.
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;
}Vergleichen Sie in konstanter Zeit und weisen Sie alles ab, dessen Zeitstempel älter als ein paar Minuten ist. Ohne diese zweite Prüfung kann Ihnen eine Kopie einer alten Zustellung jahrelang erneut geschickt werden, und die Signatur stimmt weiterhin.
Fehler
Jeder Fehler liefert dasselbe Objekt, mit einem Code, auf den man eine Bedingung schreiben soll. Codes werden nie umbenannt: es kommen welche hinzu. Die Meldung daneben ist für den, der das Protokoll liest, und die darf sich ändern.
{
"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"
}Ein unbekannter Parameter wird abgelehnt, nicht ignoriert. Ein stillschweigend verworfener Filter liefert Ihnen mehr Daten, als Sie angefordert haben, und nichts weist Sie darauf hin.
RateLimit-Limit · RateLimit-Remaining · RateLimit-Reset · Retry-After
| Code | Wann er kommt |
|---|---|
| invalid_token | 401 · Der Schlüssel fehlt, ist falsch geschrieben oder wurde gesperrt. Welches der drei, sagen wir nicht. |
| insufficient_scope | 403 · Der Schlüssel ist gültig, trägt aber nicht den Bereich, den dieser Aufruf braucht. Die Antwort sagt, welcher nötig war und welche er hat. |
| module_required | 403 · Die Firma hat das Modul Unternehmensidentität nicht gebucht, zu dem die API gehört. |
| read_only | 403 · Die kostenlose Testphase ist vorbei und die Firma ist im Nur-Lese-Zustand. Betrifft nur, was schreibt. |
| rate_limited | 429 · Mehr Anfragen als erlaubt in einer Minute. Die Antwort sagt, wie viele Sekunden zu warten sind. |
| invalid_request | 400 · Ein Feld fehlt, ist zu viel oder wird nicht verstanden. Die Meldung nennt den genauen Parameter und zählt die zulässigen Werte auf. |
| not_found | 404 · Nichts von Ihnen mit dieser Kennung. Dasselbe bekommt man für etwas, das einer anderen Firma gehört: die beiden zu unterscheiden wäre ein Weg herauszufinden, was anderswo existiert. |
| conflict | 409 · Es kollidiert mit etwas Bestehendem: zwei Personen mit derselben E-Mail, zwei gleiche Ereignisadressen. Die Antwort bringt die Kennung dessen mit, womit es kollidierte, damit man weitermachen kann. |
| server_error | 500 · Bei uns ist etwas kaputtgegangen. Nichts davon steht in der Antwort; vollständig bleibt es in unserem Protokoll. |
Grenzen
Was sie nicht kann
Wer integrieren will, braucht die Grenzen vor dem Anfangen und nicht, wenn schon ein halbes Szenario steht. Diese Liste ist das, was ein Entwickler suchen und nicht finden wird, und sie wird aktualisiert, sobald etwas davon nicht mehr stimmt.
Für Maschinen
Die halbe Kaufprüfung besteht heute darin, dass jemand einen Assistenten fragt, ob sich das an irgendetwas anschließen lässt. Also ist die Antwort so geschrieben, dass sie ohne Konto und ohne Raten lesbar ist.
Was am häufigsten gewünscht wird, wird als Nächstes geschrieben. Und wenn etwas auf dieser Seite nicht zu dem passt, was der Server antwortet, ist das unser Fehler und wir wollen ihn noch am selben Tag erfahren.