Skip to main content
properties attaches arbitrary key/value pairs to a span. Values pass through as-is, with no namespace prefix, so they stay readable by other OTel backends after a switch.

Usage

properties is also accepted by:
  • bento.begin(properties=...)
  • interaction.update(properties=...)
  • interaction.finish(properties=...)
  • bento.tool_span(name, properties=...)
  • interaction.tool_span(name, properties=...)

Type fidelity

Property values keep their type so downstream filters and aggregates work correctly:
Don’t put gen_ai.*, input.value, or output.value keys in properties. The SDK-managed kwargs are written after properties and will overwrite them. Use the dedicated kwargs (user_id, model, provider, input, output, convo_id) instead.

Properties vs built-in kwargs

User, conversation, model, provider, input, and output have dedicated kwargs, because the dashboard has filters and breakdowns built for them. Everything else goes in properties: feature flags, experiment buckets, latency, retrieved-chunk count. Each one becomes a generic filter and breakdown dimension. A property that proves widely useful can get promoted to a first-class column. Until then, anything in properties lands in spans.attributes as JSONB, queryable from custom dashboards.