Skip to main content
Send existing OpenTelemetry records to Hue with an OTLP/HTTP exporter or Collector; no Hue-specific model wrapper is needed.
Set user.id on each request’s root span so Hue can build that user’s World across traces. See Identify users for stable IDs and SDK options.
For trace exports you already hold, from OpenTelemetry or another tool, see Bulk import existing traces: your coding agent imports them through the Hue MCP server, without an exporter or a project key.

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.version and deployment.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: false or capture_content=False strips 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 local GET /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:
Serve synthetic JSON in one terminal:
Save this as http-content.py and run python http-content.py in another terminal:
The console export includes a CLIENT span with 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 write HUE_API_KEY.
Install the pinned packages:
Save this as send.mjs and run node send.mjs:
Hue accepts the Node.js OTLP/JSON, Python protobuf and Collector gzip/protobuf examples. Each marks a tool span; Traces and spans lists the attributes that make traces searchable. Verify the trace ID in Hue or with a trace receipt.

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.
The Collector replaces the SDK key, so 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

Pass redact 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:
Save as otel.ts. In an existing app, add processors to existing provider construction and retain global registration and propagation.
Run 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 existing NodeSDK setup after installing @hue-run/sdk and saving the email callback as redaction.ts; keep the rest of that application’s initialization:
At shutdown, await 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 the hue 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:
The reader starts immediately so completion and abort callbacks finish before export. Keep 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 or data: 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 carrying hue.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.
Mark 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’s hue.trace_checks attribute: a JSON object or string up to 64,000 characters. It declares the request and every boundary; Hue infers none.
  • requestKind is task (requires an action boundary) or conversation. request identifies the whole user request; authorization identifies up to eight whole earlier messages authorizing extra work.
  • boundaries lists 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.role attribute (orchestrator or subagent).
  • Each boundary in the manifest names its span with spanId, plus traceId for a span in a linked trace.
  • linkedTraces lists up to four child traces and their handoff spans. complete: true declares all request boundaries.
An output_reduction boundary has this shape, for code that trimmed a tool’s result before the agent read it:
The 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. The hue.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.