Appearance
Overview
imper.ai sends every finished verification to your SIEM as one OCSF 1.3.0 Detection Finding event (class_uid 2004, type_uid 200401). Because the event follows the Open Cybersecurity Schema Framework, SIEMs that support OCSF can ingest it without a custom parser, and the standard fields - severity, risk, the person verified and where they verified from - line up with your other security sources.
The event is delivered through imper.ai's SIEM integrations. To set one up, see Palo Alto Cortex XSIAM or Sumo Logic.
The full verification result travels inside the same event under unmapped.verification_result. OCSF requires product-specific data that has no OCSF field to be placed under unmapped, so the full result is carried there. Its overall structure is described at the end of this page.
Sample events
A verification that detected risk:
json
{
"class_uid": 2004,
"class_name": "Detection Finding",
"category_uid": 2,
"category_name": "Findings",
"activity_id": 1,
"activity_name": "Create",
"type_uid": 200401,
"type_name": "Detection Finding: Create",
"time": 1791797652000,
"severity_id": 4,
"severity": "High",
"risk_level_id": 3,
"risk_level": "High",
"risk_score": 80,
"message": "imper.ai identity verification: risk detected",
"metadata": {
"version": "1.3.0",
"product": { "name": "imper.ai", "vendor_name": "imper.ai" }
},
"finding_info": {
"uid": "5f1c2a9e-3b7d-4e21-9a6f-0c8d4b2e7a13",
"title": "imper.ai identity verification: risk detected",
"types": ["high_risk_vpn"],
"created_time": 1791797400000,
"last_seen_time": 1791797652000
},
"evidences": [
{
"user": { "name": "Dana Doe", "uid": "dana.doe@acme.example", "email_addr": "dana.doe@acme.example" },
"src_endpoint": {
"ip": "203.0.113.7",
"location": { "country": "DE", "isp": "Hetzner Online GmbH" }
}
}
],
"unmapped": {
"verification_result": {
"schema_version": "1.0",
"verification_id": "5f1c2a9e-3b7d-4e21-9a6f-0c8d4b2e7a13",
"requested_at": "2026-10-12T09:30:00+00:00",
"finished_at": "2026-10-12T09:34:12+00:00",
"subject": {
"full_name": "Dana Doe",
"work_email": "dana.doe@acme.example"
},
"session": {
"ip_address": "203.0.113.7",
"country_code": "DE",
"isp": "Hetzner Online GmbH"
},
"verdict": {
"verification_status": "risk_detected",
"risk_score": 8.0,
"risk_level": "high",
"risk_score_thresholds": { "verified": 3.0, "low": 5.0, "medium": 7.0 },
"reasons": ["high_risk_vpn"]
},
"findings": {
"vpn": {
"category": "Network",
"section": "Network",
"description": null,
"is_risk": true,
"reasons": ["high_risk_vpn", "vpn_port_open"],
"vpn_providers": ["NordVPN"],
"open_vpn_ports": [1194]
}
}
}
}
}verification_result above is an excerpt. The full result also carries use_case, started_at, the remaining subject and session fields, report, challenge and action, and lists every detection under findings, with null for those that did not fire. See unmapped.verification_result below.
A verified verification differs in its verdict fields, and no detection fires:
json
{
"severity_id": 1,
"severity": "Informational",
"risk_level_id": 0,
"risk_level": "Info",
"risk_score": 4,
"message": "imper.ai identity verification: verified",
"finding_info": {
"uid": "9d0e4b71-6a2c-4f58-b3e9-1a7c5d8f2e04",
"title": "imper.ai identity verification: verified",
"types": [],
"created_time": 1791797400000,
"last_seen_time": 1791797652000
},
"unmapped": {
"verification_result": {
"verdict": {
"verification_status": "verified",
"risk_score": 0.4,
"risk_level": "verified",
"risk_score_thresholds": { "verified": 3.0, "low": 5.0, "medium": 7.0 },
"reasons": []
}
}
}
}Fields
Optional fields are omitted from the event when they have no value; OCSF does not allow null.
| Field | Type | Always present | Description |
|---|---|---|---|
class_uid / class_name | int / string | yes | Always 2004 / Detection Finding. |
category_uid / category_name | int / string | yes | Always 2 / Findings. |
activity_id / activity_name | int / string | yes | Always 1 / Create. |
type_uid / type_name | int / string | yes | Always 200401 / Detection Finding: Create. |
time | int | yes | When the verification finished, epoch milliseconds UTC. Falls back to the request time. |
severity_id / severity | int / string | yes | OCSF severity derived from the verdict; see the mapping below. |
risk_level_id / risk_level | int / string | no | OCSF risk level derived from the verdict; omitted while no verdict exists. |
risk_score | int | no | Overall risk score on a 0-100 scale. OCSF requires an integer, so this is the imper.ai 0-10 risk score multiplied by 10 (e.g. 8.0 → 80). The original 0-10 score is in unmapped.verification_result.verdict.risk_score. |
message | string | yes | imper.ai identity verification: <status>, e.g. imper.ai identity verification: risk detected. |
metadata.version | string | yes | OCSF version, 1.3.0. |
metadata.product.vendor_name / .name | string | yes | imper.ai by default; configurable per integration for SIEMs that restrict these characters. |
finding_info.uid | string | yes | The verification ID. Unique per verification; use it to deduplicate and to open the verification in the dashboard. |
finding_info.title | string | yes | Same text as message. |
finding_info.types | string[] | yes | Why the verification raised risk, as stable keys (e.g. high_risk_vpn, virtual_machine); the same list as unmapped.verification_result.verdict.reasons. Empty for a verified verification. |
finding_info.created_time | int | yes | When the verification was requested, epoch milliseconds UTC. |
finding_info.last_seen_time | int | no | When the verification finished, epoch milliseconds UTC. |
evidences[].user.name | string | no | Full name of the person verified. |
evidences[].user.uid / .email_addr | string | no | Work email of the person verified. |
evidences[].src_endpoint.ip | string | no | IP address the person verified from. |
evidences[].src_endpoint.location.country | string | no | Country of that IP, ISO 3166-1 alpha-2. |
evidences[].src_endpoint.location.isp | string | no | ISP of that IP; reported only together with the country. |
unmapped.verification_result | object | yes | The full verification result; see unmapped.verification_result. |
evidences holds at most one entry, and is an empty list when neither the person nor their IP is known.
Verdict mapping
| Verdict | severity_id / severity | risk_level_id / risk_level |
|---|---|---|
| Verified | 1 / Informational | 0 / Info |
| Low risk | 2 / Low | 1 / Low |
| Medium risk | 3 / Medium | 2 / Medium |
| High risk | 4 / High | 3 / High |
| No verdict | 0 / Unknown | omitted |
unmapped.verification_result
The same verification result the dashboard's Export downloads. Its top-level structure:
| Field | Type | Description |
|---|---|---|
schema_version | string | Version of this structure, 1.0. |
verification_id | string | The verification's unique ID. |
use_case | string | The product the verification ran in: helpdesk, enrollment or hiring. |
requested_at / started_at / finished_at | ISO 8601 timestamp | When the verification was requested, started and finished. |
subject | object | The person verified: name, work email, department. |
session | object | Where they verified from: IP, country, ISP, timezone, device, browser, OS. |
verdict | object | Status (verified, risk_detected or not_completed), overall risk score (0-10), risk level, your organization's risk-score thresholds, and the reasons that raised risk. |
findings | object | One entry per detection that raised risk, keyed by detection name. Each carries its category, whether it counts as risk, the reasons, and the evidence for that detection. A detection that passed or did not run is null. |
report | object[] | The verification report as the dashboard shows it, section by section. |
challenge | object | Question counts - total, answered, skipped, timed out - when a challenge ran. |
action | object | The action requested after the verification, its overall result (succeeded, failed, pending, incomplete, assistance_required, no_login_detected or failed_to_login), each action's status (success or failed), and any ITSM ticket opened. null when no action ran and no ticket was opened. |
findings
One entry per detection that raised risk, keyed by the detection's name (e.g. vpn, virtual_machine, remote_desktop, emulated_phone); a detection that passed or did not run is null. Every entry has the same common fields, followed by the evidence specific to that detection:
json
"findings": {
"vpn": {
"category": "Network",
"section": "Network",
"description": null,
"is_risk": true,
"reasons": ["high_risk_vpn", "vpn_port_open"],
"vpn_providers": ["NordVPN"],
"open_vpn_ports": [1194]
},
"virtual_machine": null,
"remote_desktop": null
}| Field | Type | Description |
|---|---|---|
category | string | Detection category, e.g. Network, Device. |
section | string | The verification report section the finding appears in. |
description | string | Optional free-text explanation. |
is_risk | boolean | Whether the finding counts as risk. |
reasons | string[] | Why the detection fired, as stable keys, e.g. high_risk_vpn, vpn_port_open. |
| other fields | varies | The evidence for that detection, e.g. vpn_providers and open_vpn_ports for vpn. |