Skip to main content
Use the Hue TypeScript SDK to trace your server-side application, tools, and model integrations. Your application continues to call the model provider directly. For option defaults and method signatures, see the TypeScript API reference. Check the compatibility matrix before adding Hue to an existing application.

Install

Use Node.js 22 or 24, or Bun 1.4. Install the TypeScript SDK, then configure your key below. The package is ESM; CommonJS applications on Node.js 22.12 or later load it with require("@hue-run/sdk"). Besides the core entry point, the package exposes @hue-run/sdk/ai-sdk, @hue-run/sdk/evals, @hue-run/sdk/environment and @hue-run/sdk/managed.

Configure your project

Put a project key in your server environment as HUE_API_KEY: a Read and write key from Settings → API keys. Use separate keys for development and production; Project keys covers each preset and rotation. Never expose a key to a browser. Hue Cloud is the default destination; connection settings covers other origins. allowInsecureHttp: true permits plain HTTP to a non-loopback host, such as an in-cluster collector, and records a one-time warning issue because the key then travels unencrypted. The SDK reads no OTEL_EXPORTER_OTLP_* environment variables; pass configuration explicitly. serviceName, serviceVersion and resourceAttributes (for example { "deployment.environment.name": "production" }) describe the deployment on a client that owns its providers. When you attach Hue to your own providers, they own the resource and resourceAttributes is ignored with a warning issue. Resource attributes still being detected when a record is queued, as asynchronous detectors leave them, are omitted with a warning issue; await detection before instrumenting if you need them.

Send your first trace

Save this as trace.ts in a package whose package.json contains "type": "module" (or name the file trace.mts). It traces a deterministic uppercase tool; it makes no model call.
Run it with your environment already configured:
Open Traces in the project that owns the key. The root span and its execute_tool uppercase child share the printed trace ID. With captureContent: true, both spans show the input hello and the output HELLO alongside timing and identity metadata. checkConnection() rejects with HueConnectionError when the key or origin is wrong. Its fixed message is safe to log; status carries the HTTP status when Hue answered, and cause carries the underlying network, timeout or parsing error.

Content capture

captureContent defaults to true for an enabled client, so spans record prompts and messages, responses and tool inputs and outputs. Set it to false for metadata-only capture. A disabled client (enabled: false) exports nothing. Data privacy explains what each mode sends, how redact(value, path) scrubs values before export and what Hue does with stored content; the content policy lists the exact fields. Helper spans record a failed callback’s error.type and an ERROR status, never exception messages or stack traces; keep those in application logs. Missing usage stays missing: the SDK does not estimate tokens or cost. Images, audio and documents in recorded values upload automatically; Media covers Attachment, recordFile and reading files back.

Model spans and context

When you call a provider SDK directly, hue.model(model, callback, options) creates the GenAI client span for that call; Traces and spans shows where it sits in a request. The span is named {operation} {model} (operation defaults to chat) and carries gen_ai.operation.name, gen_ai.request.model and gen_ai.provider.name. Inside the callback, setInput and setOutput record gen_ai.input.messages and gen_ai.output.messages when captureContent is true; use the OpenTelemetry GenAI message shape ({ role, parts: [{ type: "text", content }] }). setUsage records provider-reported token counts; unknown usage stays absent.
Like withSpan, the options come after the callback and also accept name, sessionId, userId, workspaceId, input and parentContext. Pass systemInstructions and tools when you send them separately from the messages. For tools the provider runs itself, such as OpenAI hosted MCP or web search, call hue.recordProviderToolCalls(response) inside the callback. hue.recordMessages({ input, output }) inside the callback emits a correlated gen_ai.client.inference.operation.details log record that inherits the request metadata; pass operation, provider and model explicitly outside a model() span. Use either span attributes or the log record for a given content event. Across processes, call hue.inject(carrier) inside the producing span and pass hue.extract(carrier) as parentContext in the worker. Both carry W3C traceparent only, never the API key or baggage, and inject() keeps propagating the application’s own trace context when the client is disabled. Hue registers no global propagator or context manager. When your application has registered a context manager, withSpan, tool and model also make their span the active OpenTelemetry span while the callback runs, so spans from instrumentations that use the global API parent under it.

Vercel AI SDK

The hueTelemetry adapter requires AI SDK 7 (ai@^7.0.0) and @ai-sdk/otel@^1.0.0; keep the AI SDK version your application already uses. Compatibility lists the tested AI SDK and OTel pairs. The packages have different major versions.
Import hueTelemetry from @hue-run/sdk/ai-sdk and pass telemetry: hueTelemetry(hue) to your agent or generation call. The helper forwards your explicit content choice to recordInputs and recordOutputs. It also records the end user and conversation from the call’s runtime context; see hueTelemetry. Consume a streaming response inside the surrounding hue.withSpan callback before it returns. Follow production setup for delivery at the application lifecycle boundary. For AI SDK 6, import hueExperimentalTelemetry from @hue-run/sdk and pass experimental_telemetry: hueExperimentalTelemetry(hue) to each call. It needs no @ai-sdk/otel peer; the generated spans parent under withSpan, inherit session and user identifiers, and record prompts and responses only when captureContent is true. hueTelemetry reads the installed ai major version once per process and throws a TypeError below 7. Do not upgrade an application’s AI SDK only to add tracing. Keep the request span open until the AI SDK has finished. Awaiting result.text is not enough: AI SDK 6 resolves it before it ends its own ai.streamText span. Await result.consumeStream() instead, which also lets you hand textStream to the caller:
withSpan runs the callback synchronously up to its first await, so textStream is set when handleChat returns. AI SDK spans such as ai.toolCall can record an error’s message; redact applies to them. If your app already registers a global AI SDK integration, preserve it and attach Hue to the same OpenTelemetry provider. A per-call telemetry integration replaces the global AI SDK integration for that call. Follow existing OpenTelemetry when you need multiple exporters.

Verify

Finish a real application request and retain its trace ID and known span IDs. End its spans, flush the provider that owns them, then flush Hue. When borrowing a provider, flush that provider first. Verification does not run the app, invoke a model, or flush telemetry.
Only require fields the request should emit and your capture policy permits. Supported names are input, output, model, usage, and session. With content capture, add input and output to confirm the request’s content arrived. Omit them for metadata-only capture, and omit usage when the instrumentation does not report it. The receipt reports stored field presence, span counts, and missing expected spans. It contains no captured values. A successful result confirms the conditions you requested; inspect the trace in Hue to check the content and redaction. See the verification API for limits and failures.

Production setup

Keep tracing best effort in a serving application: an outage should reduce observability, not prevent an answer. Hue follows OpenTelemetry’s runtime error containment and bounded-resource principles. Use a Read and write project service key for application requests, with separate keys for development and production. The SDK suppresses its own export traffic from OpenTelemetry instrumentation. Snapshot boundaries reject unsupported values; TypeScript also handles Proxies and typed bytes without bypassing queue budgets. Verify your dependency and instrumentor combination in CI.

Verify setup outside request handling

Run the strict quickstart, connection check and trace receipt verification during setup, not in readiness or customer requests. Create one client per serving process with the safe constructor and background export. Use safe lifecycle methods at the lifecycle boundary; never rerun an agent after a telemetry error because tools may have caused side effects.
existingAgent is your function. Register shutdown in the process hook. When the process uploads files, give shutdownSafe() a budget that covers those uploads: one whose budget runs out ends the uploads still pending. Do not shut down shared providers per request.

Vercel Functions and Workflow

From TypeScript 0.23.0, Hue automatically registers queued spans and logs with Vercel’s waitUntil. Your function response or Workflow step can return while normal batches and their file uploads finish. In Workflow, instrument work inside "use step" functions and finish the traced work before the step returns. Remove a per-step await hue.flushSafe() when its only purpose is to keep Hue delivery alive. Keep an explicit flush when you need its acknowledgement report or confirmed upload completion before deleting or changing files streamed from disk. Automatic delivery preserves content capture, redaction, batching, and failure reports. Background work shares the function’s maxDuration. It does not flush or shut down application-owned providers or other exporters. For other serverless hosts, use the framework’s supported after-response lifecycle.

Failure behavior

Hue omits unsafe content or redactor failures, records instrumentation failure and preserves application results and errors. Safe initialization returns a disabled client on setup failure; helpers still execute application work. Safe lifecycle methods return failure results. A timeout neither proves delivery nor cancels an in-flight request. createHue, checks, verification and strict lifecycle methods remain diagnostic and may fail. Queues limit records and bytes, including in-flight records. maxQueueBytes defaults to 8 MiB shared by traces and logs. Separately, the SDK can hold up to 128 MiB of over-limit strings in a span’s own attributes and recorded media and explicitly requested file uploads while they await upload; log records, other events, links and resources do not upload. This bounds queued telemetry, not process RSS. Overflow drops telemetry and updates counters without retrying business work. Network retries are bounded. Shutdown counts discards; process kill, full queues, disabled clients and exporter failures can lose telemetry. There is no disk spool or delivery guarantee. In-process code cannot prevent termination, OOM, stalls or third-party hooks. Keep redactors fast and offline. Safe construction cannot catch import or dependency failures, so verify startup in CI or guard the integration.

Kill switch and monitoring

The snippets read HUE_TRACING_ENABLED; set it to false and restart to bypass Hue without changing application code. It is not a remote flag. Strict constructors also accept enabled: false; a disabled client needs neither a key nor capture settings. Inspect hue.transport.getReport() for failures, drops, pending bytes and exports. Counters are cumulative; pending bytes and records are current gauges. Emit only sanitized counts and status, never credentials, content or raw provider exceptions, and do not send health signals only through Hue. Before rollout, test your real entry point against a loopback receiver that returns 503, rejects its key, delays its response and exceeds queue capacity. Verify that each tool runs once, results and errors match an uninstrumented request, and shutdown meets your deadline. Start with a small canary.

Delivery failures

flush() sends traces and logs first, then waits for the uploads queued before it; shutdown() does the same. Partial rejection, malformed acknowledgement, queue overflow, and export failure raise HueExportError. Its report contains cumulative accepted, rejected, failed, and pending counts; hue.transport.getIssues() returns recent sanitized issues. Transient HTTP 500 responses are retried within the existing retry and timeout budgets. A 429 Retry-After keeps records queued for up to 60 seconds; a longer wait is reported as a failed export. Check uploadedValues and uploadFallbacks in hue.transport.getReport(); upload fallbacks are warnings and do not fail a flush. A partially rejected batch is not resent wholesale, and a later successful flush does not erase earlier failures from cumulative counters. Stop starting operations before shutdown. End active spans, await flush(), and await shutdown() before the process exits. The queues are in memory and cannot recover records after process termination.