Two libraries trace the same HTTP call. One writes method=GET, the other http.verb=get. Your dashboard now needs two queries for one thing. Semantic conventions exist so that doesn’t happen.
What do the conventions define?
Common names for operations and their data (OpenTelemetry docs). For a span, that means:
| Part | Example |
|---|---|
| Span name | execute_tool {gen_ai.tool.name} |
| Attribute key | http.request.method, error.type |
| Attribute value | GET, _OTHER |
| Span kind | CLIENT for an outgoing call |
They cover traces, metrics, logs, profiles and resources. A backend that knows error.type can group errors from any library that follows the convention.
Stable or Development?
Every convention has a stability level, and it matters more than the name.
- Stable. Attributes, metrics and span events can’t be renamed or removed. New attributes can be added (versioning and stability).
http.request.methodanderror.typeare Stable. - Development. Anything can still change. All the GenAI conventions,
invoke_agent,execute_toolandgen_ai.agent.idincluded, are Development. - Deprecated. Replaced by something else and kept for a while.
The JavaScript package shows the split. Stable names come from the main entry point, Development names from /incubating:
import { ATTR_ERROR_TYPE, ATTR_HTTP_REQUEST_METHOD } from '@opentelemetry/semantic-conventions';import { ATTR_GEN_AI_AGENT_ID, ATTR_GEN_AI_OPERATION_NAME } from '@opentelemetry/semantic-conventions/incubating';
console.log(ATTR_ERROR_TYPE, ATTR_HTTP_REQUEST_METHOD); // stableconsole.log(ATTR_GEN_AI_AGENT_ID, ATTR_GEN_AI_OPERATION_NAME); // developmenterror.type http.request.methodgen_ai.agent.id gen_ai.operation.nameIn version 1.43.0, ATTR_GEN_AI_AGENT_ID is already marked deprecated. The name gen_ai.agent.id didn’t change: the GenAI conventions moved to their own repository in 2026, and the package points there. The package README advises libraries to copy incubating names into their own code instead of importing them at runtime, since minor versions can break them.
What if there’s no convention for your domain?
Pick a namespace and treat it as a public API. Renaming an attribute later breaks someone’s dashboard, the same way a renamed function breaks someone’s build.