> ## Documentation Index
> Fetch the complete documentation index at: https://docs.livingsecurity.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Email phishing log

> Recreate a previous provider's event-level phishing log from /v1 reporting simulation events and entities.

This report is an event-level phishing log: one row per observed simulation
interaction (date, action, recipient email, subject, from, difficulty). It
stays long-form — it does not collapse a person's history into a single
result.

The query folds a trailing **12 calendar months** into `occurred_after`
(midnight UTC on the same day-of-month twelve months ago — not a 365-day
duration).

<Note>
  Raw client IP is never on `/v1` — privacy by design, not a pending
  mapping. Device type is a derived class on the event row; raw
  `user_agent` stays private. See
  [Divergences from the legacy export](#divergences-from-the-legacy-export).
</Note>

Setup, credentials, pagination, and rate-limit retry are the same as the
[Power BI / Excel connectivity guide](/developers/v1/powerbi). Add the shared
`Fn_FetchAll` query first; this report calls it by name.

## Required key scopes

| Scope | Used for |
| - | - |
| `reporting:read` | `GET /v1/reporting/simulation_events` |
| `entity:read` | `GET /v1/entities` (email and display-name join) |

A key granted only `simulation:read` cannot call the reporting events
endpoint (the API returns `403`). See
[choose the right grain](/developers/v1/powerbi#choose-the-right-grain).

## Source endpoints

| Endpoint | Role |
| - | - |
| `GET /v1/reporting/simulation_events` | Event-level fact. Grain is one typed interaction. `email_subject`, `sender_email`, `sender_domain`, and `difficulty_tier` are on this row, so the query does not join campaign-level results for those fields. |
| `GET /v1/entities` | Resolves `entity_id` → email / display name. The reporting event omits recipient email (a hard exclusion on the reporting reader). Walking `/entities` is how the legacy "email" column is populated. |

Allowlisted filters on the events list (anything else returns `400`):
`limit`, `page_token`, `simulation`, `entity`, `event_type`,
`occurred_after`.

This reporting family is a [preview dataset](/developers/v1/powerbi#reporting-preview-datasets-per-person-phishing).
Inspect the dataset schema and data policies at
`GET /v1/reporting/datasets` and
`GET /v1/reporting/datasets/simulation_events`.

### Grain

One row per reporting simulation event. A person who opened and then
clicked the same message produces two rows. Events with a null `entity_id`
(no actor / recipient / target participant) still appear — `email` is
null.

The API window is widened by one minute; the exact
`occurred_at >= WindowStart` bound is re-applied locally so the trailing
year does not depend on whether the server treats `occurred_after` as
inclusive or exclusive.

Request budget: one paginated walk of events in the window, plus one walk
of entities. Always set `limit = "500"`.

## Column mapping

Legacy column names are from your previous provider's export. `/v1` fields
are the public API names; the query aliases some of them for the report.

| Legacy column | `/v1` field or derivation | Report column |
| - | - | - |
| Date | `Event.occurred_at` (as a date; raw `occurred_at` is kept as `datetimezone`) | `date` |
| Action | `Event.event_type` — closed tokens listed below | `action` |
| Email | `Entity.email` (join on `entity_id`) | `email` |
| Subject | `Event.email_subject` | `subject` |
| From | `Event.sender_email` | `from` |
| Difficulty | `Event.difficulty_tier` — integer 1–5, 1 easiest, 5 hardest | `difficulty` |
| Raw IP | Never on `/v1` | Omitted, not nulled |
| Device type | `Event.device_type` — derived class; null when the event has no derived class | `device_type` |

### Action tokens

`action` is the closed reporting token. Legacy "Email Sent" maps to
`simulation.delivered` (`delivered` is the public verb; the wire token is
`simulation.delivered`).

| `action` value |
| - |
| `simulation.delivered` |
| `simulation.opened` |
| `simulation.link_clicked` |
| `simulation.credentials_submitted` |
| `simulation.attachment_opened` |
| `simulation.reported` |
| `simulation.bounced` |
| `simulation.qr_scanned` |
| `simulation.replied` |

Extra fields kept because the API has them: `sender_domain`, `full_name`,
`event_id`, `entity_id`, `simulation_id`, `occurred_at`, plus
`entity_type` and `entity_status` from the entity join.

## Divergences from the legacy export

* **Raw IP is never available.** `/v1` will not expose raw client IP —
  privacy by design, not a pending mapping. The query does not add a
  placeholder IP column.
* **Device type is derived, not raw.** `device_type` is a derived device
  class for click, submit, and report events. Observed tokens include
  `desktop`, `mobile`, `tablet`, and `unknown`, but the emitter stores a
  free-form string — treat it as open text, not a closed enum. It is null
  when the event has no derived class, and the raw `user_agent` string
  stays private.
* **"Email Sent" is `simulation.delivered`.** Use that token when you
  filter or count sends. Do not look for a legacy `email_sent` string.
* **Recipient email is a join, not a field on the event.** The reporting
  event omits email; the query walks `/entities` to fill it.
* **Trailing 12 calendar months**, not a 365-day duration, and not the
  full history.
* **Long-form, not collapsed.** One row per interaction, not one result
  per person.

## Next steps

<CardGroup cols={2}>
  <Card title="Power BI and Excel setup" href="/developers/v1/powerbi">
    Credentials, pagination, and loading these queries in Power BI or Excel.
  </Card>

  <Card title="Most susceptible users" href="/developers/v1/reports/most-susceptible-users">
    Per-person 12-month click, credential, and report rollup.
  </Card>

  <Card title="Per-person compliance" href="/developers/v1/reports/per-person-compliance">
    Training enrollments at person × assignment grain.
  </Card>

  <Card title="API keys" href="/developers/developer-hub/api-keys">
    Grant `reporting:read` and `entity:read` on the key that refreshes this report.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.