tessary.call_site.id.
For the practical subset, meaning what you have to emit to get a working project, read Span requirements. This page is the exhaustive lookup behind it.
Where spans arrive
Both transports write down the same path, so a stored span is identical no matter how it arrived. See API keys for the credential and its errors, and Configuration for the transport variables.
How to read the tables
- Field is the wire name. There is one spelling per field. Tessary reads exactly the names listed here, with no compatibility aliases and no deprecated-spelling fallbacks.
- Applies to says which spans the field is read for.
alwaysmeans every span; otherwise it names thegen_ai.operation.namefamily or the carrier the field is only read on. - Origin says where the name comes from:
OTLP protofor a protobuf span field rather than an attribute,OTel semconvfor the general semantic conventions,gen_ai semconvfor the GenAI conventions,OpenInferenceandTraceloopfor third-party dialects accepted for compatibility,Tessaryfor the one overlay attribute,carrier extensionfor the genericinputandoutputcarriers, andanyfor the attribute bag.
Identity and timing
There is no attribute for a turn. The turn is the trace: one turn per producer trace id, with no separate node.
Status and errors
error.type has one precedence: the producer’s own error.type wins, and only when it is absent does status.message supply the label, whitespace-collapsed and capped at 120 characters. State neither and the tool-call column keeps a placeholder, because a failure with no label is still a failure, while the span column stays null.
error_type is a label for grouping failures. The full prose stays recoverable from the stored payload.
Session, thread, and end user
Kind
gen_ai.operation.name is the single kind source. It is an open enum: retrieval, rerank, guardrail, plan, reasoning, and handoff are Tessary’s accepted extension values, and any name containing memory normalizes to memory.
Three more attributes refine or stand in for the kind.
Handoffs are structural
A handoff between agents needs no attribute. It is already wire-encoded as anexecute_tool span for the transfer call emitted by the first agent, followed by an invoke_agent span for the second under the same parent, which is the shape agent-framework instrumentation already emits. Ingest marks both spans truthfully, and the relationship is derivable from the span graph at read time. A producer that wants to state it explicitly may emit gen_ai.operation.name = handoff.
Tool calls
Model
Both spellings are kept because they answer different questions.
provided_model_name is what the producer said; model_id is the resolved catalog key the price book is stated in.
Content
Message content is never truncated at ingest. It is bounded by count, not by size.Payloads pass through PII redaction on the way in. The rules in force, including the built-in defaults, are on Settings → PII redaction.
Token usage
Tessary keeps the raw usage object in the span payload as an audit record and never reads it for arithmetic. When the producer reports no cost of its own, these buckets are priced on arrival from the price book with
cost_source='inferred', and never repriced.
Cost
Per-bucket figures win over any total. A lone total lands in
input_cost, because the span’s total cost is generated from the four buckets and splitting a total across them would be a derivation rather than a reading.
Retrieved documents
Call site
This is the only sanctioned Tessary overlay attribute, and the dotted spelling roots a
tessary.call_site.* namespace. Any producer can set it as a plain attribute, or a Collector attributes or transform rule can add it. No SDK is required.
Without it, a span still lands and is still queryable, but it belongs to no call site, and the connect gate on a new project does not open on it. An untagged span carries a null call_site_id, so a filter on any call site excludes it outright.
Everything else
Accepted but not consumed
These arrive without being rejected and survive verbatim in the attribute bag. They drive nothing. Do not build against them.Attributes with no reader
The consumedtessary.* surface is exactly one attribute. Every other tessary.* spelling has no reader anywhere on the platform, and its content belongs on the standard field instead.
Ad-hoc alias spellings of canonical fields are never read either.
sessionId, userId, user_id, enduser.id, and deployment.environment all fall in this category.
Limits
How long a stored trace survives afterward is a separate setting: see Data retention.
Invariants
Four rules govern how this contract changes.- Standard first. A new field uses the OTel or gen_ai name when one exists.
tessary.*is only for genuine gaps. - Ingest fails open. The absence of any non-structural field degrades a feature. It never drops a span.
- Content is verbatim. Message and tool content is never truncated at ingest. The one exception is the 8,000,000-character payload cap above, which drops the span rather than clipping it.
- No compatibility aliases. Only the canonical spelling of each field is read. Third-party dialects are normalized at the edge as documented product features; ad-hoc alias spellings are not.
Related pages
Span requirements
The practical subset: what to emit to get a working project.
API keys
The write-scoped credential ingest requires, and the errors it returns.
MCP server
How an agent reads these fields back, dataset by dataset.
Configuration reference
The OTLP transport, ingest buffer, and retention variables.
