OTel GenAI Span Validator
Validate an OpenTelemetry span's gen_ai.* attributes against the official GenAI semantic conventions — attribute types, enum values, required fields per operation, and span-name template conformance. Runs entirely in your browser.
🔒 Runs entirely in your browser — no data is ever sent anywhereWhat the GenAI semantic conventions are
When an LLM call, an agent invocation, or a tool execution is instrumented with OpenTelemetry, the resulting span is supposed to carry a standardized set of gen_ai.* attributes — the model requested, token usage, the provider, and so on — so that any OTel-compatible backend can render consistent dashboards regardless of which library or provider produced the trace. That standard is the GenAI semantic conventions, recently split out into its own dedicated repository and still explicitly marked Development stability: attribute names and requirement levels are still settling, unlike the long-stable HTTP or database conventions. There's no hosted tool to check a span against it — the only real conformance checker is Weaver, a Rust CLI that runs in CI against a live registry, not something you can paste a span into.
What this tool checks
Paste a single OTLP JSON span (the {"name":..., "attributes":[{"key":...,"value":{"stringValue":...}}]} shape a real collector export uses), a full resourceSpans trace export (every span inside is checked), or a flattened plain object of gen_ai.* key/value pairs for quick manual testing. For each span, it looks up gen_ai.operation.name to determine the expected span type (chat/generate_content/text_completion, embeddings, retrieval, fetch_response, create_agent, invoke_agent, execute_tool, invoke_workflow, plan, or one of the memory operations) and checks that type's unconditionally-required attributes are present, validates every recognized gen_ai.* attribute's type (string, int, double, boolean, string array) and enum membership (gen_ai.provider.name, gen_ai.output.type, gen_ai.response.status, gen_ai.token.type) against the registry, flags any gen_ai.* key not in the registry at all, and — when the span has a name and enough attributes to compute one — checks it against that operation's documented span-name template (e.g. "{operation} {model}" for an inference span). All of this is checked against the semantic-conventions-genai repository's own machine-readable attribute registry and span definitions, downloaded and read directly rather than summarized from a blog post.
Frequently asked questions
Why does it need gen_ai.operation.name to check anything else?
The required-attribute set and the span-name template are both defined per operation (a chat span needs gen_ai.request.model and gen_ai.provider.name; an execute_tool span needs gen_ai.tool.name instead, and neither needs the other's fields). Without a recognized operation.name, this tool falls back to only checking the type/enum shape of whatever gen_ai.* attributes are present, since it has no basis for which ones should exist.
It didn't flag a missing field I expected — why?
Only unconditionally-required attributes are enforced as violations. Many attributes are conditionally required ("if applicable", "if the request includes a seed") or opt-in (message content, tool arguments — gated behind explicit consent since they can carry sensitive data). This tool can't evaluate runtime conditions from a single span in isolation, so it doesn't guess at those — a clean report means the unconditional requirements are met, not that every optional field you might expect is present.
Does it support the full OTLP protobuf format?
It supports OTLP's JSON encoding (the format a real collector's HTTP JSON exporter produces, or what you'd get from a text-based trace-log pipeline) — either a full resourceSpans export or a single span object with an attributes array. It doesn't parse binary protobuf; export as JSON first if your pipeline produces protobuf.
The conventions are still 'Development' stability — will this go stale?
Likely, at least partially — attribute names and requirement levels in this space are actively being revised. Treat a flagged attribute as a prompt to check the current registry at github.com/open-telemetry/semantic-conventions-genai, not an unappealable verdict, the same way you would with any other tool here validating against an evolving spec.
Is my pasted data sent anywhere?
No. Parsing and validation both run locally in your browser with plain JavaScript — nothing you paste is transmitted or stored.
Related AI tools
Token Counter
Count tokens for GPT-5, GPT-4o, and older OpenAI models as you type, using the exact same tokenizer OpenAI's API uses.
Citations Viewer
Paste a Claude Citations API response to see the answer text with each cited passage highlighted and matched to its source document, location, and quoted text.
Signature Validator
Getting a 400 error or silently broken multi-turn tool use from the Gemini 3 API? Paste your request or response to check function-calling turns for missing thoughtSignature fields, functionResponse ordering mistakes, and missing id echoes.
MCP Validator
Paste a Model Context Protocol tool definition — a single tool object, an array, or a full tools/list response — to check it against the spec: missing name or inputSchema, a name most clients will reject, a required property that doesn't exist, malformed annotations, and more.
Bracketly is free and open-source. If this tool saved you time, consider supporting it.
☕ Buy me a coffee