Agent 365 observability attribute reference

This Agent 365 observability attribute reference is the canonical attribute-by-attribute spec used by the Agent 365 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, it records attributes from the agent, caller, request, and operation details you supply, along with context provided by instrumentation or baggage. It doesn't generate every required value for you. Supply the required context for your scenario, and use Picking values when a natural value isn't available. Some defaults aren't emitted explicitly; for example, the .NET scopes omit server.port for default HTTPS endpoints. If you use the direct OTel path, you supply the attributes directly. For how to assemble them into a request, see the Integration guide.

Observability attribute table legends

Use these legends to interpret the operation codes, requirement levels, and column descriptions in the Observability attribute table.

Applies to legend

The Applies to column uses the following codes to identify which operations each attribute applies to.

Code Operation
IA invoke_agent
ET execute_tool
CH chat
OM output_messages
All Applies to every operation

Required legend

The Required column uses the following codes to indicate whether you must emit an attribute.

Code Requirement
M Mandatory.
M*1 Mandatory only for agents with their own identity.
M*2 Mandatory only for agent-to-agent calls.
O*4 Optional, only meaningful when span status is Error.
O Optional.
N/A Don't emit from third-party integrations. Reserved for first-party use or auto-populated by Agent 365.

When a row lists requirement levels by operation, each level applies only to the listed operations. An attribute can be mandatory for one operation and optional for another.

RawEventData field column

This column names a JSON key inside CloudAppEvents.RawEventData that the canonical advanced-hunting query in Verifying ingestion parses. A -- means no downstream mapping is listed in this reference, either because the attribute isn't exposed or because the mapping hasn't been verified. You should still emit it according to the Required column.

Notes / impact if missing column

The .NET invocation scope records request parameters from InvokeAgentScopeDetails.RequestParameters and response parameters from InvokeAgentScopeDetails.ResponseParameters or RecordResponseParameters. The inference scope records response model and cache usage from InferenceCallDetails or the corresponding recording methods. The notes identify attributes you set explicitly and first-party-only attributes.

Observability attribute table

The following table groups attributes by agent identity, caller and run context, model requests and responses, tool execution, errors, service metadata, and span fields. SDK-specific classifications and notes reflect the .NET SDK scopes and processors. Framework instrumentation can supply additional attributes.

Attributes accept string values.

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.version All O -- Version of the agent being invoked or performing the operation. Recorded from AgentDetails.AgentVersion.
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. Omit when the agent has an Entra registration.
microsoft.agent.user.id All M*1 (IA, ET, CH); O (OM) TargetAgentUserKey (IA); UserKey (ET, CH) Microsoft Entra object ID of the agent's own user account. Required for AI teammates and agents with their own identity on IA, ET, and CH. The .NET shared scope also records it on OM when supplied.
microsoft.agent.user.email All O*1 UserId (ET, CH) UPN of the agent's user account.
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.version IA O -- Version of the calling agent in an agent-to-agent invocation. Recorded from caller agent details.
microsoft.a365.caller.agent.blueprint.id IA M*2 AgentBlueprintId Calling agent's blueprint appId. Required for agents with their own identity 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 first-party integrations. Don't emit from third-party integrations.
user.id All M UserKey (IA) Microsoft Entra object ID of the human caller. Required on every span. "Who ran this agent" is blank without it. The .NET shared scope records it on any operation when user details are supplied.
user.email All O UserId (IA) UPN of the caller.
user.name All O -- Display name of the caller.
client.address All M (IA, ET, CH); O (OM) ClientIP (IA, ET) Caller IP. IP-based investigation blocked if blank.
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.
server.address IA, ET, CH M ServerAddress (IA, ET) Endpoint your service is calling.
server.port IA, ET, CH M ServerPort (IA) Port of the endpoint your service is calling.
gen_ai.request.model IA, CH M (CH); O (IA) -- Requested model name (for example, gpt-4o). The .NET invocation scope records it from request parameters. Captured but not yet surfaced in advanced hunting.
gen_ai.provider.name All M (CH); O (IA, ET, OM) -- Provider name (for example, openai). The .NET shared scope records it from agent details; the inference scope also records it from inference details.
gen_ai.request.choice.count IA O -- Requested number of candidate completions.
gen_ai.request.seed IA O -- Seed used to improve reproducibility.
gen_ai.request.frequency_penalty IA O -- Frequency penalty requested for generation.
gen_ai.request.max_tokens IA O -- Maximum number of tokens to generate.
gen_ai.request.presence_penalty IA O -- Presence penalty requested for generation.
gen_ai.request.stop_sequences IA O -- Sequences that stop generation.
gen_ai.request.temperature IA O -- Temperature requested for generation.
gen_ai.request.top_p IA O -- Nucleus sampling setting requested for generation.
gen_ai.data_source.id IA O -- Identifier of the data source used for grounding or retrieval, such as a knowledge base or index.
gen_ai.output.type IA O -- Requested output content type, such as text, json, or image.
gen_ai.system_instructions IA O -- System or developer instructions supplied to the model. Review for sensitive content before recording.
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).
microsoft.a365.agent.thought.process IA, CH O -- Free-text reasoning or chain of thought.
gen_ai.response.model CH O -- Model name returned by the provider. It can differ from the requested model name.
gen_ai.response.finish_reasons IA, CH O -- Reasons generation stopped. The .NET invocation scope records them from response parameters.
gen_ai.usage.input_tokens IA, CH O -- Input token count. The .NET invocation scope records it from response parameters.
gen_ai.usage.output_tokens IA, CH O -- Output token count. The .NET invocation scope records it from response parameters.
gen_ai.usage.cache_creation.input_tokens IA O -- Input tokens written to a provider-managed cache, recorded through invocation response parameters.
gen_ai.usage.cache_write.input_tokens CH O -- Input tokens written to cache, recorded through inference details or RecordCacheWriteInputTokens.
gen_ai.usage.cache_read.input_tokens IA, CH O -- Input tokens served from cache. Recorded through invocation response parameters or inference details and recording methods.
gen_ai.tool.name ET M ToolName Tool name. Defender tool-usage views are blank if missing.
gen_ai.tool.type ET M ToolType The .NET SDK defines function, extension, and datastore. Other integration-specific values include Power Platform Connector, MCP Server, API, Knowledge Source, bing_grounding, code_interpreter, and file_search.
gen_ai.tool.call.id ET M ToolId Identifier for this tool call.
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.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).
url.full ET O -- Full tool endpoint URL. Remove credentials, access tokens, and other sensitive URL components before supplying it.
gen_ai.skill.name ET O -- Name of the skill loaded, the skill whose resource is read, or the skill whose script is executed.
gen_ai.skill.description ET O -- Description of the skill. Review for sensitive content before recording.
gen_ai.skill.source.uri ET O -- Original skill source URI, not a temporary local path. Remove credentials and access tokens before recording.
gen_ai.skill.resource.name ET O -- Skill-relative resource or script name.
process.executable.name ET O -- Executable name. Set only when the tool directly executes a single process.
process.executable.path ET O -- Executable path. Set only when the tool directly executes a single process.
process.exit.code ET O -- Reported process exit code, including zero for success. Recording an exit code doesn't change the span's error status.
microsoft.a365.transfer.mode ET O -- Control transfer mode: return_to_caller or pass_control. Recorded from tool transfer details.
microsoft.a365.transfer.target.type ET O -- Transfer target: agent, human, or workflow.
microsoft.a365.transfer.target.agent.id ET O -- Identifier of the agent receiving the transfer. Set target agent details only for an agent target.
microsoft.a365.transfer.target.agent.name ET O -- Name of the agent receiving the transfer.
microsoft.a365.transfer.target.agent.blueprint.id ET O -- Blueprint identifier of the agent receiving the transfer.
microsoft.a365.transfer.target.agent.platform.id ET O -- Platform identifier of the agent receiving the transfer.
microsoft.a365.transfer.target.agent.version ET O -- Version of the agent receiving the transfer.
error.type All O -- Error classification. The .NET scope records the exception type, an Azure request failure status, or a cancellation type when the scope ends after an error or cancellation is recorded.
error.message All O -- Error message key defined by the SDK. The .NET scope's RecordError path sets span.Status.Message instead of automatically emitting this attribute. Set it explicitly if your instrumentation uses it.
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.
operation.source All O InvokeSource (IA) Identifier for the SDK or service emitting the telemetry. Might be a Resource attribute.
service.name All O -- Name of the service emitting telemetry. The .NET SDK records Request.OperationSource under this key, not operation.source.
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.

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.

Pick 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.* 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 approximate counts are available, you can include them.
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.
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.
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.