Box
Every event field Built
140 fields. Five are required, one more is on by default, and everything else is optional. You never have to use a field you do not need, and a field we do not know is kept rather than dropped.
| Contract | Value |
|---|---|
| Version | 1.0.0-rc.5 |
| Fields | 140, of which 65 carry an OpenTelemetry name |
| Required | action actor.type actor.id outcome ts |
| Size limits | 256 KiB an event, 5 MiB or 1000 events a batch |
How to read this
- Required means an event without it is refused. There are five, and they are the answer to "who did what, how did it end, and when did they say it happened".
- On by default means your project can make it optional. Today that is the description.
- OpenTelemetry against a field means the name is identical to the OpenTelemetry convention, so data you already collect maps with no translation.
- Personal data is our own marker, to make the fields worth thinking about before you send them easy to spot. Several can be sent hashed instead, which proves two events concern the same person without carrying who they are.
- Anything not listed here is still kept. Unknown fields are sealed with the rest and stay queryable; they are simply not interpreted. You do not have to strip anything.
On this page
- Core — 11 fields
- Actor — 11 fields
- Target and change — 15 fields
- Access — 6 fields
- AI and generative AI — 53 fields
- Network, HTTP and TLS — 20 fields
- Device, browser and session — 22 fields
- Data subject — 2 fields
Core
The shape of every event: what happened, and how it ended.
| Field | Accepts | Constraints | Notes |
|---|---|---|---|
actionRequired | text |
| What happened, as dotted noun.verb (user.login, record.delete, rx.recommend). |
correlation_id | text |
| Groups related events (an AI recommendation and its human approval; open-edit-move of one file). |
event.category | text |
| Area of the application (auth, billing, records). |
event.client_id | text |
| Client-supplied idempotency key; a retry with the same value is not sealed twice. |
event.descriptionOn by default | text |
| Human-readable description of what happened. Required by default; a project may switch it to optional in its field policy. |
event.duration_ms | whole number |
| How long the action took, in milliseconds. |
event.timezone | text |
| IANA time zone the event happened in, as claimed by the client. An offset alone cannot identify the zone or whether daylight saving applied; this can. |
outcomeRequired | one of a fixed set |
| Result of the action. |
parent_event_id | text |
| Event that directly caused this one. |
severity | one of a fixed set |
| Significance of the event. Values are the OpenTelemetry log SeverityText names in lower case (trace < debug < info < warn < error < fatal). |
tsRequired | RFC 3339 timestamp |
| When the client says the event happened: RFC 3339 with an explicit Z or numeric offset. Recorded as a claim; chain order never uses it. Stored normalized to UTC together with the original offset, so both the UTC instant and the local wall-clock time the event claimed are always available. |
Actor
Who or what did it. Service accounts, machines and AI agents are actors too.
| Field | Accepts | Constraints | Notes |
|---|---|---|---|
actor.auth_method | one of a fixed set |
| How the actor authenticated for this action. |
actor.display_name | text |
| Human-readable label (Jane Doe). Not unique, may change; often absent for machines and service accounts. Personal data. Can be sent hashed instead. |
actor.domain | text |
| Tenant, domain or realm of the identity (CORP, acme.onmicrosoft.com). |
actor.email | text |
| Actor's email address; also the TRACE identifier. Personal data. Can be sent hashed instead. |
actor.idRequired | text |
| Stable unique identifier of the principal (user ID, ARN, SID, db-account@host). |
actor.identity_provider | text |
| Where the identity is defined. |
actor.name | text |
| Identity name the principal authenticates as (jdoe, svc-backup, app_rw, build-agent-03). Unique within its identity provider and stable over time. Not a display label. Personal data. Can be sent hashed instead. |
actor.on_behalf_of.id | text |
| Identifier of the principal the actor acted for. |
actor.on_behalf_of.type | one of a fixed set |
| Kind of principal the actor acted for (delegation or impersonation). |
actor.role | text |
| Role of the actor (admin, physician, readonly). |
actor.typeRequired | one of a fixed set |
| Kind of principal that performed the action. The actor is WHO did it; the device is WHAT it was done from. |
Target and change
What was acted on, and what changed about it.
| Field | Accepts | Constraints | Notes |
|---|---|---|---|
change.after | text | No constraint beyond its type. | Values of the changed fields after the change, keyed by field name (absent for delete). Serialized size up to 64 KB. Personal data. Can be sent hashed instead. |
change.before | text | No constraint beyond its type. | Values of the changed fields before the change, keyed by field name (absent for create). Serialized size up to 64 KB. Personal data. Can be sent hashed instead. |
change.fields | array | No constraint beyond its type. | Names of the target's fields that changed. change.before and change.after contain only these fields. |
change.kind | one of a fixed set |
| What sort of change was made to the target. |
change.state_hash.after | text |
| SHA-256 of the target's entire state after the change. |
change.state_hash.before | text |
| SHA-256 of the target's entire state before the change (for a file: its content). Should equal the previous event's state_hash.after for the same target; a mismatch means an unrecorded change. |
file.content_sha256 | text |
| SHA-256 of the file contents at the moment of a non-changing operation (proves exactly what was opened or downloaded). |
file.name | text |
| Name of the file including the extension, without the directory. OpenTelemetry: file.name. Personal data. Can be sent hashed instead. |
file.operation | one of a fixed set |
| Shared file vocabulary. Changing operations also carry change.*; non-changing ones (open, read, download) carry file.content_sha256. |
file.path | text |
| Full path of the file at the time of the event. For moves and renames use change.before/after with field 'path' instead. OpenTelemetry: file.path. Personal data. Can be sent hashed instead. |
file.size | whole number |
| File size in bytes. OpenTelemetry: file.size. |
file.type | text |
| File media type. |
target.id | text |
| Stable identifier of the object acted on; should survive renames and moves. |
target.name | text |
| Display name of the object acted on. Personal data. Can be sent hashed instead. |
target.type | text |
| Kind of object acted on (patient_record, invoice, file, user, environment). 'Target' is the object of the action. |
Access
Emergency, elevated, impersonated and delegated access, with its justification.
| Field | Accepts | Constraints | Notes |
|---|---|---|---|
access.approver.id | text |
| Identifier of the approver. |
access.approver.type | one of a fixed set |
| Kind of principal that approved the access, if any. |
access.expires_at | RFC 3339 timestamp |
| When the elevated or break-glass access ends. |
access.justification | text |
| Reason given for break-glass or elevated access. |
access.mode | one of a fixed set |
| How access was obtained. break_glass = emergency access that bypassed normal controls; elevated = temporary privilege raise (sudo, JIT admin); impersonation = acting as another principal; delegated = acting with granted authority. Anything but normal is always surfaced. |
access.reference | text |
| Incident, ticket or change reference authorising the access. |
AI and generative AI
The prompt, the model, its reasoning, and whether a human was in the loop.
| Field | Accepts | Constraints | Notes |
|---|---|---|---|
ai.autonomy | one of a fixed set |
| advisory = the AI recommended and a human decided; supervised = the AI acted after human approval; autonomous = the AI acted with no human in the loop. Autonomous actions are always surfaced. |
ai.confidence | number |
| Model confidence, 0 to 1. |
ai.decision | text |
| What the AI decided or recommended. |
ai.explanation | text |
| The AI's own plain-language explanation of its decision, written for the audit trail (what a reviewer should read). |
ai.guardrail.action | one of a fixed set |
| Most severe action taken by the guardrails. |
ai.guardrail.categories | array |
| Categories of the guardrails that fired. |
ai.guardrail.details | text |
| What the guardrail found. |
ai.guardrail.names | array | No constraint beyond its type. | Guardrails that fired, by name. |
ai.guardrail.triggered | true or false | No constraint beyond its type. | Whether any guardrail fired on the input or output. |
ai.human_review | one of a fixed set |
| Human review status; the approval itself is a separate event linked by correlation_id. |
ai.model.digest | text |
| SHA-256 of the model weights or manifest (self-hosted models), proving exactly which model ran. |
ai.model.host | one of a fixed set |
| Where inference ran. |
ai.model.quantization | text |
| Weight quantization of the model that served the request. |
ai.model.version | text |
| Model version or snapshot date when not part of the model name. |
ai.prompt.sha256 | text |
| SHA-256 of the exact rendered prompt bytes sent to the model. Proves what the model was asked without storing the prompt. |
ai.prompt.version | text |
| Version of the prompt template named by gen_ai.prompt.name. |
ai.reasoning | text |
| Raw rationale or chain of thought as produced by the model. Can be sent hashed instead. |
ai.tone | text |
| Tone the model was instructed to use or self-reported. |
gen_ai.agent.description | text |
| The agent's purpose. OpenTelemetry: gen_ai.agent.description. |
gen_ai.agent.id | text |
| Unique identifier of the agent. For an ai_agent actor this normally equals actor.id. OpenTelemetry: gen_ai.agent.id. |
gen_ai.agent.name | text |
| Human-readable agent name. OpenTelemetry: gen_ai.agent.name. |
gen_ai.agent.version | text |
| Agent version. OpenTelemetry: gen_ai.agent.version. |
gen_ai.conversation.id | text |
| Conversation or thread identifier. OpenTelemetry: gen_ai.conversation.id. |
gen_ai.data_source.id | text |
| Data source used for retrieval. OpenTelemetry: gen_ai.data_source.id. |
gen_ai.input.messages | array | No constraint beyond its type. | The input prompt: chat history provided to the model, in OpenTelemetry message form ({role, parts:[{type, content}]}). Large: counts toward event_max_bytes; ai.prompt.sha256 proves it without storing it. OpenTelemetry: gen_ai.input.messages. Personal data. Can be sent hashed instead. |
gen_ai.operation.name | text |
| The operation performed. OpenTelemetry: gen_ai.operation.name. |
gen_ai.output.messages | array | No constraint beyond its type. | Messages generated by the model, in OpenTelemetry message form. OpenTelemetry: gen_ai.output.messages. Personal data. Can be sent hashed instead. |
gen_ai.output.type | text |
| Kind of output requested. OpenTelemetry: gen_ai.output.type. |
gen_ai.prompt.name | text |
| Reference identifier of the prompt template in the customer's prompt registry (the prompt the agent's output was produced against). OpenTelemetry: gen_ai.prompt.name. |
gen_ai.provider.name | text |
| Generative AI provider. OpenTelemetry: gen_ai.provider.name. |
gen_ai.request.frequency_penalty | number | No constraint beyond its type. | Frequency penalty setting. OpenTelemetry: gen_ai.request.frequency_penalty. |
gen_ai.request.max_tokens | whole number |
| Maximum tokens requested. OpenTelemetry: gen_ai.request.max_tokens. |
gen_ai.request.model | text |
| Model requested (claude-opus-5, gpt-4o, llama-3.1-70b). OpenTelemetry: gen_ai.request.model. |
gen_ai.request.presence_penalty | number | No constraint beyond its type. | Presence penalty setting. OpenTelemetry: gen_ai.request.presence_penalty. |
gen_ai.request.seed | whole number | No constraint beyond its type. | Seed for deterministic generation. OpenTelemetry: gen_ai.request.seed. |
gen_ai.request.stop_sequences | array | No constraint beyond its type. | Stop sequences requested. OpenTelemetry: gen_ai.request.stop_sequences. |
gen_ai.request.stream | true or false | No constraint beyond its type. | Whether the response was streamed. OpenTelemetry: gen_ai.request.stream. |
gen_ai.request.temperature | number |
| Temperature setting. OpenTelemetry: gen_ai.request.temperature. |
gen_ai.request.top_k | number |
| Top-k sampling setting. OpenTelemetry: gen_ai.request.top_k. |
gen_ai.request.top_p | number |
| Top-p sampling setting. OpenTelemetry: gen_ai.request.top_p. |
gen_ai.response.finish_reasons | array | No constraint beyond its type. | Why generation stopped (stop, length, tool_calls, content_filter). OpenTelemetry: gen_ai.response.finish_reasons. |
gen_ai.response.id | text |
| Provider's identifier for the completion. OpenTelemetry: gen_ai.response.id. |
gen_ai.response.model | text |
| Model that actually generated the response (may differ from the request by routing or aliasing). OpenTelemetry: gen_ai.response.model. |
gen_ai.system_instructions | array | No constraint beyond its type. | System instructions given to the model. OpenTelemetry: gen_ai.system_instructions. Can be sent hashed instead. |
gen_ai.tool.call.arguments | text | No constraint beyond its type. | Arguments passed to the tool (any JSON). OpenTelemetry: gen_ai.tool.call.arguments. Personal data. Can be sent hashed instead. |
gen_ai.tool.call.id | text |
| Tool call identifier. OpenTelemetry: gen_ai.tool.call.id. |
gen_ai.tool.call.result | text | No constraint beyond its type. | Result returned by the tool (any JSON). OpenTelemetry: gen_ai.tool.call.result. Personal data. Can be sent hashed instead. |
gen_ai.tool.name | text |
| Tool the model invoked. OpenTelemetry: gen_ai.tool.name. |
gen_ai.tool.type | text |
| Kind of tool. OpenTelemetry: gen_ai.tool.type. |
gen_ai.usage.input_tokens | whole number |
| Input tokens consumed. OpenTelemetry: gen_ai.usage.input_tokens. |
gen_ai.usage.output_tokens | whole number |
| Output tokens generated. OpenTelemetry: gen_ai.usage.output_tokens. |
gen_ai.usage.reasoning.output_tokens | whole number |
| Output tokens spent on reasoning. OpenTelemetry: gen_ai.usage.reasoning.output_tokens. |
gen_ai.workflow.name | text |
| Workflow the operation belongs to. OpenTelemetry: gen_ai.workflow.name. |
Network, HTTP and TLS
Where the request came from and how it arrived.
| Field | Accepts | Constraints | Notes |
|---|---|---|---|
client.address | text |
| Address of the client as observed by the application: IPv4, IPv6, hostname or Unix socket. OpenTelemetry: client.address. Personal data. |
client.port | whole number |
| Client port. OpenTelemetry: client.port. |
dns.answers | array | No constraint beyond its type. | IPv4 or IPv6 addresses resolved during the lookup. OpenTelemetry: dns.answers. |
dns.question.name | text |
| The name being queried, as submitted. OpenTelemetry: dns.question.name. |
http.request.method | text |
| HTTP request method. OpenTelemetry: http.request.method. |
http.response.status_code | whole number |
| HTTP response status code. OpenTelemetry: http.response.status_code. |
network.direction | one of a fixed set |
| Direction of the traffic relative to the application (enTrail; not OpenTelemetry's network.io.direction, which is per interface). |
network.path | array | No constraint beyond its type. | Ordered hops the request passed through (proxy chain / X-Forwarded-For), client first (enTrail). |
network.protocol.name | text |
| OSI application layer protocol. OpenTelemetry: network.protocol.name. |
network.protocol.version | text |
| Protocol version, e.g. 1.1, 2. OpenTelemetry: network.protocol.version. |
network.transport | one of a fixed set |
| OSI transport layer. OpenTelemetry: network.transport. |
network.type | one of a fixed set |
| OSI network layer. OpenTelemetry: network.type. |
server.address | text |
| Address of the server the request went to. OpenTelemetry: server.address. |
server.port | whole number |
| Server port. OpenTelemetry: server.port. |
tls.client.hash.sha256 | text |
| SHA-256 fingerprint of the client certificate. OpenTelemetry: tls.client.hash.sha256. |
tls.protocol.version | text |
| TLS version negotiated, e.g. 1.3. OpenTelemetry: tls.protocol.version. |
url.domain | text |
| Domain extracted from the URL. OpenTelemetry: url.domain. |
url.full | text |
| Absolute URL including query. May contain PII. OpenTelemetry: url.full. Personal data. Can be sent hashed instead. |
url.path | text |
| The URI path component. OpenTelemetry: url.path. |
user_agent.original | text |
| User-agent string as received. The box also parses it into server fields. OpenTelemetry: user_agent.original. |
Device, browser and session
The thing in someone's hands, and the session it belonged to.
| Field | Accepts | Constraints | Notes |
|---|---|---|---|
browser.language | text |
| Preferred language of the user (navigator.language). OpenTelemetry: browser.language. |
browser.mobile | true or false | No constraint beyond its type. | Whether the browser reports running on a mobile device. OpenTelemetry: browser.mobile. |
browser.name | text |
| Browser name as claimed by the client (Chrome, Safari). The box also derives it from user_agent.original; a mismatch is an anomaly signal. |
browser.platform | text |
| Platform reported by UA client hints (Windows, macOS, Android). OpenTelemetry: browser.platform. |
browser.version | text |
| Browser version as claimed by the client. |
device.hostname | text |
| Network hostname of the device. |
device.id | text |
| Stable device identifier. OpenTelemetry: device.id. |
device.local_ip | text |
| Device's local network address. |
device.mac | text |
| MAC address of the device. Personal data. Can be sent hashed instead. |
device.managed | true or false | No constraint beyond its type. | Whether the device is enrolled in device management (MDM). |
device.manufacturer | text |
| Device manufacturer (Apple, Dell). OpenTelemetry: device.manufacturer. |
device.model.identifier | text |
| Machine-readable model identifier (MacBookPro18,3). OpenTelemetry: device.model.identifier. |
device.model.name | text |
| Marketing model name (MacBook Pro 16-inch). OpenTelemetry: device.model.name. |
device.name | text |
| Device name. |
device.os.name | text |
| Operating system name of the actor's device (Windows, macOS, Linux, iOS, Android). enTrail field: OpenTelemetry os.* describes the telemetry host, not the actor's device. |
device.os.version | text |
| Operating system version. |
device.screen.height | whole number |
| Screen height in CSS pixels. |
device.screen.pixel_ratio | number |
| Device pixel ratio. |
device.screen.width | whole number |
| Screen width in CSS pixels. |
device.type | one of a fixed set |
| Kind of device. |
session.id | text |
| Session the event belongs to. OpenTelemetry: session.id. |
session.previous_id | text |
| The previous session id for this actor, when known (session renewal chains). OpenTelemetry: session.previous_id. |
Data subject
For access and erasure requests about a person.
| Field | Accepts | Constraints | Notes |
|---|---|---|---|
data_subject.id | text |
| Identifier of the person whose personal data the event involves. Used by TRACE and access requests. Personal data. Can be sent hashed instead. |
data_subject.type | text |
| Kind of person whose personal data the event involves (patient, customer, employee). Distinct from actor (who acted) and target (what was acted on). |
Your own fields
Fields outside this list are kept, sealed and queryable — they are simply not interpreted. To have your own names understood, a mapping profile translates them to these on the way in, and we write it for you today from a sample of your log lines.
Coming soon: defining and mapping your own custom fields yourself, in the console.
When this list changes
Field definitions are versioned and signed. New versions download automatically, and the box owner chooses when to adopt one, so a change never breaks a working integration overnight. A minor version only adds fields; removing one, or changing what an existing field means, requires a major version. Deprecated fields keep working with a warning and a stated removal version.