/v1 in Power BI. Er behandelt
das Konnektivitätsmuster in Power Query (M), ein Sternschema-Semantikmodell auf Basis von
/v1/activities, inkrementelle Aktualisierung und den Einsatz der Reporting-Preview-Datasets
für Phishing-Ergebnisse pro Person.
Die Beispiele verwenden den US-Produktionshost
(https://api.us-east-1.livingsecurity.ai/v1). Für eine EU-Organisation verwenden Sie
https://api.eu-west-1.livingsecurity.ai/v1 sowohl in Fn_FetchAll als auch
in Fn_GetJson und binden dann die Datenquellen-Anmeldedaten an diesen Host. Siehe
Regionen.
Dieser Leitfaden verwendet gespeicherte Basic-Anmeldedaten mit einem API-Schlüssel. Ein
OAuth-Client ist nicht erforderlich. Informationen zu den Optionen für Anmeldedaten finden Sie unter Authentifizierung,
Informationen zu Zugriff und Einrichtung im Developer Hub.
Wofür dieses Beispiel gedacht ist
Verwenden Sie es, wenn Sie Folgendes benötigen:/v1-Listenendpunkte mit korrekter Cursor-Paginierung und einem Rate-Limit-Retry in ein Power-BI-Dataset laden.- Ein Semantikmodell erstellen, in dem Kennzahlen („aktive Entitäten“, „Aktivitäten pro aktiver Entität“) dimensional berechnet werden, statt aus einer flachen Tabelle gezählt zu werden.
- Eine geplante Power-BI-Aktualisierung von einem vollständigen Durchlauf der gesamten Historie auf ein kleines tägliches Zeitfenster reduzieren, indem die inkrementelle Aktualisierung verwendet wird.
- Die passende Phishing-Granularität wählen: Kampagnensummen (operativ) oder Ergebnisse pro Person und typisierte Ereignisse (Reporting-Preview).
Voraussetzungen
- Ein API-Schlüssel mit den Berechtigungen, die Ihre Abfragen benötigen:
- Operatives Beispiel:
activity:read,entity:readundsimulation:read. - Phishing pro Person über Reporting-Datasets:
reporting:read. Siehe API-Schlüssel.
- Operatives Beispiel:
- Power BI Desktop oder ein Power-BI-/Fabric-Arbeitsbereich, in dem Sie ein Semantikmodell erstellen und die Aktualisierung planen können.
Die passende Granularität wählen
/v1 stellt zwei verwandte Oberflächen für Phishing bereit. Sie sind nicht austauschbar.
Die nachfolgenden Power-BI-Beispielabfragen rufen die operativen Routen auf
(
/v1/simulations, /v1/simulations/{id}/results, /v1/activities,
/v1/entities). Für das Phishing-Reporting pro Person bevorzugen Sie die
unten beschriebene Reporting-Preview-Familie. Ein Schlüssel, dem nur reporting:read gewährt wurde, kann
den operativen Endpunkt /v1/simulation_results nicht aufrufen (die API gibt 403 zurück).
Schwierigkeitsskala
Der Schwierigkeitsgrad von Simulationen ist eine Ganzzahl von 1–5 bei/v1/simulations (difficulty_level),
/v1/simulation_results (difficulty_level), den /v1/activities-Eigenschaften
(difficulty_tier) und /v1/reporting/simulation_events (difficulty_tier).
1 ist am einfachsten und 5 am schwierigsten. Adaptive und progressive Simulationen haben keinen
einzelnen Wert auf Kampagnenebene, daher ist /v1/simulations.difficulty_level null,
während der difficulty_level pro Empfänger in den Ergebnissen dennoch gesetzt sein kann. Um auf
ältere Low/Medium/High-Exporte abzubilden, behandeln Sie 1–2 als Low, 3 als Medium und 4–5 als
High.
Konnektivitätsmuster (Power Query)
Vier Regeln liegen jeder Abfrage im Beispiel zugrunde. Jede davon wird vom Power BI Service erzwungen und ist keine Frage des Stils.Die Basis-URL von Web.Contents statisch halten und auf /v1 enden lassen
Die Basis-URL von Web.Contents statisch halten und auf /v1 enden lassen
Legen Sie alles Dynamische in
RelativePath und Query ab. Das erste Argument von
Web.Contents muss ein Literal-String sein, der mit dem regionalen /v1-Stamm
der Organisation endet:- US:
https://api.us-east-1.livingsecurity.ai/v1 - EU:
https://api.eu-west-1.livingsecurity.ai/v1
"simulations", nicht
"v1/simulations"). Fügen Sie für eine EU-Organisation keinen US-Host ein.Wird das erste Argument durch String-Verkettung gebildet, kann der Power BI Service
die Datenquelle nicht statisch identifizieren, und die geplante Aktualisierung schlägt mit
einem Fehler „dynamische Datenquelle“ fehl, obwohl die Abfrage in Power BI
Desktop funktioniert.Den API-Schlüssel als gespeicherte Basic-Anmeldedaten angeben, nicht im Abfragetext
Den API-Schlüssel als gespeicherte Basic-Anmeldedaten angeben, nicht im Abfragetext
Wenn Power BI für die
/v1-Datenquelle nach Anmeldedaten fragt, wählen Sie
Basic und fügen Sie den API-Schlüssel als Benutzername ein. Tragen Sie einen Platzhalter
wie x in das Feld Passwort ein. Der Power BI Service lehnt ein leeres
Passwort ab, obwohl die API dieses Feld ignoriert. Der Schlüssel als Passwort mit einem
Platzhalter als Benutzernamen funktioniert ebenfalls.Fügen Sie in M keinen Authorization-Header hinzu. Das funktioniert auf Ihrem Desktop, schreibt dann aber
den Schlüssel in die Abfragedatei und steht der geplanten Aktualisierung im Weg.Den Verbindungstest des Anmeldedialogs ausführen lassen
Den Verbindungstest des Anmeldedialogs ausführen lassen
GET /v1 ist authentifiziert: Es gibt mit einem gültigen Schlüssel 200 zurück und ohne
Schlüssel 401. Richten Sie die Datenquelle auf …/v1 aus und überspringen Sie den Test nicht –
ein gültiger Schlüssel wird gespeichert, ein widerrufener oder fehlerhafter schlägt sofort fehl.Ältere Beispiele verwendeten den reinen Host als Datenquelle und wiesen an, den Test
zu überspringen, weil GET / immer 404 zurückgibt. Richten Sie diese Modelle wieder auf …/v1 aus.limit=500 bei jeder Listenabfrage explizit setzen
limit=500 bei jeder Listenabfrage explizit setzen
Die Standardseitengröße bei jedem
/v1-Listenendpunkt beträgt 25. Wird der Standard beibehalten,
vervielfacht sich die Anzahl der Anfragen für dieselben Daten. Abfragewerte müssen Text sein –
limit = "500" in M, nicht limit = 500.Gemeinsame Paginierungsfunktion
Jede Abfrage im Beispiel ruft eine einzelneFn_FetchAll auf, die
next_page_token durchläuft, bis es null ist (siehe
Paginierung). Ihre wichtigsten Eigenschaften:
- Statische
/v1-Basis-URL, dynamischeRelativePathundQuery. Erforderlich für die geplante Aktualisierung und für den Anmeldedaten-Test. ManualStatusHandling = {429}mit begrenztem Retry. Die Funktion liestRetry-After, sofern Power Query es bereitstellt, wartet andernfalls 30 Sekunden und gibt nach 5 aufeinanderfolgenden429-Antworten mit einem expliziten Fehler auf, statt zu schleifen, bis die Aktualisierung in den Timeout läuft.5xxwird bewusst nicht wiederholt – ein Serverfehler soll sichtbar werden und nicht stillschweigend ein unvollständiges Dataset erzeugen.- 60-Sekunden-
Timeout. Seiten antworten in der Regel deutlich unter einer Sekunde, daher bedeutet eine Minute Stille, dass die Anfrage tot ist. Binary.BuffervorJson.Document. Ohne Pufferung fordert die Mashup-Engine den Antwortstrom unter Umständen erneut an, wenn sie ihn mehr als einmal liest.baseQuerywird in jeder Iteration unverändert übergeben. Seitentoken sind undurchsichtige, signierte Cursor, die an Organisation, Anmeldedaten, Vertragsversion sowie den Fingerabdruck von Filtern und Sortierung gebunden sind. Eine Änderung eines Filters während des Durchlaufs wird als ungültiges Token abgelehnt, anstatt auf Seite eins neu zu starten.
Fn_FetchAll.pq — base and call shape
Typisierte Abfragen pro Endpunkt
Jeder Konsument vonFn_FetchAll folgt demselben Muster: den Endpunkt aufrufen,
eine feste Spaltenliste projizieren, den Diskriminator object entfernen und
Zeitstempel als datetimezone typisieren, damit Datumskennzahlen nicht unbemerkt um die
Zeitzone der Aktualisierungskapazität verschoben werden.
Excel
Dasselbe Power Query (M) läuft in Excel unter „Daten abrufen und transformieren“ – es ist dieselbe Engine wie in Power BI Desktop. Verwenden Sie dies, wenn Sie eine Arbeitsblatttabelle statt eines Semantikmodells wünschen. In Excel für Windows (Microsoft 365, Excel 2024, 2021, 2019 oder 2016):- Data → Get Data → From Other Sources → Blank Query.
- Wählen Sie im Power Query Editor Home → Advanced Editor. Fügen Sie zuerst
Fn_FetchAllein und benennen Sie diese Abfrage dann inFn_FetchAllum (Query Settings → Name oder Rechtsklick im Bereich „Queries“ → Rename). - Wiederholen Sie dies für
Fn_GetJsonund anschließend für jede Berichtsabfrage. - Home → Close & Load → Close & Load To… öffnet den Dialog Import Data.
Wählen Sie Only Create Connection für
Fn_FetchAllundFn_GetJson(es sind Funktionen, keine Tabellen). Wählen Sie Table für jede Berichtsabfrage, die Sie auf einem Arbeitsblatt haben möchten. - Wählen Sie bei der ersten Aktualisierung Basic: den API-Schlüssel als User name, einen
Platzhalter wie
xals Password. Excel speichert pro Datenquellen-URL einen Satz Anmeldedaten; spätere Abfragen, die denselben/v1-Host ansprechen, verwenden ihn erneut.
Close & Load To… kann beim ersten Erstellen einer Abfrage in einer
Arbeitsmappe abgeblendet sein. Verwenden Sie Close & Load, wählen Sie dann in Excel Data →
Queries & Connections, klicken Sie mit der rechten Maustaste auf die Abfrage und wählen Sie Load To.
Dieser Weg wird von Microsoft für diesen Fall dokumentiert.
Living-Security-Version aus Power Query bei einer
authentifizierten Quelle nicht senden – dieselbe Einschränkung wie in Power BI. Fixieren Sie das
Dienstkonto oder übergeben Sie api_version im Abfragedatensatz. Siehe
Vertragsversionen und gespeicherte Anmeldedaten.
Fertige Berichtsabfragen (Spaltenzuordnungen und Abweichungen vom Export eines
früheren Anbieters):
Compliance pro Person
Schulungsanmeldungen auf Granularität Person × Zuweisung.
E-Mail-Phishing-Protokoll
Phishing-Interaktionen auf Ereignisebene, letzte 12 Monate.
Anfälligste Benutzer
Zusammenfassung von Klicks, Anmeldedaten und Meldungen pro Person über 12 Monate.
Reporting-Preview-Datasets (Phishing pro Person)
Die Reporting-Preview-Familie stellt Datasets für Phishing pro Person bereit. Sie erfordertreporting:read und Reporting-Zugriff für Ihre Organisation.
Verwenden Sie den folgenden Dataset-Katalog, um Schemas und Datenrichtlinien einzusehen.
Den Live-Katalog abrufen:
simulation_results
- Pfad:
GET /v1/reporting/simulation_results - Granularität: Entität × Simulation
- Filter:
simulation,entity,updated_aftersowielimit/page_token - Wire-Objekt:
reporting.simulation_result - Join-Schlüssel:
entity_id,simulation_id
ReportingSimulationResults.pq (sketch)
updated_after als inklusive untere Wasserzeichengrenze, wenn Sie aktuelle
Partitionen aktualisieren. Veränderliche Ergebnisdimensionen werden unter demselben id an Ort und Stelle neu dargestellt.
simulation_events
- Pfad:
GET /v1/reporting/simulation_events - Granularität: ein typisierter Fakt pro beobachteter Interaktion
- Filter:
simulation,entity,event_type,occurred_aftersowielimit/page_token - Wire-Objekt:
reporting.simulation_event - Ereignistypen: geschlossene öffentliche Token wie
simulation.delivered,simulation.opened,simulation.link_clicked,simulation.credentials_submitted,simulation.reported– keine rohen ClickHouse-phishing.simulation.*-Aktivitätstypen - Gerät:
device_typeist die abgeleitete Klasse (beobachtete Token sind unter anderemdesktop,mobile,tablet,unknown). Roheruser_agentist nicht in/v1enthalten. Die rohe IP ist nie in/v1enthalten (wird nie persistiert; nur gesalzenerip_hash).
ReportingSimulationEvents.pq (sketch)
occurred_after für inkrementelle Ereignisladevorgänge. Fakten sind nur anhängend;
verspätet eintreffende Daten sind neue Zeilen.
entities
- Pfad:
GET /v1/reporting/entities - Granularität: eine aktuelle Zeile pro Entität
- Filter:
type,updated_aftersowielimit/page_token - Wire-Objekt:
reporting.entity - Join-Schlüssel:
id/entity_id(gleicher Wert)
reporting.simulation_results.entity_id = reporting.entities.id.
Der operative Endpunkt GET /v1/entities bleibt bei entity:read und erfordert eine andere
Berechtigung.
ReportingEntities.pq
entity_versions und cohort_memberships
Diese beiden Datasets haben eine benannte Ausnahme, die nur den aktuellen Stand abbildet:Es existiert keine maßgebliche Tabelle mit Versions- oder Mitgliedschaftshistorie. Dieses Dataset bildet die aktuelle Zeile als ein offenes Intervall ab (valid_toist null,is_currentist true).valid_fromist bei Entitätsversionencreated_atoder andernfallsupdated_atund bei Kohortenmitgliedschaften der Beobachtungszeitpunkt der Anfrage. Geschlossene historische Intervalle werden nicht erfunden.
- entity_versions:
GET /v1/reporting/entity_versions. Dieselben Filter wie bei entities.valid_fromistcreated_atoder andernfallsupdated_at. Eine Entität mit beiden Zeitstempeln null wird ausgelassen. - cohort_memberships:
GET /v1/reporting/cohort_memberships. Filter:cohort,entity,updated_after.updated_atist die letzte Aktualisierung der Kohorte, damit die inkrementelle Aktualisierung korrekt bleibt.valid_fromist der Beobachtungszeitpunkt der Anfrage. Verknüpfen Sieentity_idmitreporting.entities.id.
ReportingEntityVersions.pq
ReportingCohortMemberships.pq
Sternschema-Semantikmodell auf /v1/activities
/v1/activities ist der mit Zeitstempeln versehene Ereignisstrom der Organisation. Er hat keine
numerischen Kennzahlen – jede Größe in einem Bericht ist eine Zeilenanzahl –, weshalb
ein Sternschema naheliegt.
Activitiesist der Ereignisfakt in echter Granularität. Eine Zeile pro Aktivität. Teilnehmer werden hier entfernt und als eigene Tabelle neu aufgebaut.ActivityParticipantsexistiert, weil Teilnehmer tatsächlich eine Eins-zu-viele-Beziehung bilden, mit Rollen wieactorundtarget. Ein Abflachen aufActivitieswürde entweder Aktivitätszeilen duplizieren (und damit jede Zählung aufblähen) oder zusätzliche Teilnehmer verwerfen. Die Beziehung zuActivitiesist die einzige bidirektionale Beziehung des Modells, sodass ein Entitäts-Slicer die Faktentabelle erreicht.Entitiesist die Dimension, die Teilnehmer benennt. Teilnehmerzeilen einer Aktivität enthaltenentity_idund eine Rolle, aber keinen Anzeigenamen.Dateswird in M erzeugt (null API-Aufrufe) und als Datumstabelle des Modells markiert. Dadurch sind DAX-Zeitintelligenz-Funktionen (DATESINPERIOD,DATEADD) zulässig. Spalten für Monats- und Wochentagsnamen deklarierensortByColumnauf ihren Zahlen-Pendants, damit Visuals Monate nicht alphabetisch sortieren.
discourageImplicitMeasures): Gesamtzahl der
Aktivitäten, aktive Entitäten, Aktivitäten pro aktiver Entität, Tage mit Aktivität
und ein nachlaufender 7-Tage-Tagesdurchschnitt.
Form der Bridge-Tabelle
ActivityParticipants durchläuft /v1/activities und löst das participants-Array
in eine Zeile pro Teilnehmer auf:
ActivityParticipants.pq
ActivityParticipants durchläuft /v1/activities unabhängig, statt
die Abfrage Activities zu referenzieren. In Power BI rufen zwei Abfragen, die als zwei
Tabellen geladen werden, bei der Aktualisierung jeweils unabhängig Daten ab. Werden sie unabhängig gehalten,
kann der Dienst die Partitionen beider Tabellen parallel aktualisieren.
Inkrementelle Aktualisierung
Beide Tabellen auf Faktenebene (Activities und ActivityParticipants) deklarieren eine
Richtlinie für die inkrementelle Aktualisierung in Power BI: 5 Jahre an jährlichen Partitionen vorhalten,
die letzten 14 Tage bei jeder Aktualisierung erneut importieren.
Der Mechanismus besteht aus einem Paar von DateTime-Parametern, RangeStart und RangeEnd,
die der Power BI Service bei der Aktualisierung pro Partition neu bindet. Jede Faktenabfrage
übernimmt diese Parameter in die API-Filter start_date und end_date,
sodass das Anfragevolumen pro Partition proportional zur Partition ist und
nicht zur gesamten Historie. Die Abfrage weitet das API-Fenster auf jeder Seite um eine Minute aus und wendet die exakte halboffene Grenze [RangeStart, RangeEnd)
lokal erneut an, sodass die Korrektheit der Partition nicht davon abhängt, ob der Server
seine Grenzen inklusiv oder exklusiv behandelt.
Activities.pq — the fold that makes incremental refresh work
Das 14-Tage-Fenster ist bewusst großzügig gewählt. Die Aktivitätsaufnahme erfolgt nicht
ausschließlich anhängend zum aktuellen Zeitpunkt: Backfills von Konnektoren liefern Ereignisse mit zurückliegenden Zeitstempeln.
Ein Fenster von 1–2 Tagen würde diese dauerhaft verpassen.
Das Aktualisierungsfenster in die API hinein ausweiten
GET /v1/activities akzeptiert die Filter start_date und end_date, in die die
Power-BI-Parameter einfließen, und filtert event_ts zwischen den Grenzen.
Entities ist eine Dimension, daher aktualisiert dieses Beispiel sie jedes Mal vollständig
statt inkrementell.
Reporting-Datasets verwenden ihre eigenen Wasserzeichen (updated_after,
occurred_after) anstelle des Datumsfensters der Aktivitäten.
Rate Limits während der Aktualisierung
/v1 erzwingt getrennte Budgets pro Schlüssel und pro IP (siehe
Rate Limits). Beachten Sie 429 + Retry-After;
codieren Sie kein Anfragebudget fest in Ihr Modell. Zwei Eigenschaften von Power-BI-Aktualisierungen
sind relevant:
- Der Durchlauf einer einzelnen Tabelle erfolgt sequenziell. Jede Seitenanfrage benötigt das Token der vorherigen Seite, sodass eine Tabelle unabhängig von der Seitengröße latenzgebunden ist.
- Gleichzeitige Tabellenaktualisierungen vervielfachen sich. Wenn mehrere große Tabellen
parallel aktualisiert werden, wird die Obergrenze erreicht, weshalb der 429-
Retry-Pfad in
Fn_FetchAllwichtig ist. Bevorzugen Sie weniger parallele Tabellen, statt von unbegrenzter Parallelität auszugehen.
Vertragsversionen und gespeicherte Anmeldedaten
/v1 akzeptiert einen Anfrage-Header Living-Security-Version, um eine veröffentlichte
Vertragsversion zu fixieren (siehe API-Schnellstart). Power
Query kann diesen Header nicht senden, wenn die Datenquelle gespeicherte Anmeldedaten verwendet –
nur anonyme Datenquellen erlauben benutzerdefinierte Header. Wird er hinzugefügt, schlägt eine Aktualisierung
fehl mit:
contract_version des
Dienstkontos oder die neueste veröffentlichte Version, wenn keine Fixierung gesetzt ist.
Klären Sie die Vertragsversion des Kontos mit Ihrem API-Administrator, bevor Sie
eine Aktualisierung veröffentlichen. Unterstützte Versionen finden Sie im API-Changelog.
Wenn sich eine Aktualisierung unerwartet verhält, prüfen Sie den
API-Antwort-Header Living-Security-Version, um festzustellen, welcher Vertrag die Anfrage
tatsächlich bedient hat.
Ihr Modell aktualisieren und prüfen
Veröffentlichen Sie das Semantikmodell in Ihrem Power-BI-Arbeitsbereich, binden Sie die gespeicherten Anmeldedaten an die regionale/v1-Quelle und führen Sie eine Aktualisierung aus, bevor Sie einen
Zeitplan aktivieren. Prüfen Sie den Aktualisierungsverlauf auf Fehler oder unvollständige Lesevorgänge.
Vergleichen Sie Zeilenanzahlen mit einem unabhängigen API-Lesevorgang mit denselben Filtern.
Der Paginierungsleitfaden enthält Python- und cURL-Beispiele
zum Lesen eines vollständigen Ergebnissatzes. Eine Aktualisierung, die nur die
erste Seite liest, kann bei einem kleinen Dataset erfolgreich aussehen; vergleichen Sie die Anzahlen, bevor
Sie sich auf den Bericht verlassen.
Modellentscheidungen
- Kampagnensummen und Ergebnisse pro Person haben unterschiedliche Granularität.
SimulationResultsruftGET /v1/simulations/{id}/resultsauf (ein GET pro Durchlauf). Für Phishing pro Person fügen Sie Abfragen fürGET /v1/reporting/simulation_resultsundGET /v1/reporting/simulation_eventshinzu (oder den operativenGET /v1/simulation_results, wenn Sie bereitssimulation:readbesitzen). vectorsbei/v1/simulationswird zu einem kommagetrennten String abgeflacht. Eine Spalte vom Listentyp kann nicht als echte Dimension gefiltert werden. Wenn eine Berichtsseite nach Vektor filtern muss, fügen Sie eine Bridge-Tabelle zwischen Simulation und Vektor hinzu.
Nächste Schritte
Developer Hub
Erstellen Sie ein Dienstkonto und einen API-Schlüssel für Power BI.
API-Schnellstart
Authentifizieren Sie
/v1-Anfragen mit Basic-Authentifizierung.Paginierung
Die Listen-Hülle, Cursor-Token und Filterstabilität über einen Durchlauf hinweg.
Rate Limits
Budgets pro Schlüssel und pro IP, der 429-Vertrag und Hinweise zu Retries.

