Agent 365 observability attribute reference

This article is the canonical attribute-by-attribute spec used by Agent 365's ingestion pipeline. Every span ingested by Agent 365 - whether emitted by the Microsoft OpenTelemetry Distro, the deprecated Agent 365 Observability SDK, or sent over direct OTel - must conform to it. Each entry lists the operation types the attribute applies to, whether it's mandatory, the field name your value lands in for advanced-hunting queries (where one exists), and the impact if you skip it.

If you use the SDK or the Distro, the SDK emits these attributes for you. The Picking values section applies only when you need to override a default. If you use the direct OTel path, you emit every attribute manually. For how to assemble them into a request, see the Integration guide.

Attribute table

All values are sent as stringValue - token counts must be "42" (not 42); ports must be "443" (not 443).

Operation legend. IA = invoke_agent, ET = execute_tool, CH = chat, OM = output_messages, All = applies to every operation.

Required legend.

  • M: mandatory.
  • M*1: mandatory only for embodied agents (the agent has its own Entra Agent ID user account).
  • M*2: mandatory only for agent-to-agent calls.
  • M*3: mandatory for non-root spans only. The root invoke_agent has no parent.
  • O*4: optional, only meaningful when span status is Error.
  • O: optional.
  • N/A: don't emit. Agent 365 auto-populates.

The "RawEventData field" column names a JSON key inside CloudAppEvents.RawEventData that the canonical advanced-hunting query in Verifying ingestion parses. A blank cell means the attribute isn't exposed in CloudAppEvents today. You should still emit it (per the Required column) because Agent 365 uses it for ingestion, parent-resolution, and Microsoft Defender's agent-activity views. However, you can't directly query it from Microsoft Defender advanced hunting today.

Note

Agent 365 auto-populates the static record fields (Id, RecordType, Workload, UserType, Version) and the generated request and response IDs.

Attribute Applies to Required RawEventData field Notes / impact if missing
gen_ai.operation.name All M Operation One of invoke_agent, execute_tool, chat, output_messages. Span dropped if missing or unrecognized.
microsoft.tenant.id All M OrganizationId URL {tenantId} is authoritative. If you set this value and it disagrees, request is rejected (403).
gen_ai.agent.id All M TargetAgentId (IA); AgentId (ET, CH) The calling app's appId. Must match URL {agentId} and the authenticated app. Mismatch returns 403.
gen_ai.agent.name All M TargetAgentName (IA); AgentName (ET, CH) Defender and admin center show the raw GUID instead of a name if missing.
microsoft.a365.agent.blueprint.id All M TargetAgentBlueprintID (IA); AgentBlueprintId (ET, CH) The blueprint's appId. For standard Entra apps with no blueprint, reuse the agent's appId. Blueprint roll-ups in admin center break otherwise.
gen_ai.agent.description All O -- Detail view in admin center is blank for the agent.
gen_ai.agent.type All O PlatformTargetAgentType (IA); PlatformAgentType (ET); CopilotEventData.PlatformAgentType (CH) A label for your identity system, paired with microsoft.a365.agent.platform.id when the agent doesn't have an Entra registration. Free-form text; pick a value that uniquely identifies your identity system. Omit when the agent has an Entra registration. Agent 365 auto-classifies. Don't use the Microsoft-reserved values (see Picking values).
microsoft.a365.agent.platform.id All O PlatformTargetAgentId (IA, also top-level AlternateId); PlatformAgentId (ET, CH) The agent's unique ID in your non-Entra identity system. Free-form text. Set together with gen_ai.agent.type. Omit when the agent has an Entra registration. See Picking values.
gen_ai.conversation.id All M ConversationId (IA, ET); CopilotEventData.ConversationId / CopilotEventData.ThreadId (CH) The primary join key for a run. Without it, the run doesn't appear in Defender agent-activity views or admin center.
microsoft.channel.name All M ChannelName (IA, ET) The surface the agent runs in. Use a short lowercase token. The canonical values used by Defender and admin center filters today are msteams and outlook. Custom strings (for example web, <your-product-name>) are accepted but don't pivot in built-in channel filters. Use the same value on every span. See Picking values.
microsoft.channel.link All O -- Channel deep-link.
microsoft.session.id All O SessionIdentity Session pivots blank if missing.
microsoft.session.description All O -- Session description.
microsoft.conversation.item.link All O -- Deep link to the message.
correlation.id All O -- Cross-service tracing. Not surfaced in advanced hunting today.
operation.source All O InvokeSource (IA) Identifier for the SDK or service emitting the telemetry. Might be a Resource attribute.
client.address IA, ET, CH M ClientIP (IA, ET) Caller IP. IP-based investigation blocked if blank.
server.address IA, ET, CH M ServerAddress (IA, ET) Endpoint your service is calling.
server.port IA, ET, CH M ServerPort (IA) String-encoded (for example "443").
user.id IA M UserKey Microsoft Entra object ID of the human caller. "Who ran this agent" is blank without it.
user.email IA O UserId UPN of the caller.
user.name IA O -- Display name of the caller.
gen_ai.input.messages IA, CH M -- Request payload (JSON string). Captured for downstream analysis but not yet surfaced in advanced hunting.
gen_ai.output.messages IA, CH, OM M -- Response payload (JSON string).
gen_ai.execution.type IA O -- One of HumanToAgent, Agent2Agent, EventToAgent.
microsoft.a365.agent.thought.process IA, CH O -- Free-text reasoning or chain of thought.
gen_ai.author.app.id OM O -- Microsoft Entra app ID of the application that authored or created the agent.
gen_ai.tool.name ET M ToolName Tool name. Defender tool-usage views are blank if missing.
gen_ai.tool.type ET M ToolType One of function, Power Platform Connector, MCP Server, API, Knowledge Source, bing_grounding, code_interpreter, file_search.
gen_ai.tool.call.id ET M ToolId Identifier for this tool call.
gen_ai.tool.call.arguments ET M -- Tool arguments (JSON string). Captured but not yet surfaced in advanced hunting.
gen_ai.tool.call.result ET M -- Tool result (JSON string).
gen_ai.tool.description ET O ToolDescription Tool description.
gen_ai.tool.server.name ET O -- Tool server hostname. Set this attribute for MCP tools.
gen_ai.request.model CH M -- Model name (for example, gpt-4o). Captured but not yet surfaced in advanced hunting.
gen_ai.provider.name CH M -- Provider name (for example, openai).
gen_ai.usage.input_tokens CH O -- Input token count, string-encoded.
gen_ai.usage.output_tokens CH O -- Output token count, string-encoded.
gen_ai.response.finish_reasons CH O -- Finish reasons.
microsoft.a365.caller.agent.id IA M*2 AgentId (IA) Calling agent appId. Required for agent-to-agent.
microsoft.a365.caller.agent.name IA M*2 AgentName (IA) Calling agent display name.
microsoft.a365.caller.agent.blueprint.id IA M*2 AgentBlueprintId Calling agent's blueprint appId. Required for embodied A2A.
microsoft.a365.caller.agent.user.id IA M*2 -- Calling agent's user ID.
microsoft.a365.caller.agent.user.email IA M*2 -- Calling agent UPN.
microsoft.a365.caller.agent.platform.id IA N/A -- Reserved for non-Entra alternate IDs.
gen_ai.caller.agent.type IA N/A -- Agent 365 auto-classifies.
microsoft.agent.user.id IA, ET, CH M*1 TargetAgentUserKey (IA); UserKey (ET, CH) Microsoft Entra object ID of the agent's own user account. Required for AI teammates and embodied agents.
microsoft.agent.user.email IA, ET, CH O*1 UserId (ET, CH) UPN of the agent's user account.
span.SpanId All M OpId OTel SDK emits this.
span.ParentSpanId All M*3 ParentId Required for non-root spans only; the root invoke_agent has none.
span.StartTimeUnixNano All M top-level TimeGenerated (also CreationTime in RawEventData) Unix epoch nanos as a string.
span.EndTimeUnixNano All M CompletionTime (IA, ET); CopilotEventData.CompletionTime (CH) Duration can't be computed if missing.
span.Status.Message All O*4 ErrorMessage (IA, ET); CopilotEventData.ErrorMessage (CH) Failed runs' root cause is empty if missing.
span.Status.Code All O*4 ErrorType (IA); CopilotEventData.ErrorType (CH) Error category blank if missing.

Note

Agent 365 accepts several attributes you emit, such as tool arguments and results, model parameters, and channel deep-links. Downstream Microsoft Defender views use these attributes, but Agent 365 doesn't yet expose them as a CloudAppEvents.RawEventData JSON key. Set them according to the Required column. They might be added to the hunting payload in a future release.

Important

On invoke_agent (IA) records, the AgentId, AgentName, and AgentBlueprintId fields describe the calling agent, not the invoked agent. Agent 365 populates them from the microsoft.a365.caller.agent.* attributes. When a human invokes your agent, omit those attributes, so AgentId and AgentBlueprintId appear as an all-zeros GUID (00000000-0000-0000-0000-000000000000) and AgentName is empty in audit records and Microsoft Purview. The all-zeros value is expected for human-initiated runs. To identify the invoked agent, use TargetAgentId, TargetAgentName, and TargetAgentBlueprintID.

Picking values when you don't have a natural one

Some required attributes describe concepts that might not exist in your agent's architecture. If the natural value isn't available, set the following values instead. Do not leave a mandatory field empty. Even an all-zeros GUID hides your run from some customer-facing experiences. This rule applies to mandatory attributes only. It doesn't apply to the caller-agent attributes on human-initiated runs, where an all-zeros AgentId on invoke_agent records is expected.

Question / scenario Field(s) What to set
My agent is a standard Entra app registration (not built from an Entra Agent ID blueprint). gen_ai.agent.id The Entra app's appId.
↑ same scenario microsoft.a365.agent.blueprint.id Reuse the same value as gen_ai.agent.id (the agent's appId). The schema requires a non-empty value; reusing the agent appId is the safe default when there's no blueprint.
My agent is built from an Entra Agent ID blueprint - one or many agent identities minted from the same blueprint. gen_ai.agent.id The agent identity's appId (the instance appId, not the blueprint's).
↑ same scenario microsoft.a365.agent.blueprint.id The blueprint's appId. All instances minted from the same blueprint share this value.
The caller is a human user, not another agent. All microsoft.a365.caller.agent.* and gen_ai.caller.agent.* attributes Omit. They're mandatory only in agent-to-agent scenarios. On invoke_agent records, the caller fields AgentId and AgentBlueprintId show an all-zeros GUID. Use TargetAgentId to identify your agent.
In agent-to-agent: the calling agent is a standard Entra app (no blueprint). microsoft.a365.caller.agent.blueprint.id Reuse the calling agent's appId.
My agent is not an AI teammate - it doesn't have its own user account in the tenant. All microsoft.agent.user.* attributes Omit. They're mandatory only when the agent has its own Entra Agent ID user account.
My agent has no concept of a session beyond a single run. microsoft.session.id Optional - omit. If you want each run to be its own session, set to a per-run GUID.
My agent has no concept of a conversation (one-shot, stateless). gen_ai.conversation.id Generate a fresh GUID per run. The field is mandatory; skipping it removes the run from Defender agent-activity views and the Microsoft 365 admin center.
The caller has no IP (for example, an autonomous scheduled trigger). client.address Use a stable placeholder you control (for example, "0.0.0.0"). The field is mandatory; an empty value removes the run from IP-based investigation pivots.
The agent runs in-process; there's no separate "server" being called. server.address / server.port Use the hostname of the machine that ran the agent (for example, myagent.example.com) and the port your endpoint listens on. Required even when there's no separate downstream service.
My chat span has no model token usage. gen_ai.usage.input_tokens / gen_ai.usage.output_tokens Optional - omit. If you have approximate counts, send them as stringValue.
My span has no error to report. span.Status.Message, span.Status.Code Set the OTel status to OK (numeric code 1) and omit the message. The pipeline only consults these fields when status is Error.
My agent uses a non-Entra identity system (the agent has no Entra registration). microsoft.a365.agent.platform.id and gen_ai.agent.type Set both, on every span. platform.id is the agent's unique ID in your identity system; agent.type is a short label that identifies which identity system that is. Both are free-form text - pick whatever makes sense for your system. Don't use the Microsoft-reserved type values: CustomBuiltAgentsUsingSDK, CopilotStudio, Foundry, DeclarativeAgent, Custom (these values are reserved for internal Microsoft surfaces). The calling app you authenticate as still needs an Entra registration to use these routes - the alternate-id pair describes a target agent, not the caller.
What value should I put in microsoft.channel.name? microsoft.channel.name The surface the agent runs in. Defender and admin center filters key off the literal string, so use a short, stable, lowercase token. Today the canonical values are msteams and outlook; common customer-facing surfaces also use web, office, sharepoint, or <your-product-name>. Pick one value and stick to it - tooling can't reconcile msteams and Microsoft Teams as the same channel.
Should I set gen_ai.agent.type? gen_ai.agent.type Only if you're also setting microsoft.a365.agent.platform.id (for example, your agent has no Entra registration). The pair tells Agent 365 which identity system the agent comes from. Pick a short label that uniquely identifies your identity system. Don't use CustomBuiltAgentsUsingSDK, CopilotStudio, Foundry, DeclarativeAgent, or Custom - those values are reserved for internal Microsoft use. For Entra-registered agents, omit the field; Agent 365 backfills it.
What OTLP kind should I set on my spans? span.kind Use the integer enum value, not the proto enum string - 1 (INTERNAL), 2 (SERVER), 3 (CLIENT), 4 (PRODUCER), 5 (CONSUMER). Agent 365 accepts any of these and doesn't derive customer-visible behavior from kind, so 1 (INTERNAL) is a safe default for every span. If you want kind to reflect the call shape, INTERNAL for invoke_agent / output_messages and CLIENT for chat / execute_tool is reasonable.