From 8a8024a6af37327f3157921bd91b2016bdc4ee6d Mon Sep 17 00:00:00 2001 From: Jonathan Pedoeem Date: Tue, 19 May 2026 11:16:48 -0400 Subject: [PATCH 1/2] Docs: Document OTLP metadata and user identity span attributes Documents the OTLP ingestion support for attaching searchable metadata to request logs via span attributes (backend PR #936): - Standard OpenTelemetry attributes: user.id / enduser.id -> user_id, gen_ai.conversation.id / session.id -> conversation_id. - PromptLayer custom metadata: promptlayer.metadata.. Adds an "Attaching User Identity & Metadata" section to the OpenTelemetry feature page and a behavior note to the OTLP ingest API reference. --- features/opentelemetry.mdx | 62 ++++++++++++++++++++++++++++++++ reference/otlp-ingest-traces.mdx | 3 +- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/features/opentelemetry.mdx b/features/opentelemetry.mdx index 97d3598..f9eeb17 100644 --- a/features/opentelemetry.mdx +++ b/features/opentelemetry.mdx @@ -170,6 +170,68 @@ tracer.startActiveSpan("llm-call", (span) => { ``` +## Attaching User Identity & Metadata + +You can attach searchable metadata — including end-user identity and conversation IDs — to the request logs generated from your spans. This is the OpenTelemetry-native equivalent of the PromptLayer SDK's `track.metadata()`, with no extra REST call required. + +PromptLayer recognizes two kinds of span attributes for metadata. + +### Standard OpenTelemetry attributes + +If your instrumentation already follows OpenTelemetry conventions, these are picked up automatically — no PromptLayer-specific attributes needed: + +| Attribute | Mapped to | Description | +|---|---|---| +| `user.id` | `user_id` metadata | End-user identity (current OpenTelemetry attribute) | +| `enduser.id` | `user_id` metadata | End-user identity (deprecated OpenTelemetry attribute, supported as a fallback) | +| `gen_ai.conversation.id` | `conversation_id` metadata | Conversation / session / thread identifier (OpenTelemetry GenAI attribute) | +| `session.id` | `conversation_id` metadata | Conversation identifier (common alias, supported as a fallback) | + +### PromptLayer custom metadata + +For arbitrary key/value metadata, use the `promptlayer.metadata.` namespace. Each attribute becomes a metadata key on the request log — for example, `promptlayer.metadata.tenant` becomes a `tenant` metadata key. + +| Attribute | Mapped to | +|---|---| +| `promptlayer.metadata.` | `` metadata | + + +```python Python +with tracer.start_as_current_span("llm-call") as span: + # Standard OpenTelemetry attributes + span.set_attribute("user.id", "customer-42") + span.set_attribute("gen_ai.conversation.id", "conv_abc123") + + # Arbitrary PromptLayer metadata + span.set_attribute("promptlayer.metadata.tenant", "acme-corp") + span.set_attribute("promptlayer.metadata.environment", "production") + + # ... make your LLM call ... +``` + +```javascript JavaScript +tracer.startActiveSpan("llm-call", (span) => { + // Standard OpenTelemetry attributes + span.setAttribute("user.id", "customer-42"); + span.setAttribute("gen_ai.conversation.id", "conv_abc123"); + + // Arbitrary PromptLayer metadata + span.setAttribute("promptlayer.metadata.tenant", "acme-corp"); + span.setAttribute("promptlayer.metadata.environment", "production"); + + // ... make your LLM call ... + + span.end(); +}); +``` + + +An explicit `promptlayer.metadata.` always takes precedence over a standard attribute mapped to the same key. For example, if a span has both `user.id` and `promptlayer.metadata.user_id`, the `promptlayer.metadata.user_id` value wins. + + +Metadata is attached to the request log generated from the span, so set these attributes on your **LLM call spans**. To apply metadata across an entire trace, set the attributes as **resource attributes** — they apply to every span in the export. + + ## Using an OpenTelemetry Collector If you're already running an [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/), you can add PromptLayer as an additional exporter in your Collector config: diff --git a/reference/otlp-ingest-traces.mdx b/reference/otlp-ingest-traces.mdx index 8438038..4831de8 100644 --- a/reference/otlp-ingest-traces.mdx +++ b/reference/otlp-ingest-traces.mdx @@ -12,7 +12,8 @@ Ingest OpenTelemetry traces through PromptLayer's OTLP/HTTP endpoint. - Supported content types are `application/x-protobuf` for binary protobuf encoding and `application/json` for JSON encoding. - Gzip `Content-Encoding` is supported for both formats. - Spans can include `promptlayer.prompt.name` or `promptlayer.prompt.id`, plus `promptlayer.prompt.version` or `promptlayer.prompt.label`, to link the generated request log to an existing prompt template in your workspace. -- For SDK setup, GenAI semantic conventions, prompt template linking, and collector configuration, see [OpenTelemetry](/features/opentelemetry). +- Spans can include `user.id`/`enduser.id`, `gen_ai.conversation.id`/`session.id`, and `promptlayer.metadata.*` attributes to attach searchable user identity and metadata to the generated request log. +- For SDK setup, GenAI semantic conventions, prompt template linking, metadata, and collector configuration, see [OpenTelemetry](/features/opentelemetry). ## Related From 204d446a1159aa5f8f29f007458d909c24839b2e Mon Sep 17 00:00:00 2001 From: Jonathan Pedoeem Date: Tue, 19 May 2026 11:18:36 -0400 Subject: [PATCH 2/2] Docs: Correct prompt-template linking attributes for OTLP The OTLP ingestion extractor only resolves promptlayer.prompt.name (optionally with promptlayer.prompt.version). promptlayer.prompt.id is never read and promptlayer.prompt.label is extracted but not used to resolve a version, so documenting them was misleading. Removes promptlayer.prompt.id / promptlayer.prompt.label from the prompt-template linking docs and updates the code samples to use promptlayer.prompt.version. --- features/opentelemetry.mdx | 10 ++++------ reference/otlp-ingest-traces.mdx | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/features/opentelemetry.mdx b/features/opentelemetry.mdx index f9eeb17..0137f91 100644 --- a/features/opentelemetry.mdx +++ b/features/opentelemetry.mdx @@ -126,10 +126,8 @@ You can associate OTEL spans with prompt templates in your PromptLayer workspace | Attribute | Type | Description | |---|---|---| -| `promptlayer.prompt.name` | string | Name of the prompt template | -| `promptlayer.prompt.id` | integer | ID of the prompt template (alternative to `name`) | -| `promptlayer.prompt.version` | integer | Specific version number (optional) | -| `promptlayer.prompt.label` | string | Label to resolve version (e.g. `production`) | +| `promptlayer.prompt.name` | string | Name of the prompt template in your workspace | +| `promptlayer.prompt.version` | integer | Specific version number to link (optional) | ```python Python @@ -140,7 +138,7 @@ tracer = trace.get_tracer("my-llm-app") with tracer.start_as_current_span("llm-call") as span: # Link this span to a prompt template span.set_attribute("promptlayer.prompt.name", "my-prompt") - span.set_attribute("promptlayer.prompt.label", "production") + span.set_attribute("promptlayer.prompt.version", 3) # Add GenAI attributes span.set_attribute("gen_ai.request.model", "gpt-4") @@ -157,7 +155,7 @@ const tracer = trace.getTracer("my-llm-app"); tracer.startActiveSpan("llm-call", (span) => { // Link this span to a prompt template span.setAttribute("promptlayer.prompt.name", "my-prompt"); - span.setAttribute("promptlayer.prompt.label", "production"); + span.setAttribute("promptlayer.prompt.version", 3); // Add GenAI attributes span.setAttribute("gen_ai.request.model", "gpt-4"); diff --git a/reference/otlp-ingest-traces.mdx b/reference/otlp-ingest-traces.mdx index 4831de8..bf2f5d0 100644 --- a/reference/otlp-ingest-traces.mdx +++ b/reference/otlp-ingest-traces.mdx @@ -11,7 +11,7 @@ Ingest OpenTelemetry traces through PromptLayer's OTLP/HTTP endpoint. - Spans carrying [GenAI semantic convention](https://opentelemetry.io/docs/specs/semconv/gen-ai/) attributes are automatically converted into PromptLayer request logs. - Supported content types are `application/x-protobuf` for binary protobuf encoding and `application/json` for JSON encoding. - Gzip `Content-Encoding` is supported for both formats. -- Spans can include `promptlayer.prompt.name` or `promptlayer.prompt.id`, plus `promptlayer.prompt.version` or `promptlayer.prompt.label`, to link the generated request log to an existing prompt template in your workspace. +- Spans can include `promptlayer.prompt.name`, optionally with `promptlayer.prompt.version`, to link the generated request log to an existing prompt template in your workspace. - Spans can include `user.id`/`enduser.id`, `gen_ai.conversation.id`/`session.id`, and `promptlayer.metadata.*` attributes to attach searchable user identity and metadata to the generated request log. - For SDK setup, GenAI semantic conventions, prompt template linking, metadata, and collector configuration, see [OpenTelemetry](/features/opentelemetry).