Provider ownership
Your provider owns instrumentation and propagation; Hue stores what it sends.- Hue never replaces global providers, propagators or context managers. Set
service.name,service.versionanddeployment.environment.name; keep your sampler and W3C propagation. Run traces are labeled separately, hidden from production searches by default and linked from their run. - Hue stores emitted telemetry and does not proxy model providers. With a standard OTLP exporter, your application chooses its instrumentation. The Hue SDK can also record supported app HTTP calls.
- Hue SDK
captureContent: falseorcapture_content=Falsestrips recognized content attributes, including third-party spans; custom keys pass through. Without a Hue SDK, capture and redact content in your instrumentation or Collector; Hue cannot reconstruct omitted data. See Data privacy. - Hue processors send a separate provider copy; existing exporters and filters are unchanged. Test each destination with synthetic content.
App HTTP calls
Standard HTTP client instrumentation records request identity, such as method, URL, host and status. It does not generally record request or response bodies. Keep HTTP CLIENT spans in your export filters, even when your framework also emits model and tool spans. A summary-only tool result is not the underlying app response. For JavaScript, use@opentelemetry/instrumentation-http for node:http clients and @opentelemetry/instrumentation-undici for Node.js fetch and undici. For Python, use the instrumentor for your client, such as requests or httpx. Register instrumentation at application startup with your existing provider. Check its runtime and load-order requirements.
Body capture needs a hook that can access bytes the application has already read, or capture in the application’s normal read path. The undici responseHook receives status and headers, not a response body. HTTPX, urllib and aiohttp response hooks can run before the body is read. Do not consume a stream in a hook to fill telemetry.
Record a loaded requests response
This synthetic example uses standard OpenTelemetry and requests, with no Hue SDK. It captures only a localGET /messages.json without query parameters or a request body. Its hook checks that requests has already loaded the response, bounds the encoded value and leaves streaming responses unread. Apply your app’s allowlist and redaction policy before adapting it to real content.
Install the tested packages in a Python environment:
http-content.py and run python http-content.py in another terminal:
input.value, the parsed response JSON in output.value and its type in output.mime_type. HTTP status stays in the instrumentor’s attributes. Reuse your existing provider and exporter to send those fields to Hue. The _content_consumed guard is specific to the pinned requests version. Test it again when upgrading requests. The hook deliberately omits streaming, non-JSON and over-limit content rather than asserting that a complete exchange was recorded.
The Hue SDK offers default HTTP capture for its supported clients. Other exporters remain vendor-neutral; no Hue-specific tool name or tool return shape is required.
Configure the endpoint
Use a Read and write key from Settings → API keys, with separate keys for development and production. The key determines the project; an attribute cannot select a project.
Set complete signal endpoints; do not append another
/v1/traces or /v1/logs. Keep authorization in server environment/secret storage.
Routes accept OTLP, not arbitrary JSON. Metrics and OTLP gRPC are unsupported. Logs provide trace-correlated evidence, not general log search.
Send from any language
Any OTLP/HTTP SDK or Collector can send here. Examples use standard packages and a Read and writeHUE_API_KEY.
- Node.js
- Python
- Collector
Install the pinned packages:Save this as
send.mjs and run node send.mjs:Send through a Collector
Hue SDKs post to<origin>/api/v1/otlp/v1/traces and /logs. Add a separate receiver so standard exporters keep /v1/traces and /v1/logs. Disable live-span placeholders; generic receivers would forward them.
apiKey / api_key can be a non-empty placeholder. Skip SDK checks and receipts; the Collector cannot answer. Without liveSpans: false, placeholders are sent once, then TypeScript warns or Python sets export_status.live_spans_rejected and stops.
Existing JavaScript providers
Passredact when creating the transport to scrub exported content; see Data privacy.
To keep provider ownership while using Hue content controls and diagnostics, attach its processors during construction. Install the TypeScript package and these dependencies, skipping any your application already has at another version:
otel.ts. In an existing app, add processors to existing provider construction and retain global registration and propagation.
node otel.ts after setting your environment. An export rejection makes the command fail rather than reporting successful delivery. Hue does not register or replace a global tracer, logger, or context manager. An instrumentor that only uses global providers still needs your application’s normal OpenTelemetry initialization.
Your providers own the resource in this mode: set service.name, deployment.environment.name and similar attributes on them. resourceAttributes on the transport options is ignored and reported as a warning issue. The Python SDK attaches the same way through tracer_provider= and logger_provider=; a provider Hue creates for the other signal reuses the borrowed provider’s resource. See the Python guide.
Use with Langfuse
Keep Langfuse’s instrumentation/exporter. Add Hue’s processor to that provider at construction; preserve resources, sampling, propagation, processors and filters. See Langfuse’s OpenTelemetry guidance. For example, this is the change to an existingNodeSDK setup after installing @hue-run/sdk and saving the email callback as redaction.ts; keep the rest of that application’s initialization:
sdk.shutdown() and then hueTransport.shutdown(), so Hue’s copy and its file uploads are sent before the process exits. To check delivery with verifyTrace, create a separate diagnostic client with createHue({ apiKey, serviceName }) in a setup script; it needs none of your providers. This is an attachment example, not a replacement bootstrap or version certification. If an OTLP exporter already sends these spans to Hue, replace it with Hue’s processor rather than exporting twice. Create the optional transport inside a fail-open boundary and append only on success. Use framework processor configuration when it owns the provider; see production setup.
Keep Langfuse AI SDK instrumentation: SDK 6 uses experimental_telemetry; SDK 7 uses its registered integration. Per-call hueTelemetry() replaces global integrations for that call. See Langfuse setup and compatibility.
Langfuse’s mask hook does not redact Hue’s copy. Apply policy to both exports, then inspect synthetic content in both. See Langfuse masking and Data privacy.
Hue reads Langfuse attributes directly. langfuse.observation.type, .model.name, .usage_details, .input, .output, langfuse.session.id and langfuse.user.id fill Hue fields when GenAI attributes are absent; GenAI wins. langfuse.trace.name names traces without request text; langfuse.release supplies release absent service.version; langfuse.environment supplies the environment absent deployment.environment.name. The field glossary lists these fields and the Langfuse metadata fields Hue reads as the user and session; other metadata, tags and levels stay raw. OpenTelemetry status marks failure.
Langfuse’s SDKs move a recorded image, audio file or document into Langfuse and leave a media reference in its place. With Langfuse’s TypeScript SDK, Hue’s processor records the file before that happens, so it uploads to Hue; a reference Hue receives has no bytes behind it. See remote references.
To bring traces already in Langfuse into Hue, run hue import langfuse on your machine with the Langfuse project’s own keys. It copies the traces, and with --media their files, as the spans a Langfuse OpenTelemetry SDK records, and running it again resumes without duplicates. For Langfuse exports you already hold (API answers, UI downloads or blob-storage files), see Bulk import existing traces.
Current SDKs strip recognized Langfuse content in metadata-only mode; older SDKs need producer or Collector controls. Metadata and custom fields pass through. Verify each independent capture policy; see compatibility.
Test a real request with model and tool spans, preserved IDs and parentage and both exporters flushed by the host deadline. Check content and fields in both destinations. Hue’s trace receipt checks span and field presence, not payload correctness or Langfuse delivery; also test errors and cancellation.
Exporters cannot recover truncated data. Instrument reductions when analysis needs original and retained results.
Flush streamed responses in Next.js
In AI SDK 7, add Hue processors to existing providers at startup and retain thehue client/providers for the server lifetime.
The standalone diagnostic fails on setup errors. In serving apps, guard optional setup and use production-safe initialization. createHueSafe({ transport, tracerProvider, loggerProvider }) cannot catch createHueTransport(...) errors, so guard that call too.
In the route, import consumeStream from ai and after from next/server, and import the server-lifetime hue client from your telemetry module. Replace a standalone after(flushTelemetry) with this option inside your existing createAgentUIStreamResponse call:
request.signal on generation; callbacks stay unchanged.
hue.flushSafe() flushes borrowed providers or transport, returns counters and waits at most one second. Timeout does not cancel third-party work; transport.flush() is strict. When the route uploads files, give flushSafe() a budget that covers those uploads.
Log delivery counters to an independent, non-throwing sink. Do not shut down shared transport per request. See the AI SDK stream-abort guide.
Agent attributes
Traces and spans lists the attributes that make traces searchable, and Data privacy covers content capture. Hue preserves original resource, scope, status, events, links, dropped counts, typed attributes, and external trace and span IDs. It derives AI fields alongside those records using versioned normalization profiles. Supported profile families include generic OpenTelemetry, GenAI conventions, OpenInference, OpenLLMetry, Vercel AI SDK 6 and 7, Langfuse, LangSmith, MLflow, Google ADK, Braintrust, Mastra, Claude Code, VoltAgent, Spring AI and Genkit. A profile family is not a guarantee that every package version or API surface has been tested. Compatibility lists the AI SDK and OTel pairs the TypeScript adapter is verified with. Hue also reads model-call content from current GenAI semantic-convention events (gen_ai.client.inference.operation.details, as a log record or a span event), tools the model provider ran (server_tool_call parts), and the tool calls a model response records in its provider’s own shape when they carry a call ID (Anthropic tool_use, OpenAI Responses function_call and LangChain tool_calls).
When you create the request’s root span yourself, record the user’s request as its input.value attribute and the reply as output.value, the attributes Hue’s helpers write. Prefer current GenAI attributes when your instrumentation supports them, including gen_ai.provider.name, gen_ai.request.model, gen_ai.usage.input_tokens, and gen_ai.usage.output_tokens. Preserve unavailable fields as absent. Do not submit 0 for unknown usage or null for an output that was never captured.
A child can arrive before its parent, and a correlated log can arrive before its span. Preserve the same trace ID and the correct parent and span IDs across services. Root-span completion does not prove that the whole distributed trace has arrived. Evaluations use a pinned evidence revision.
Files
Images, audio and documents that your instrumentation records inline, as message parts ordata: URLs, appear in the trace without Hue code. To attach a file larger than the 1 MiB value limit from an exporter without a Hue SDK, upload it with the file upload API. Media lists the recognized formats and how to read files back.
Trace checks and request timing
Trace checks assess delegation, scope and omitted output; request timing measures time to a useful answer. They use recorded attributes and events, not inferred data, and require an activated, tested version. Run traces are excluded.Mark the root span
Put request attributes, timing events and the manifest on the request’s root span. Hue reads them from the span carryinghue.trace_checks, or the parentless root when no manifest exists.
Record root timing events with
hue.request.id; Hue reads the earliest of each name and at most 128 events.
Define useful answers; acknowledgements do not count.
first_useful_answer_ms uses playback time when present, otherwise server time. Out-of-order events are incomplete.
hue.response.useful when the answer is ready, not when sending a placeholder.
The example assumes agent.support_reply is root. If not, put attributes and events and the manifest on the active root Hue reads.
Declare agent boundaries
Put one manifest on the root span’shue.trace_checks attribute: a JSON object or string up to 64,000 characters. It declares the request and every boundary; Hue infers none.
requestKindistask(requires anactionboundary) orconversation.requestidentifies the whole user request;authorizationidentifies up to eight whole earlier messages authorizing extra work.boundarieslists up to 32 agent actions (action_scope), delegations (delegation_scope, parent task given to the delegating agent), or pre-use tool-output reductions (output_omission). A reduction points to its task, full original and retained outputs, code, next decision and later use. Delegation checks read the request plus each action and handoff.- Each boundary’s span carries the
hue.agent.roleattribute (orchestratororsubagent). - Each boundary in the manifest names its span with
spanId, plustraceIdfor a span in a linked trace. linkedTraceslists up to four child traces and their handoff spans.complete: truedeclares all request boundaries.
output_reduction boundary has this shape, for code that trimmed a tool’s result before the agent read it:
original and retained references cover the whole output; task, code, decision and use identify the reduction purpose, code and downstream use.
A source reference names a 16-hex spanId (and linked traceId), field (input, output or attributes), key/index path, and half-open UTF-16 start and end offsets in the exact recorded string (max 8,000 chars). A string attribute (field: "attributes", path=key) keeps offsets exact; use its length for a whole-value reference. The model reads only referenced text, up to 16,000 chars per check.
Checks read the manifest and named spans and, in linked traces, the first span plus handoff continuation—not every trace span. Trace size is not the cap: at most 128 spans are read, each with attributes, input and output up to 64 KiB. Missing or invalid manifests or over-limit evidence yield unavailable; delegation is not_applicable without task actions or handoffs, and other checks when no boundary is declared.
Collector responses
Keep requests at or below 4 MiB on the wire and 8 MiB after decompression. An individual OTLP value can contain up to 1 MiB. Hue cuts oversized text values at a UTF-8 character boundary and replaces oversized structured values with a truncation marker. Thehue.truncated attribute lists the affected keys. Oversized requests return HTTP 413.
Hue indexes up to 10,000 spans and 20,000 correlated logs per trace. Records beyond those index limits remain stored in the trace’s evidence segments and counted on the trace.
An otherwise valid batch can receive an OTLP partial-success response containing rejected-record counts. Configure your exporter monitoring to inspect that response; HTTP 200 alone does not prove that every record was accepted. Hue SDKs surface those failures through their flush APIs. Partial rejection must not trigger a blind replay of the whole batch.
Exact completed-span replays are deduplicated within the project. A different payload for the same completed span ID is rejected. Logs have no universal event ID, so exact duplicate records collapse; include their actual timestamps and correlation data. These rules do not make the client’s in-memory queue durable.