Skip to main content
Questa guida è un esempio completo di lettura di /v1 in Power BI. Illustra il pattern di connettività Power Query (M), un modello semantico a schema a stella costruito su /v1/activities, l’aggiornamento incrementale e i casi in cui utilizzare i dataset di anteprima reporting per i risultati di phishing per singola persona. Gli esempi utilizzano l’host di produzione per gli Stati Uniti (https://api.us-east-1.livingsecurity.ai/v1). Per un’organizzazione europea, utilizzare https://api.eu-west-1.livingsecurity.ai/v1 sia in Fn_FetchAll sia in Fn_GetJson, quindi associare la credenziale dell’origine dati a tale host. Vedere Regioni. Questa guida utilizza credenziali Basic memorizzate con una chiave API. Non è necessario un client OAuth. Per le opzioni relative alle credenziali, vedere Autenticazione; per l’accesso e la configurazione, vedere Developer Hub.

A cosa serve questo esempio

Utilizzarlo quando è necessario:
  • Caricare gli endpoint di elenco /v1 in un dataset di Power BI con paginazione a cursore corretta e un nuovo tentativo in caso di rate limit.
  • Creare un modello semantico in cui le misure (“entità attive”, “attività per entità attiva”) siano dimensionali anziché calcolate a partire da una tabella piatta.
  • Ridurre l’aggiornamento pianificato di Power BI da una scansione completa dello storico a una piccola finestra giornaliera mediante l’aggiornamento incrementale.
  • Scegliere la granularità corretta per il phishing: totali delle campagne (operativi) oppure risultati per singola persona ed eventi tipizzati (anteprima reporting).

Prerequisiti

  • Una chiave API con le autorizzazioni necessarie per le query:
    • Esempio operativo: activity:read, entity:read e simulation:read.
    • Phishing per singola persona tramite dataset di reporting: reporting:read. Vedere Chiavi API.
  • Power BI Desktop, oppure un workspace Power BI / Fabric in cui sia possibile creare un modello semantico e pianificare l’aggiornamento.

Scegliere la granularità corretta

/v1 espone due superfici correlate per il phishing. Non sono intercambiabili. Le query di esempio di Power BI riportate di seguito richiamano le route operative (/v1/simulations, /v1/simulations/{id}/results, /v1/activities, /v1/entities). Per il reporting del phishing per singola persona, si consiglia la famiglia di anteprima reporting descritta più avanti. Una chiave con la sola autorizzazione reporting:read non può richiamare /v1/simulation_results operativo (l’API restituisce 403).

Scala di difficoltà

La difficoltà della simulazione è un numero intero da 1 a 5 nelle proprietà /v1/simulations (difficulty_level), /v1/simulation_results (difficulty_level), /v1/activities (difficulty_tier) e /v1/reporting/simulation_events (difficulty_tier). 1 è il livello più facile e 5 il più difficile. Le simulazioni adattive e progressive non hanno un singolo valore a livello di campagna, quindi /v1/simulations.difficulty_level è null, mentre difficulty_level per singolo destinatario nei risultati può comunque essere impostato. Per mappare i valori sulle esportazioni legacy basso/medio/alto, considerare 1–2 come basso, 3 come medio e 4–5 come alto.
Non creare nuove integrazioni BI basate su chiamate di rete non documentate della Dashboard o sulla panoramica legacy curata della Public API /api/v1. Autenticarsi sull’host /v1 regionale dell’organizzazione con una chiave API di Developer Hub. Vedere Regioni.

Pattern di connettività (Power Query)

Quattro regole sono alla base di ogni query dell’esempio. Ciascuna è imposta dal servizio Power BI e non è una semplice preferenza di stile.
Inserire tutto ciò che è dinamico in RelativePath e Query. Il primo argomento di Web.Contents deve essere una stringa letterale che termina alla radice /v1 regionale dell’organizzazione:
  • US: https://api.us-east-1.livingsecurity.ai/v1
  • EU: https://api.eu-west-1.livingsecurity.ai/v1
I chiamanti passano quindi solo la risorsa ("simulations", non "v1/simulations"). Non inserire un host US per un’organizzazione europea.Se il primo argomento viene costruito tramite concatenazione di stringhe, il servizio Power BI non riesce a identificare staticamente l’origine dati e l’aggiornamento pianificato non riesce con un errore di “origine dati dinamica”, anche se la query funziona in Power BI Desktop.
Quando Power BI richiede le credenziali per l’origine dati /v1, scegliere Basic e incollare la chiave API come nome utente. Inserire un segnaposto, ad esempio x, nel campo password. Il servizio Power BI rifiuta una password vuota anche se l’API ignora quel campo. Funziona anche l’uso della chiave come password con un nome utente segnaposto.Non aggiungere un’intestazione Authorization in M. Funziona sul desktop, ma incorpora la chiave nel file della query e ostacola l’aggiornamento pianificato.
GET /v1 è autenticato: restituisce 200 con una chiave valida e 401 senza. Puntare l’origine dati a …/v1 e non saltare il test: una chiave corretta viene salvata, una chiave revocata o malformata non riesce immediatamente.I vecchi esempi utilizzavano l’host semplice come origine dati e suggerivano di saltare il test perché GET / restituisce sempre 404. Riassegnare tali modelli a …/v1.
La dimensione di pagina predefinita di ogni endpoint di elenco /v1 è 25. Lasciarla al valore predefinito moltiplica il numero di richieste a parità di dati. I valori della query devono essere testo: limit = "500" in M, non limit = 500.

Funzione di paginazione condivisa

Ogni query dell’esempio richiama un’unica Fn_FetchAll che scorre next_page_token finché non è null (vedere paginazione). Le sue proprietà principali:
  • URL di base /v1 statico, RelativePath e Query dinamici. Necessario per l’aggiornamento pianificato e per il test delle credenziali.
  • ManualStatusHandling = {429} con un nuovo tentativo limitato. La funzione legge Retry-After quando Power Query lo espone, altrimenti attende 30 secondi e si arrende dopo 5 risposte 429 consecutive con un errore esplicito, anziché continuare a ripetere fino allo scadere del tempo dell’aggiornamento. 5xx volutamente non viene ritentato: un errore del server deve emergere e non produrre silenziosamente un dataset parziale.
  • Timeout di 60 secondi. Le pagine rispondono in genere in molto meno di un secondo, quindi un minuto di silenzio significa che la richiesta è bloccata.
  • Binary.Buffer prima di Json.Document. Senza il buffering, il motore mashup potrebbe richiedere nuovamente il flusso di risposta se lo legge più di una volta.
  • baseQuery viene passato invariato a ogni iterazione. I token di pagina sono cursori opachi e firmati, associati all’organizzazione, alla credenziale, alla versione del contratto e all’impronta di filtri e ordinamento. La modifica di un filtro durante la scansione viene rifiutata come token non valido e non riparte dalla prima pagina.
Fn_FetchAll.pq — base and call shape

Query tipizzate per endpoint

Ogni consumer di Fn_FetchAll segue la stessa struttura: richiama l’endpoint, proietta un elenco fisso di colonne, elimina il discriminatore object e tipizza i timestamp come datetimezone in modo che le misure sulle date non subiscano spostamenti silenziosi dovuti al fuso orario della capacità di aggiornamento.
Un elenco esplicito di colonne su Table.FromRecords mantiene stabile lo schema quando un endpoint restituisce zero righe. Un semplice Table.FromRecords({}) produce una tabella senza colonne e tutti i passaggi successivi non riescono per i campi mancanti.

Excel

Lo stesso Power Query (M) funziona in Get & Transform di Excel: è lo stesso motore di Power BI Desktop. Utilizzarlo quando si desidera una tabella in un foglio di lavoro anziché un modello semantico. In Excel per Windows (Microsoft 365, Excel 2024, 2021, 2019 o 2016):
  1. Data → Get Data → From Other Sources → Blank Query.
  2. Nel Power Query Editor, Home → Editor avanzato. Incollare prima Fn_FetchAll, quindi rinominare la query Fn_FetchAll (Impostazioni query → Nome, oppure clic con il pulsante destro nel riquadro Query → Rename).
  3. Ripetere l’operazione per Fn_GetJson, quindi per ogni query di report.
  4. Home → Close & Load → Close & Load To… apre la finestra di dialogo Import Data. Scegliere Only Create Connection per Fn_FetchAll e Fn_GetJson (sono funzioni, non tabelle). Scegliere Table per ogni query di report che si desidera visualizzare in un foglio di lavoro.
  5. Al primo aggiornamento, scegliere Basic: la chiave API come User name e un segnaposto, ad esempio x, come Password. Excel memorizza una credenziale per ogni URL di origine dati; le query successive che utilizzano lo stesso host /v1 la riutilizzano.
Close & Load To… può risultare disattivato la prima volta che si crea una query in una cartella di lavoro. Utilizzare Close & Load, quindi in Excel selezionare Data → Queries & Connections, fare clic con il pulsante destro sulla query e scegliere Load To. Questo percorso è documentato da Microsoft per questo caso.
Non è possibile inviare Living-Security-Version da Power Query su un’origine autenticata: la restrizione è la stessa di Power BI. Associare l’account di servizio oppure passare api_version nel record della query. Vedere Versioni del contratto e credenziali memorizzate. Query di report pronte all’uso (mappatura delle colonne e differenze rispetto all’esportazione di un provider precedente):

Conformità per singola persona

Iscrizioni alla formazione con granularità persona × assegnazione.

Log del phishing via email

Interazioni di phishing a livello di evento, ultimi 12 mesi.

Utenti più vulnerabili

Riepilogo per singola persona dei clic, delle credenziali e delle segnalazioni degli ultimi 12 mesi.

Dataset di anteprima reporting (phishing per singola persona)

La famiglia di anteprima reporting fornisce dataset per il phishing per singola persona. Richiede reporting:read e l’accesso al reporting per la propria organizzazione. Utilizzare il catalogo dei dataset riportato di seguito per esaminarne gli schemi e le policy sui dati. Consultare il catalogo in tempo reale:
Ogni dataset dichiara granularità, chiave primaria, join, watermark, policy di correzione e di eliminazione.

simulation_results

  • Percorso: GET /v1/reporting/simulation_results
  • Granularità: entità × simulazione
  • Filtri: simulation, entity, updated_after, più limit / page_token
  • Oggetto wire: reporting.simulation_result
  • Chiavi di join: entity_id, simulation_id
ReportingSimulationResults.pq (sketch)
Utilizzare updated_after come watermark inferiore inclusivo quando si aggiornano le partizioni recenti. Le dimensioni mutabili dei risultati vengono riformulate sul posto con lo stesso id.

simulation_events

  • Percorso: GET /v1/reporting/simulation_events
  • Granularità: un fatto tipizzato per ogni interazione osservata
  • Filtri: simulation, entity, event_type, occurred_after, più limit / page_token
  • Oggetto wire: reporting.simulation_event
  • Tipi di evento: token pubblici chiusi come simulation.delivered, simulation.opened, simulation.link_clicked, simulation.credentials_submitted, simulation.reported, non i tipi di attività phishing.simulation.* grezzi di ClickHouse
  • Dispositivo: device_type è la classe derivata (i token osservati includono desktop, mobile, tablet, unknown). user_agent grezzo non è presente in /v1. L’IP grezzo non è mai presente in /v1 (non viene mai salvato in modo persistente; solo ip_hash con salt).
ReportingSimulationEvents.pq (sketch)
Utilizzare occurred_after per i caricamenti incrementali degli eventi. I fatti sono di sola aggiunta; gli arrivi tardivi sono nuove righe.

entities

  • Percorso: GET /v1/reporting/entities
  • Granularità: una riga corrente per entità
  • Filtri: type, updated_after, più limit / page_token
  • Oggetto wire: reporting.entity
  • Chiave di join: id / entity_id (stesso valore)
Collegare i fatti di phishing alle persone con reporting.simulation_results.entity_id = reporting.entities.id. GET /v1/entities operativo rimane su entity:read e richiede un’autorizzazione diversa.
ReportingEntities.pq

entity_versions e cohort_memberships

Questi due dataset prevedono un’eccezione denominata di sola versione corrente:
Non esiste alcuna tabella autorevole dello storico delle versioni o delle appartenenze. Questo dataset proietta la riga corrente come un unico intervallo aperto (valid_to è null, is_current è true). valid_from è created_at oppure, in alternativa, updated_at per le versioni delle entità, e l’ora di osservazione della richiesta per le appartenenze alle coorti. Gli intervalli storici chiusi non vengono fabbricati.
  • entity_versions: GET /v1/reporting/entity_versions. Stessi filtri di entities. valid_from è created_at oppure, in alternativa, updated_at. Un’entità con entrambi i timestamp null viene omessa.
  • cohort_memberships: GET /v1/reporting/cohort_memberships. Filtri: cohort, entity, updated_after. updated_at è l’ultimo aggiornamento della coorte, in modo che l’aggiornamento incrementale rimanga attendibile. valid_from è l’ora di osservazione della richiesta. Collegare entity_id a reporting.entities.id.
ReportingEntityVersions.pq
ReportingCohortMemberships.pq

Modello semantico a schema a stella su /v1/activities

/v1/activities è il flusso di eventi con timestamp dell’organizzazione. Non ha misure numeriche: ogni quantità in un report è un conteggio di righe, il che rende lo schema a stella una scelta naturale.
  • Activities è il fatto evento alla granularità reale. Una riga per attività. I partecipanti vengono rimossi qui e ricostruiti come tabella a sé stante.
  • ActivityParticipants esiste perché i partecipanti sono effettivamente uno-a-molti, con ruoli come actor e target. Appiattirli su Activities comporterebbe la duplicazione delle righe delle attività (gonfiando ogni conteggio) oppure lo scarto dei partecipanti aggiuntivi. La relazione con Activities è l’unica relazione bidirezionale del modello, così che uno slicer sulle entità raggiunga la tabella dei fatti.
  • Entities è la dimensione che nomina i partecipanti. Le righe dei partecipanti in un’attività contengono entity_id e un ruolo, ma non un nome visualizzato.
  • Dates viene generata in M (zero chiamate API) e contrassegnata come tabella delle date del modello. Questo rende valida la time intelligence DAX (DATESINPERIOD, DATEADD). Le colonne con i nomi di mesi e giorni della settimana dichiarano sortByColumn sulle rispettive controparti numeriche, in modo che i visual non ordinino i mesi in ordine alfabetico.
Tutte le misure sono esplicite (il modello imposta discourageImplicitMeasures): totale attività, entità attive, attività per entità attiva, giorni con attività e media giornaliera mobile a 7 giorni.

Struttura della tabella bridge

ActivityParticipants scorre /v1/activities ed espande l’array participants in una riga per partecipante:
ActivityParticipants.pq
ActivityParticipants scorre /v1/activities in modo indipendente, anziché fare riferimento alla query Activities. In Power BI, due query caricate come due tabelle eseguono ciascuna un recupero indipendente al momento dell’aggiornamento. Mantenerle indipendenti consente al servizio di aggiornare in parallelo le partizioni di entrambe le tabelle.

Aggiornamento incrementale

Entrambe le tabelle a granularità di fatto (Activities e ActivityParticipants) dichiarano una policy di aggiornamento incrementale di Power BI: conservare 5 anni di partizioni annuali e reimportare gli ultimi 14 giorni a ogni aggiornamento. Il meccanismo è una coppia di parametri DateTime, RangeStart e RangeEnd, che il servizio Power BI riassegna per ogni partizione al momento dell’aggiornamento. Ogni query dei fatti riporta tali parametri nei filtri start_date e end_date dell’API, in modo che il volume di richieste a livello di partizione sia proporzionale alla partizione e non all’intero storico. La query amplia di un minuto per lato la finestra dell’API e riapplica localmente l’esatto limite semiaperto [RangeStart, RangeEnd), così che la correttezza delle partizioni non dipenda dal fatto che il server tratti i propri limiti come inclusivi o esclusivi.
Activities.pq — the fold that makes incremental refresh work
Il primo aggiornamento dopo una distribuzione applica la policy: un caricamento storico completo, lento. Ogni aggiornamento successivo interessa solo la finestra incrementale. Misurato su un dataset di ~158.000 attività e ~2.300 entità:
L’endpoint REST di aggiornamento classico di Power BI (POST .../refreshes con il solo notifyOption) ignora silenziosamente le policy di aggiornamento ed esegue ogni volta una scansione completa. Per applicare la policy tramite l’API REST, utilizzare l’aggiornamento avanzato (enhanced refresh): inviare type, commitMode e applyRefreshPolicy nel corpo della richiesta. Gli aggiornamenti avviati dall’utilità di pianificazione del servizio Power BI applicano sempre le policy: questa particolarità è specifica della chiamata REST.
La finestra di 14 giorni è volutamente ampia. L’acquisizione delle attività non è di sola aggiunta all’istante corrente: i backfill dei connettori inseriscono eventi con timestamp passati. Una finestra di 1-2 giorni li perderebbe in modo permanente.

Estensione della finestra di aggiornamento nell’API

GET /v1/activities accetta i filtri start_date e end_date in cui vengono riportati i parametri di Power BI, filtrando event_ts tra i limiti. Entities è una dimensione, quindi questo esempio la aggiorna ogni volta per intero anziché in modo incrementale. I dataset di reporting utilizzano watermark propri (updated_after, occurred_after) anziché la finestra di date delle attività.

Rate limit durante l’aggiornamento

/v1 applica budget separati per chiave e per IP (vedere rate limit). Rispettare 429 + Retry-After; non inserire in modo fisso un budget di richieste nel modello. Due caratteristiche degli aggiornamenti di Power BI sono rilevanti:
  • La scansione di una singola tabella è sequenziale. Ogni richiesta di pagina richiede il token della pagina precedente, quindi una singola tabella è vincolata dalla latenza indipendentemente dalla dimensione della pagina.
  • Gli aggiornamenti simultanei delle tabelle si moltiplicano. L’aggiornamento in parallelo di più tabelle di grandi dimensioni è il caso che raggiunge il limite massimo, ed è per questo che il percorso di nuovo tentativo per il 429 in Fn_FetchAll è importante. Preferire un numero ridotto di tabelle in parallelo anziché presumere una concorrenza illimitata.
Il nuovo tentativo è stato verificato con un limiter realmente saturo. Un aggiornamento eseguito mentre un carico di lavoro parallelo manteneva deliberatamente la chiave al limite massimo è stato comunque completato e ha prodotto lo stesso numero di righe di una baseline senza contesa: i nuovi tentativi hanno restituito pagine complete, senza lacune.

Versioni del contratto e credenziali memorizzate

/v1 accetta un’intestazione di richiesta Living-Security-Version per fissare una versione pubblicata del contratto (vedere Guida rapida all’API). Power Query non può inviare tale intestazione quando l’origine dati utilizza credenziali memorizzate: solo le origini dati anonime consentono intestazioni personalizzate. Aggiungerla fa fallire l’aggiornamento con:
Conservare la chiave nelle credenziali memorizzate di Power BI e omettere l’intestazione personalizzata. In assenza di una versione esplicita nella richiesta, l’API utilizza il valore contract_version fissato per l’account di servizio oppure, se non è impostato alcun valore, l’ultima versione pubblicata. Prima di pubblicare un aggiornamento, verificare la versione del contratto dell’account con l’amministratore dell’API. Per le versioni supportate, vedere il changelog dell’API. Se un aggiornamento inizia a comportarsi in modo inatteso, esaminare l’intestazione di risposta Living-Security-Version dell’API per verificare quale contratto ha effettivamente servito la richiesta.

Aggiornare e verificare il modello

Pubblicare il modello semantico nel workspace Power BI, associare la relativa credenziale memorizzata all’origine /v1 regionale ed eseguire un aggiornamento prima di abilitare una pianificazione. Esaminare la cronologia degli aggiornamenti per individuare errori o letture incomplete. Confrontare il numero di righe con una lettura API indipendente che utilizzi gli stessi filtri. La guida alla paginazione include esempi in Python e cURL per la lettura di un set di risultati completo. Un aggiornamento che legge solo la prima pagina può sembrare riuscito su un dataset di piccole dimensioni; confrontare i conteggi prima di fare affidamento sul report.

Scelte di modellazione

  • I totali delle campagne e i risultati per singola persona hanno granularità diverse. SimulationResults richiama GET /v1/simulations/{id}/results (una GET per esecuzione). Per il phishing per singola persona, aggiungere query per GET /v1/reporting/simulation_results e GET /v1/reporting/simulation_events (oppure GET /v1/simulation_results operativo se si dispone già di simulation:read).
  • vectors su /v1/simulations viene appiattito in una stringa separata da virgole. Una colonna di tipo elenco non può essere usata come slicer in una vera dimensione. Se una pagina del report deve filtrare per vettore, aggiungere una tabella bridge simulazione-vettore.

Passaggi successivi

Developer Hub

Creare un account di servizio e una chiave API per Power BI.

Guida rapida all'API

Autenticare le richieste /v1 con l’autenticazione Basic.

Paginazione

L’envelope dell’elenco, i token cursore e la stabilità dei filtri durante una scansione.

Rate limit

Budget per chiave e per IP, il contratto 429 e indicazioni sui nuovi tentativi.