# Span Attributes

groundcover adheres to the [OpenTelemetry GenAI Semantic Conventions](https://opentelemetry.io/docs/specs/semconv/gen-ai/). The more attributes your spans carry, the richer the experience — cost analytics, prompt debugging, execution chain visibility.

For how groundcover handles older SDK attribute conventions (Era 1 `gen_ai.prompt`/`gen_ai.completion` and Era 2 log events), see [OTel GenAI Conventions](/use-groundcover/ai-observability.md#otel-genai-conventions).

***

## Core Attributes

| Attribute                        | Type      | Description                      |
| -------------------------------- | --------- | -------------------------------- |
| `gen_ai.provider.name`           | string    | GenAI provider                   |
| `gen_ai.operation.name`          | string    | Operation type                   |
| `gen_ai.request.model`           | string    | Model requested                  |
| `gen_ai.response.model`          | string    | Model that responded             |
| `gen_ai.response.id`             | string    | Completion ID                    |
| `gen_ai.usage.input_tokens`      | int       | Tokens consumed by the prompt    |
| `gen_ai.usage.output_tokens`     | int       | Tokens generated in the response |
| `gen_ai.response.finish_reasons` | string\[] | Why the model stopped            |
| `gen_ai.conversation.id`         | string    | Session/thread identifier        |

***

## Additional Attributes

### Token Usage

| Attribute                                  | Type | Description                             |
| ------------------------------------------ | ---- | --------------------------------------- |
| `gen_ai.usage.cache_read.input_tokens`     | int  | Input tokens served from provider cache |
| `gen_ai.usage.cache_creation.input_tokens` | int  | Input tokens written to provider cache  |

### Content

| Attribute                    | Type | Description                               |
| ---------------------------- | ---- | ----------------------------------------- |
| `gen_ai.input.messages`      | JSON | Structured input messages (role + parts)  |
| `gen_ai.output.messages`     | JSON | Structured output messages (role + parts) |
| `gen_ai.system_instructions` | JSON | System prompt, separate from chat history |
| `gen_ai.tool.definitions`    | JSON | Tool schemas passed to the model          |

eBPF captures content automatically for supported providers. For SDK instrumentation, content capture is controlled by your SDK configuration — see [Privacy Controls](/use-groundcover/ai-observability/privacy-controls.md) for details.

### Agent

| Attribute                  | Type   | Description               |
| -------------------------- | ------ | ------------------------- |
| `gen_ai.agent.name`        | string | Human-readable agent name |
| `gen_ai.agent.id`          | string | Unique agent identifier   |
| `gen_ai.agent.description` | string | Agent description         |
| `gen_ai.agent.version`     | string | Agent version             |

### Tool Execution

| Attribute                    | Type   | Description                          |
| ---------------------------- | ------ | ------------------------------------ |
| `gen_ai.tool.name`           | string | Name of the tool                     |
| `gen_ai.tool.type`           | string | `function`, `extension`, `datastore` |
| `gen_ai.tool.call.id`        | string | Tool call identifier                 |
| `gen_ai.tool.call.arguments` | JSON   | Parameters passed to the tool        |
| `gen_ai.tool.call.result`    | JSON   | Result returned by the tool          |

For request parameters, response metadata, and the complete specification, see the [OpenTelemetry GenAI Semantic Conventions](https://opentelemetry.io/docs/specs/semconv/gen-ai/).

***

## groundcover Enrichment

groundcover adds the following attributes at ingestion time. These are not part of the OTel specification — they're computed by groundcover for cost analytics and filtering.

### Cost

| Attribute            | Type   | Description                                                                                |
| -------------------- | ------ | ------------------------------------------------------------------------------------------ |
| `gc.llm_cost.input`  | float  | Cost of input tokens, computed from the model's pricing table                              |
| `gc.llm_cost.output` | float  | Cost of output tokens, computed from the model's pricing table                             |
| `gc.llm_cost.status` | string | `computed` when pricing is available, `unpriced` when the model isn't in the pricing table |

Cost is calculated per-span using `gen_ai.request.model` and `gen_ai.provider.name` to look up the correct pricing. When cache tokens are present (`gen_ai.usage.cache_read.input_tokens`), cached and non-cached portions are priced separately.

{% hint style="info" %}
If `gc.llm_cost.status` shows `unpriced`, the model isn't in groundcover's pricing table yet. This typically resolves automatically as the table is updated. [Contact us](https://www.groundcover.com/contact) if it persists.
{% endhint %}

### Filtering

| Attribute                   | Type       | Description                                                                                                                            |
| --------------------------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `span_type:gen_ai`          | expression | [GCQL](/use-groundcover/querying-your-groundcover-data/groundcover-query-language.md) filter — use in search, dashboards, and monitors |
| `protocol_type == "gen_ai"` | expression | [Traces Pipeline](/use-groundcover/data-pipelines/traces-pipeline.md) condition — use in OTTL pipeline rules                           |

groundcover assigns `span_type:gen_ai` automatically — eBPF spans from supported providers always receive it; SDK spans receive it when `gen_ai.operation.name` is present (best-effort). You do not need to set it yourself.

See [Example Queries](/use-groundcover/ai-observability/example-queries.md) for patterns using these attributes.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.groundcover.com/use-groundcover/ai-observability/attributes.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
