You can route full audit telemetry from Office agents to your own OpenTelemetry (OTEL) collector. This gives your organization complete control over retention, encryption, and integration with your SIEM or observability platform.
This guide covers how to enable a custom collector, what data you'll receive, and the full span schema reference.
Custom OTEL collectors are available to Claude Enterprise organizations and to direct-provider deployments (Amazon Bedrock, Google Vertex AI, or a gateway).
What you'll receive
When you configure a custom collector, Office agents send trace data covering every user turn. Each turn produces a tree of spans capturing the prompt, model calls, tool executions, file uploads, and context compaction events.
Your collector receives all span attributes, including those carrying user-generated content (prompt text, tool inputs and outputs, document URLs, and filenames). No attributes are redacted or filtered. Assistant response text is not included in the emitted span data. Your organization owns this data.
Important: Metrics aren't sent to custom collectors. The office_agent.* counter namespace routes to Anthropic only. However, every counter increment also appears as a span event on the active span, so the same signals are available in your traces.
Telemetry is sent via OTLP/HTTP to your endpoint at {your_url}/v1/traces. gRPC isn't supported because the add-in runs in an Office WebView.
Enable a custom collector
Setup differs depending on how your organization authenticates with Claude.
Important: When a custom endpoint is configured, telemetry goes exclusively to your collector. Spans aren't dual-sent to Anthropic.
Claude Enterprise (OAuth) organizations
An organization administrator sets the collector endpoint in the Claude.ai admin console under Organization settings > Office agents. The setting applies organization-wide.
Setting | Description |
| Base URL of your OTLP collector. The add-in appends /v1/traces. HTTPS strongly recommended. |
| Optional authentication headers, formatted per the OpenTelemetry spec: key1=value1,key2=value2 |
The protocol must be HTTP-based OTLP. gRPC is rejected at configuration time.
Direct provider deployments (Amazon Bedrock, Google Vertex AI, gateway)
For deployments that authenticate against your own model provider rather than Claude.ai, the collector endpoint is supplied through one of three configuration channels. All three use the same two keys.
Recommended: Use the claude-in-office plugin for Claude Code. It walks you through generating the manifest, registering Entra extension attributes, and standing up a bootstrap endpoint with otlp_endpoint and otlp_headers pre-wired. The three channels below are documented for reference and manual setup.
Key | Format | Description |
| HTTPS URL | Base URL of your OTLP collector. The add-in strips any trailing slash and appends /v1/traces. |
| key1=value1,key2=value2 | Optional authentication headers. Same format as the OpenTelemetry OTEL_EXPORTER_OTLP_HEADERS environment variable. |
If otlp_endpoint is unset or empty, no custom collector is configured and the add-in falls back to default behavior.
Note: These configuration channels apply to Microsoft Office deployments only. Google Workspace add-ins are configured separately.
Channel 1: Manifest URL parameter
Append the keys as query string parameters to the taskpane URL in your custom add-in manifest:
URL-encode the values. This applies the configuration to every user who installs the manifest.
Channel 2: Azure Entra ID directory extension
For per-user configuration, register the keys as Entra ID directory extension attributes and assign them via Microsoft Graph. The add-in reads them from the user's ID token using Nested App Authentication (NAA).
The claim names in the issued ID token follow Azure's directory extension format:
Claim | Maps to |
| otlp_endpoint |
| otlp_headers |
Set these per-user with a Graph PATCH against the user object. Azure encodes directory extension values as single-element arrays in the ID token; the add-in unwraps them automatically. This channel requires entra_sso=1 in the manifest URL parameters to enable NAA token acquisition.
Channel 3: Bootstrap endpoint response
If your deployment uses a bootstrap endpoint (a JSON endpoint your organization hosts that the add-in calls at startup), include the keys in the response body:
{
"otlp_endpoint": "https://otel-collector.your-domain.com",
"otlp_headers": "Authorization=Bearer <token>"
}The bootstrap endpoint URL itself is configured via bootstrap_url in either the manifest URL parameters or an Entra extn.bootstrap_url claim. If an Entra ID token was acquired, it is passed to the bootstrap endpoint as a Bearer authorization header so your endpoint can authenticate the user before returning per-user configuration.
Precedence
When multiple channels supply a value, later channels override earlier ones: manifest parameters are read first, then Entra claims, then the bootstrap response. The bootstrap response wins.
If you haven't already, the fastest path is the claude-in-office plugin.
Deployment modes
Custom collector export is available on both deployment modes:
Claude.ai Enterprise (OAuth): full audit trail including user identity (
user.email,user.account_uuid,organization.id), MCP server metadata, and file upload records.Direct provider (Bedrock, Vertex AI, gateway): core audit trail (prompts, tool inputs and outputs, document URLs) but no user identity, no MCP metadata, and no file upload spans. User attribution requires correlating
session.idagainst your own identity provider logs.
The core audit payload is identical in both modes. Direct provider deployments lack Claude.ai account context, so attributes derived from the Claude.ai user or organization profile are absent. See the [claude.ai-only] tags in the span schema below for the complete list.
Surface and vendor labels
Every span includes two labels identifying which Office application and platform generated it. Use these as your primary dimensions for filtering and dashboards.
Label | Values |
| sheet (Excel/Google Sheets), doc (Word), slide (PowerPoint) |
| m (Microsoft) |
Span reference
Each user turn produces a parent/child tree of up to five span types. Attributes marked [content] carry user-generated data; these form your audit payload. Attributes marked [claude.ai-only] are populated only when the user signs in with a Claude account; they are absent on Bedrock, Vertex AI, and gateway deployments. Absent attributes are omitted from the span entirely (no key with a null value).
The file.upload span and all mcp.* attributes are also [claude.ai-only], since file upload and MCP server connections are Claude platform features.
For direct provider deployments, user identity should be correlated via session.id and document.url, joined against your identity provider's session logs.
Resource attributes
These attributes appear on every span:
Attribute | Description |
| Fixed value: office-agent |
| Fixed value: 1.0.0 |
| Build commit identifier |
agent.query (root span)
One span per user turn. This is the root of the span tree and carries session identity, document context, and MCP server status. SpanKind: INTERNAL.
Attribute | Description |
| sheet | doc | slide |
| m |
| The user's prompt (first 4000 characters) |
| Opaque session identifier |
| User's email address |
| Deterministic hash bucket (SHA-256 of email, mod 30) |
| Claude account UUID |
| URL of the open Office document |
| Claude organization UUID |
| Claude subscription tier |
| Claude organization type |
| Model selected by the user for this session |
| PC | Mac | OfficeOnline | iOS | Android | Universal |
| Office build number |
| Number of MCP servers configured |
| Number of MCP servers successfully connected |
| Number of MCP servers that failed to connect |
| success | error | timeout | no_auth | not_attempted |
| MCP registry fetch duration |
| MCP registry fetch HTTP status code |
| Serialized MCP server details (names, tool counts, error messages) |
| Number of files attached to this turn |
| Total bytes uploaded |
| Number of image attachments |
| Number of document attachments |
| Number of other attachments |
| Exception class name (present on failure) |
| Phase at which the query failed (present on failure) |
agent.stream
One span per API call to Claude, as a child of the query span. SpanKind: CLIENT.
Attribute | Description |
| Model ID used for this call |
| Maximum output tokens requested |
| Number of messages in the conversation at stream start |
| Input tokens billed (from API response) |
| Output tokens billed (from API response) |
| Tokens served from prompt cache |
| Tokens written to prompt cache |
| end_turn | tool_use | max_tokens | etc. |
| Anthropic API request-id header, usable for support correlation |
Note on prompt caching: The add-in requests prompt caching unconditionally. The cache_read_tokens and cache_creation_tokens attributes are set from the provider's API response and are omitted when the response doesn't include them. Prompt caching is available for the Claude Developer Platform; as of this writing, Amazon Bedrock and Google Vertex AI don't yet return these fields through the client the add-in uses. When support lands on your provider, these attributes will begin appearing automatically.
agent.tool_execution
One span per tool call, as a child of the stream span. SpanKind: INTERNAL. This is the primary record of what actions the model took against the document.
Attribute | Description |
| Tool identifier (e.g. get_cell_ranges, execute_office_js, edit_slide_xml) |
| Unique ID of this tool invocation |
| server | client |
| first_party | mcp | server |
| read | write | read_write |
| manual | auto_accept | deferred |
| Serialized tool input (first 4000 characters) |
| Boolean |
| Serialized tool output (first 4000 characters) |
| Full output length in characters (use to detect truncation) |
| Error classification (present on failure) |
| Cells read (sheet surface only) |
| Cells written (sheet surface only) |
| Cells copied (sheet surface only) |
Note: The tool.accept_decision attribute records how the permission decision was made: manual (the user approved this specific action), auto_accept (the user had previously granted standing approval), or deferred (the action was queued for later review). Use this to audit approval patterns across your organization.
agent.compaction
One span per conversation auto-summarization, fired when context approaches the window limit. SpanKind: CLIENT.
Attribute | Description |
| Token count before summarization |
| Token count after summarization |
| Delta |
| Boolean |
| Currently always reactive |
This span also carries agent.surface, agent.vendor, session.id, user.email [claude.ai-only], user.bucket [claude.ai-only], office.platform, and office.version, duplicated from the root span so you can query compaction events independently.
file.upload [claude.ai-only]
One span per individual file upload, as a child of the query span. SpanKind: CLIENT. This span type only appears when users sign in with a Claude.ai account. File upload isn't available on direct provider deployments.
Attribute | Description |
| Original filename |
| File size |
| MIME type |
| Anthropic Files API identifier |
| Boolean |
Span events
Span events are timestamped markers attached to the spans above. They capture lifecycle transitions and counter-equivalent signals.
agent.query: exception {exception.type}; file_upload {file_id, mime_type, content_category}agent.stream: first_token; stream_complete; stream_error {exception.type}agent.tool_execution: tool_init; tool_run; tool_result; tool_error {error_type}agent.compaction: compaction_start; compaction_complete; compaction_error {exception.type}file.upload: exception {exception.type}
Every internal product counter also records a span event with the same name on the currently active span, providing the equivalent of the metrics stream within your trace data. The office_agent.token.usage event is emitted on each agent.stream span, once per non-zero token type, with attributes {token_usage.type: input | output | cacheRead | cacheCreation, token_usage.model, token_usage.token_count}. This mirrors the *.token.usage counter shape emitted by other Anthropic products, so a single collector can aggregate token cost across products by grouping on service.name.
Surface-specific behavior
The telemetry schema is consistent across all surfaces. These are the differences:
Sheets (Excel):
agent.tool_executionspans includesheet.cells_read,sheet.cells_written, andsheet.cells_copiedattributes.office_agent.cell_edit_collision_totalspan events appear when a user is mid-cell-edit while a tool tries to write.Documents (Word): document-edit funnel events track the edit lifecycle:
office_agent.doc_edit_received_total,office_agent.doc_edit_parsed_total,office_agent.doc_edit_applied_total,office_agent.doc_proposed_edit_reviewed_total. Nosheet.cells_*attributes.Slides (PowerPoint): no surface-specific attributes or events beyond the common schema.
Reconstructing a user session
Claude.ai deployments
Filter spans by
user.email(oruser.account_uuid) andsession.id.Order
agent.queryspans by start timestamp; each is one user turn.For each turn,
user.messageis the prompt anddocument.urlis the file being worked on.Child
agent.tool_executionspans, ordered by timestamp, are the actions taken:tool.inputis what was attempted,tool.outputis the result,tool.accept_decisionrecords whether the user explicitly approved.
Direct provider deployments
The add-in has no Claude.ai user identity in this mode, so spans carry no user.email or user.account_uuid. To attribute activity to a user:
Filter spans by
session.idto isolate one continuous add-in session.Use
document.urlto identify the file being worked on.Correlate the session against your identity provider's logs: Entra sign-in events, gateway access logs, or your bootstrap endpoint's request log (which receives the user's Entra ID token as a Bearer header).
Once a session is attributed to a user, the per-turn reconstruction is identical: agent.query spans ordered by timestamp, with
user.message,tool.input,tool.output, andtool.accept_decisionproviding the audit trail.
This produces a complete, ordered transcript of the interaction in both deployment modes.
