Insight OTel Ingestion Semantic Conventions
Insight accepts OpenTelemetry (OTLP) trace data and converts it into traces and observations. This page documents every span attribute the ingestion endpoint recognizes, how attributes are resolved across frameworks, and how observation types, usage, and costs are extracted.
How It Works
When you send OTLP spans to Insight, the ingestion processor:
- Extracts resource attributes (set once per exporter, e.g.
service.name,deployment.environment) - Extracts span attributes (set per span)
- Resolves each concept (input, output, model name, etc.) by checking multiple attribute keys in priority order -- the first non-empty value wins
- Maps the span to an observation type (GENERATION, TOOL, AGENT, etc.) using a priority-ordered mapper registry
- Extracts usage details (token counts) and cost details from framework-specific attributes
- Produces a trace event (from the root span or spans with trace-level attributes) and an observation event (from every span)
Attribute Priority
For each concept, the processor checks attribute keys in a defined order. For example, to resolve the model name it checks insight.observation.model.name first, then langfuse.observation.model.name, then gen_ai.response.model, and so on. The first non-empty value found is used.
Span attributes are checked before resource attributes. If a value is not found on the span, certain attributes (environment, session ID, run ID, tags) fall back to resource attributes.
Supported Frameworks
Insight recognizes attributes from the following SDKs and frameworks out of the box. You do not need to do any special configuration -- just send OTLP spans and the processor will detect the format automatically.
| Framework / SDK | Attribute Namespace | Notes |
|---|---|---|
| Mantis Insight SDK | insight.* | Primary namespace, highest priority |
| Langfuse SDK | langfuse.* | Compatibility with upstream Langfuse |
| OpenInference | openinference.*, input.value, output.value, llm.* | Used by Arize, Agno, BeeAI, and others |
| OTel GenAI Semconv | gen_ai.* | Standard OpenTelemetry semantic conventions for generative AI |
| Vercel AI SDK | ai.*, operation.name | Vercel's AI SDK telemetry |
| Pydantic AI | gen_ai.*, tool_arguments, tool_response | Via Logfire or direct OTel export |
| MLFlow | mlflow.spanInputs, mlflow.spanOutputs | MLFlow tracing |
| TraceLoop | traceloop.entity.* | OpenLLMetry / TraceLoop SDK |
| Google ADK | gcp.vertex.agent.* | Google Agent Developer Kit |
| LiveKit | lk.* | LiveKit Agents framework |
| Logfire | prompt, all_messages_events, logfire.msg | Pydantic Logfire |
| SmolAgents | input.value, output.value | HuggingFace SmolAgents |
| Pipecat | input, output | Pipecat framework |
| AgentOps | workflow.*, agent.*, final_output | AgentOps SDK |
| CrewAI | crewai.*, task_input, task_output | CrewAI framework |
| Semantic Kernel | gen_ai.content.prompt, gen_ai.content.completion | Via span events (legacy) |
Attribute Reference
The tables below list every attribute key that Insight recognizes, grouped by category. Within each group, keys are listed in priority order -- earlier entries take precedence.
Trace-Level Attributes
These attributes are extracted from the root span (or any span that sets them) and applied to the trace.
Trace Name
| Priority | Attribute Key | Source |
|---|---|---|
| 1 | insight.trace.name | Insight SDK |
| 2 | langfuse.trace.name | Langfuse SDK |
Falls back to the OTel span name if neither is set.
Trace Input
| Priority | Attribute Key | Source |
|---|---|---|
| 1 | insight.trace.input | Insight SDK |
| 2 | langfuse.trace.input | Langfuse SDK |
Trace Output
| Priority | Attribute Key | Source |
|---|---|---|
| 1 | insight.trace.output | Insight SDK |
| 2 | langfuse.trace.output | Langfuse SDK |
Trace System Prompt
| Priority | Attribute Key | Source |
|---|---|---|
| 1 | insight.trace.system_prompt | Insight SDK |
Stored in trace metadata under the system_prompt key.
Trace Metadata
| Priority | Attribute Key | Source |
|---|---|---|
| 1 | insight.trace.metadata | Insight SDK |
| 2 | langfuse.trace.metadata | Langfuse SDK |
Accepts a JSON string. Nested metadata keys are also supported via the langfuse.trace.metadata.* prefix pattern (e.g. langfuse.trace.metadata.myKey).
Trace Public
| Priority | Attribute Key | Source |
|---|---|---|
| 1 | insight.trace.public | Insight SDK |
| 2 | langfuse.trace.public | Langfuse SDK |
| 3 | langfuse.public | Langfuse SDK (legacy) |
Boolean. Accepts true, "true", or truthy values.
Trace Tags
| Priority | Attribute Key | Source |
|---|---|---|
| 1 | insight.trace.tags | Insight SDK |
| 2 | langfuse.trace.tags | Langfuse SDK |
| 3 | langfuse.tags | Langfuse SDK (legacy) |
| 4 | langfuse.observation.metadata.langfuse_tags | Langfuse SDK (metadata) |
| 5 | langfuse.trace.metadata.langfuse_tags | Langfuse SDK (metadata) |
| 6 | ai.telemetry.metadata.tags | Vercel AI SDK |
| 7 | tag.tags | Generic |
Accepts a JSON array string (e.g. '["prod", "v2"]') or an array value. Also checked on resource attributes as a fallback.
User and Session
User ID
| Priority | Attribute Key | Source |
|---|---|---|
| 1 | insight.user.id | Insight SDK |
| 2 | langfuse.user.id | Langfuse SDK |
| 3 | user.id | Generic OTel |
| 4 | langfuse.observation.metadata.langfuse_user_id | Langfuse SDK (metadata) |
| 5 | langfuse.trace.metadata.langfuse_user_id | Langfuse SDK (metadata) |
| 6 | ai.telemetry.metadata.userId | Vercel AI SDK |
Session ID
| Priority | Attribute Key | Source |
|---|---|---|
| 1 | insight.session.id | Insight SDK |
| 2 | langfuse.session.id | Langfuse SDK |
| 3 | session.id | Generic OTel |
| 4 | gen_ai.conversation.id | OTel GenAI Semconv |
| 5 | langfuse.observation.metadata.langfuse_session_id | Langfuse SDK (metadata) |
| 6 | langfuse.trace.metadata.langfuse_session_id | Langfuse SDK (metadata) |
| 7 | ai.telemetry.metadata.sessionId | Vercel AI SDK |
Also checked on resource attributes as a fallback.
Run ID
| Priority | Attribute Key | Source |
|---|---|---|
| 1 | insight.run.id | Insight SDK |
| 2 | run.id | Generic |
| 3 | mantis.run.id | Mantis SDK |
| 4 | experiment.id | Generic |
Also checked on resource attributes as a fallback. Automatically set when traces are created within a mantisdk.run context.
Environment and Version
Environment
| Priority | Attribute Key | Source |
|---|---|---|
| 1 | insight.environment | Insight SDK |
| 2 | langfuse.environment | Langfuse SDK |
| 3 | deployment.environment.name | OTel Resource Semconv |
| 4 | deployment.environment | OTel Resource Semconv (legacy) |
Checked on both span and resource attributes. Defaults to "default" if not set.
Version
| Priority | Attribute Key | Source |
|---|---|---|
| 1 | insight.version | Insight SDK |
| 2 | langfuse.version | Langfuse SDK |
| 3 | service.version | OTel Resource Semconv |
Release
| Priority | Attribute Key | Source |
|---|---|---|
| 1 | insight.release | Insight SDK |
| 2 | langfuse.release | Langfuse SDK |
Observation-Level Attributes
These attributes are extracted from every span and applied to the observation.
Observation Type
| Priority | Attribute Key | Source |
|---|---|---|
| 1 | insight.observation.type | Insight SDK |
| 2 | langfuse.observation.type | Langfuse SDK |
| 3 | openinference.span.kind | OpenInference |
| 4 | gen_ai.operation.name | OTel GenAI Semconv |
See Observation Type Mapping below for the full mapping rules.
Observation Input
| Priority | Attribute Key | Source |
|---|---|---|
| 1 | insight.observation.input | Insight SDK |
| 2 | langfuse.observation.input | Langfuse SDK |
| 3 | input.value | OpenInference / SmolAgents |
| 4 | input | Pydantic AI / Pipecat |
| 5 | traceloop.entity.input | TraceLoop |
| 6 | mlflow.spanInputs | MLFlow |
| 7 | gen_ai.input.messages | OTel GenAI Semconv |
| 8 | gen_ai.tool.call.arguments | OTel GenAI (tools) |
| 9 | ai.prompt.messages | Vercel AI SDK |
| 10 | ai.prompt | Vercel AI SDK |
| 11 | ai.toolCall.args | Vercel AI SDK |
| 12 | gcp.vertex.agent.llm_request | Google ADK |
| 13 | gcp.vertex.agent.tool_call_args | Google ADK (tools) |
| 14 | lk.input_text | LiveKit |
| 15 | prompt | Logfire |
| 16 | tool_arguments | Pydantic AI (tools) |
| 17 | workflow.input | AgentOps |
| 18 | agent.input | AgentOps |
| 19 | crewai.task.input | CrewAI |
| 20 | crewai.agent.input | CrewAI |
| 21 | task_input | CrewAI (alt) |
Additional input sources via span events and prefix-based patterns are documented in Span Events and Prefix-Based Input/Output.
Observation Output
| Priority | Attribute Key | Source |
|---|---|---|
| 1 | insight.observation.output | Insight SDK |
| 2 | langfuse.observation.output | Langfuse SDK |
| 3 | output.value | OpenInference / SmolAgents |
| 4 | output | Pydantic AI / Pipecat |
| 5 | traceloop.entity.output | TraceLoop |
| 6 | mlflow.spanOutputs | MLFlow |
| 7 | gen_ai.output.messages | OTel GenAI Semconv |
| 8 | gen_ai.tool.call.result | OTel GenAI (tools) |
| 9 | ai.response.text | Vercel AI SDK |
| 10 | ai.result.text | Vercel AI SDK (legacy, < 4.0) |
| 11 | ai.toolCall.result | Vercel AI SDK |
| 12 | ai.response.object | Vercel AI SDK |
| 13 | ai.result.object | Vercel AI SDK (legacy, < 4.0) |
| 14 | ai.response.toolCalls | Vercel AI SDK |
| 15 | ai.result.toolCalls | Vercel AI SDK (legacy, < 4.0) |
| 16 | gcp.vertex.agent.llm_response | Google ADK |
| 17 | gcp.vertex.agent.tool_response | Google ADK (tools) |
| 18 | lk.function_tool.output | LiveKit |
| 19 | lk.response.text | LiveKit |
| 20 | all_messages_events | Logfire |
| 21 | tool_response | Pydantic AI (tools) |
| 22 | workflow.output | AgentOps |
| 23 | final_output | AgentOps |
| 24 | agent.output | AgentOps |
| 25 | crewai.task.output | CrewAI |
| 26 | crewai.agent.output | CrewAI |
| 27 | task_output | CrewAI (alt) |
| 28 | result | Generic fallback |
Vercel AI SDK special case: When both ai.response.text and ai.response.toolCalls are present, the output is combined into a structured object with role, content, and tool_calls fields.
Observation Metadata
| Priority | Attribute Key | Source |
|---|---|---|
| 1 | insight.observation.metadata | Insight SDK |
| 2 | langfuse.observation.metadata | Langfuse SDK |
| 3 | langfuse.metadata | Langfuse SDK (shorthand) |
| 4 | ai.telemetry.metadata | Vercel AI SDK |
Accepts a JSON string. Nested keys via the langfuse.observation.metadata.* prefix are also supported.
Observation Level
| Priority | Attribute Key | Source |
|---|---|---|
| 1 | insight.observation.level | Insight SDK |
| 2 | langfuse.observation.level | Langfuse SDK |
Valid values: DEBUG, DEFAULT, WARNING, ERROR.
If not set, defaults to ERROR when the OTel span status code is 2 (ERROR), otherwise DEFAULT.
Observation Status Message
| Priority | Attribute Key | Source |
|---|---|---|
| 1 | insight.observation.status_message | Insight SDK |
| 2 | langfuse.observation.status_message | Langfuse SDK |
Falls back to the OTel span status.message field.
Model and Generation
Model Name
| Priority | Attribute Key | Source |
|---|---|---|
| 1 | insight.observation.model.name | Insight SDK |
| 2 | langfuse.observation.model.name | Langfuse SDK |
| 3 | gen_ai.response.model | OTel GenAI Semconv |
| 4 | ai.model.id | Vercel AI SDK |
| 5 | gen_ai.request.model | OTel GenAI Semconv |
| 6 | llm.response.model | OpenInference |
| 7 | llm.model_name | OpenInference (legacy) |
| 8 | model | Generic |
Model Parameters
| Priority | Attribute Key | Source |
|---|---|---|
| 1 | insight.observation.model.parameters | Insight SDK (JSON string) |
| 2 | langfuse.observation.model.parameters | Langfuse SDK (JSON string) |
| 3 | llm.invocation_parameters | OpenInference (JSON string) |
| 4 | model_config | Generic (JSON string) |
Additionally, any attributes matching the gen_ai.request.* prefix (excluding gen_ai.request.model) are collected as model parameters.
Vercel AI SDK special case: When the instrumentation scope is ai, the following attributes are extracted into model parameters:
| Attribute | Parameter Key |
|---|---|
ai.settings.maxSteps | maxSteps |
ai.prompt.toolChoice | toolChoice |
gen_ai.request.max_tokens | maxTokens |
gen_ai.response.finish_reasons or gen_ai.finishReason | finishReason |
gen_ai.system or ai.model.provider | system |
ai.settings.maxRetries | maxRetries |
ai.settings.mode | mode |
gen_ai.request.temperature | temperature |
Completion Start Time
| Priority | Attribute Key | Source |
|---|---|---|
| 1 | langfuse.observation.completion_start_time | Langfuse SDK |
For Vercel AI SDK, computed from ai.response.msToFirstChunk or ai.stream.msToFirstChunk added to the span start time.
Prompt Management
Prompt Name
| Priority | Attribute Key | Source |
|---|---|---|
| 1 | langfuse.observation.prompt.name | Langfuse SDK |
| 2 | langfuse.prompt.name | Langfuse SDK (shorthand) |
Also extracted from Vercel AI SDK's ai.telemetry.metadata.langfusePrompt JSON field.
Prompt Version
| Priority | Attribute Key | Source |
|---|---|---|
| 1 | langfuse.observation.prompt.version | Langfuse SDK |
| 2 | langfuse.prompt.version | Langfuse SDK (shorthand) |
Also extracted from Vercel AI SDK's ai.telemetry.metadata.langfusePrompt JSON field.
Observation Type Mapping
Every span is mapped to an observation type using a priority-ordered registry. Mappers are evaluated from lowest priority number (highest precedence) to highest. The first mapper that both matches and returns a type wins.
Valid Observation Types
SPAN, GENERATION, EVENT, EMBEDDING, AGENT, TOOL, CHAIN, RETRIEVER, GUARDRAIL, EVALUATOR
If no mapper matches, the span defaults to type SPAN.
Mapper Priority Order
Priority 0 -- Python SDK v3.3.0 and Earlier Override
Handles a known bug in older Langfuse Python SDK versions where generation-like spans were incorrectly labeled as span. If the scope name is langfuse-sdk, the SDK language is python, and version is 3.3.0 or earlier, the presence of generation attributes (model, usage, cost, etc.) overrides the type to GENERATION.
Priority 1 -- Direct Type Attribute
Reads langfuse.observation.type or insight.observation.type and maps directly:
| Attribute Value | Observation Type |
|---|---|
span | SPAN |
generation | GENERATION |
event | EVENT |
embedding | EMBEDDING |
agent | AGENT |
tool | TOOL |
chain | CHAIN |
retriever | RETRIEVER |
guardrail | GUARDRAIL |
evaluator | EVALUATOR |
Priority 2 -- OpenInference
Reads openinference.span.kind:
| Attribute Value | Observation Type |
|---|---|
CHAIN | CHAIN |
RETRIEVER | RETRIEVER |
LLM | GENERATION |
EMBEDDING | EMBEDDING |
AGENT | AGENT |
TOOL | TOOL |
GUARDRAIL | GUARDRAIL |
EVALUATOR | EVALUATOR |
Priority 3 -- OTel GenAI Operation
Reads gen_ai.operation.name:
| Attribute Value | Observation Type |
|---|---|
chat | GENERATION |
completion | GENERATION |
text_completion | GENERATION |
generate_content | GENERATION |
generate | GENERATION |
embeddings | EMBEDDING |
invoke_agent | AGENT |
create_agent | AGENT |
execute_tool | TOOL |
Priority 4 -- Vercel AI SDK (Generation / Embedding)
Matches when model information is present (ai.model.id, gen_ai.request.model, etc.) and the operation name matches one of:
| Operation Name Prefix | Observation Type |
|---|---|
ai.generateText.doGenerate | GENERATION |
ai.streamText.doStream | GENERATION |
ai.generateObject.doGenerate | GENERATION |
ai.streamObject.doStream | GENERATION |
ai.embedMany.doEmbed | EMBEDDING |
ai.embed.doEmbed | EMBEDDING |
Checked via both operation.name (prefix match) and ai.operationId (exact match).
Priority 5 -- Vercel AI SDK (Tool Calls)
Matches any ai.* operation that is not a generation or embedding:
| Operation Name Prefix | Observation Type |
|---|---|
ai.toolCall | TOOL |
Priority 6 -- GenAI Tool Call Detection
Matches when gen_ai.tool.name or gen_ai.tool.call.id is present. Used by Pydantic AI and other frameworks that set GenAI tool attributes without setting gen_ai.operation.name.
Result: TOOL
Priority 7 -- Model-Based Fallback
If any model-related attribute is present (langfuse.observation.model.name, gen_ai.request.model, gen_ai.response.model, llm.model_name, or model), the span is classified as a GENERATION.
Usage and Cost Extraction
Token Usage
Token usage is extracted differently depending on the instrumentation source. The processor normalizes all formats into a standard usageDetails object with keys like input, output, total, input_cached_tokens, output_reasoning_tokens, etc.
Langfuse / Insight SDK
| Attribute | Description |
|---|---|
langfuse.observation.usage_details | JSON string with full usage details |
Vercel AI SDK (scope name: ai)
| Attribute | Maps To |
|---|---|
gen_ai.usage.prompt_tokens or gen_ai.usage.input_tokens | input |
gen_ai.usage.completion_tokens or gen_ai.usage.output_tokens | output |
ai.usage.tokens | total |
ai.usage.cachedInputTokens | input_cached_tokens |
ai.usage.reasoningTokens | output_reasoning_tokens |
Provider metadata fallback: If the extended usage attributes are not present, the processor reads ai.response.providerMetadata (a JSON string) and extracts provider-specific details:
- OpenAI:
cachedPromptTokens,acceptedPredictionTokens,rejectedPredictionTokens,reasoningTokens - Anthropic:
cacheCreationInputTokens,cacheReadInputTokens - Bedrock:
usage.cacheReadInputTokens,usage.cacheWriteInputTokens,usage.cacheCreationInputTokens
Cached token counts are subtracted from the total input count to avoid double-counting.
Pydantic AI (scope name: pydantic-ai)
| Attribute | Maps To |
|---|---|
gen_ai.usage.input_tokens | input |
gen_ai.usage.output_tokens | output |
gen_ai.usage.cache_read_tokens or gen_ai.usage.details.cache_read_input_tokens | input_cache_read |
gen_ai.usage.cache_write_tokens or gen_ai.usage.details.cache_creation_input_tokens | input_cache_creation |
Generic (all other frameworks)
Any attributes matching gen_ai.usage.* or llm.token_count.* are collected. Standard key mappings:
| Raw Key Suffix | Normalized Key |
|---|---|
prompt_tokens | input |
completion_tokens | output |
total_tokens | total |
input_tokens | input |
output_tokens | output |
prompt | input |
completion | output |
All other suffixes are kept as-is (e.g. gen_ai.usage.reasoning_tokens becomes reasoning_tokens).
Cost
| Attribute | Description |
|---|---|
langfuse.observation.cost_details | JSON string with cost breakdown (Langfuse SDK only) |
gen_ai.usage.cost | Total cost as a number, stored as { total: value } |
Span Events
In addition to span attributes, the processor extracts input and output from OTel span events (the events array on a span). This is used by frameworks that follow the OTel GenAI event-based conventions.
GenAI Message Events
These events are collected as the input to the observation:
| Event Name | Role |
|---|---|
gen_ai.system.message | system |
gen_ai.user.message | user |
gen_ai.assistant.message | assistant |
gen_ai.tool.message | tool |
Each event's attributes are included in the message object.
GenAI Choice Events
| Event Name | Usage |
|---|---|
gen_ai.choice | Extracted as the output |
If a single choice event exists, it is returned as the output directly. Multiple choice events are returned as an array.
Legacy Semantic Kernel Events
| Event Name | Usage |
|---|---|
gen_ai.content.prompt | Input |
gen_ai.content.completion | Output |
Logfire Events Array
Logfire sends a stringified events attribute containing GenAI events. The processor parses this and extracts gen_ai.choice events as output and all other events as input.
Prefix-Based Input/Output
Some frameworks use flattened attribute keys with numeric indices to represent structured messages. The processor reassembles these into nested objects:
GenAI Prompt/Completion Prefix
Attributes starting with gen_ai.prompt.* are reassembled into an input object. Attributes starting with gen_ai.completion.* are reassembled into an output object. Used by TraceLoop and similar frameworks.
Example: gen_ai.prompt.0.content + gen_ai.prompt.0.role becomes [{ content: "...", role: "..." }]
OpenInference LLM Messages Prefix
Attributes starting with llm.input_messages.* are reassembled into input. Attributes starting with llm.output_messages.* are reassembled into output. Used by Agno, BeeAI, and OpenInference instrumentors.
Observation Name Extraction
The observation name is determined by this priority:
gen_ai.tool.name-- for tool-type observationslogfire.msg-- for Pydantic AI / Logfire spansai.toolCall.name-- for Vercel AI SDK tool callsai.telemetry.functionId+ai.operationId-- for Vercel AI SDK operations (formatted asfunctionId:operationId)- The OTel span name -- default fallback
Resource Attributes
Resource attributes are set once per exporter instance and apply to all spans in the batch. The following attributes are checked on resource attributes as a fallback when not found on span attributes:
environment(deployment.environment.name,deployment.environment)session.idrun.idtagsversion(service.version)release
Resource attributes are also stored in the observation and trace metadata under the resourceAttributes key for debugging purposes.
Quick Reference
Insight SDK Attributes (Primary Namespace)
These are the recommended attributes when instrumenting with the Mantis Insight SDK:
insight.trace.name
insight.trace.input
insight.trace.output
insight.trace.system_prompt
insight.trace.metadata
insight.trace.tags
insight.trace.public
insight.user.id
insight.session.id
insight.run.id
insight.environment
insight.release
insight.version
insight.observation.type
insight.observation.input
insight.observation.output
insight.observation.metadata
insight.observation.level
insight.observation.status_message
insight.observation.model.name
insight.observation.model.parametersUsing with MantisDK
If you are using the MantisDK Python SDK, these attributes are available as constants:
import mantisdk.tracing as tracing
with tracing.trace("my-workflow", input=query) as span:
span.set_attribute(tracing.semconv.USER_ID, "user-123")
span.set_attribute(tracing.semconv.SESSION_ID, "session-456")
span.set_attribute(tracing.semconv.TRACE_OUTPUT, result)See the MantisDK Semantic Conventions page for the full SDK constant reference.