Skip to main content
Export spans through OTLP/HTTP or a Threadify SDK exporter. Report each operation once; do not duplicate its span with an SDK step report.

Direct OTLP/HTTP ingestion

Configure a standard exporter with your Engine’s URL and an Engine API key:
Set equivalent SDK options if your exporter does not read these variables. JSON and gRPC are not accepted here. A separate collector can forward gRPC input as OTLP/HTTP. Plan bandwidth allowances also apply.

Threadify SDK exporter

The JavaScript exporter uses your existing Threadify WebSocket connection:
Flush/shut down the provider before closing the connection when your process exits. See filtering to exclude spans or remove sensitive fields. For Go, install github.com/ThreadifyDev/go-sdk/otel and use threadifyotel.NewSpanExporter(conn, threadifyotel.SpanExporterOptions{...}). Use RefsMap for attribute-to-ref mappings; Refs is a list of attribute names. For Python, install threadify-sdk[otel] and use connection.create_span_exporter(options={...}) with your tracer provider.

Filter trace data

Drop whole spans

Configure the Threadify SDK exporter:
  • healthcheck drops that exact span name.
  • internal.* drops names beginning with internal..
  • Matching is case-sensitive, against the original span name, before threadify.step_name mapping.
  • Only a trailing * is supported; these are not regex patterns.
Each span is filtered independently. Dropping a parent does not drop its children. Keep steps required by contracts and spans carrying the run’s completion signal.

Filter every OTLP exporter at the Engine

Open Settings → Trace ingestion. Enter one exact name or trailing-* prefix per line, preview sample names, then save. An administrator must save changes. Empty rules keep all spans. These rules apply only to POST /v1/traces, before threads or steps are created. Threadify SDK WebSocket events and SDK span exporters are unaffected. Rules match original span names, before threadify.step_name mapping. With the CLI:
Preview without saving using preview.yaml:
  • Saves apply to the next batch across replicas sharing Valkey. In-flight batches can finish under their previous rules; existing history is unchanged.
  • Rules and counts persist in Valkey without a TTL. Preserve its data volume.
  • Stale saves return 409; reload and review before retrying.
  • Unavailable rules storage returns 503 instead of bypassing filtering.
  • Filtered exports succeed, including batches with no remaining spans. The X-Threadify-Filtered-Spans response header reports each batch’s drop count.
  • The settings page shows cumulative evaluated and dropped delivery attempts, including retries. Preview does not change counts. Counter-write failures are logged, so these are diagnostic counts, not billing totals.
  • Received bytes still count toward input bandwidth. Keep contract-required steps and run completion signals in your retained spans.

Remove fields from retained spans

Span filters do not redact attributes, prompts, payloads, or event data. refs maps attributes to references; it is not an attribute allowlist. Omit unwanted values in your instrumentation or remove them before export. Threadify has no built-in field-redaction option. Check span and resource attributes, events, and status messages; preserve fields needed by contracts.

Choose the thread identity

The correlation precedence is:
  1. threadify.thread_id: an existing internal Threadify thread ID.
  2. threadify.thread_key: your application-owned session or process key.
  3. workflow.run_id: used by default when no explicit key is supplied.
  4. OpenTelemetry trace ID: the fallback when none of the above applies.
The key uses the same Engine resolver as connection.thread(threadKey, options?). The stored contract and pinned version are loaded on resume, so subsequent spans can omit threadify.contract. A different supplied contract is rejected. Initialize contracted sessions before reporting spans; a new key without a contract creates a free-form thread. A shared thread key combines traces into one thread. Use a unique value per run, consistently set on its spans or dedicated resource. Thread keys must be nonblank strings of at most 1024 UTF-8 bytes after trimming. Existing threads are not merged retroactively. Conflicting identities or contracts are rejected.

Keep one trace per thread

Disable the workflow-run fallback on the direct traces URL:
Or on the exporter:
This only disables workflow.run_id; explicit threadify.thread_id and threadify.thread_key still take precedence. Omit those too for trace-ID grouping.

Mapping operations

Outcome is not contract compliance. A successful span can still violate a rule.
For a shared run, ending one root span does not necessarily finish the whole thread. Signal final completion with threadify.run.complete: true; contracted threads complete through their contract rules. Completion waits for all accepted spans in the current export. Terminal threads reject further writes, including delayed spans; keep the thread open until all session work has arrived. Preserve source trace/span IDs when investigating retries.

Observe or enforce

Passive export records operations after they happen. To prevent an agent tool call or backend action, use an SDK execution wait before running it, then let the span report its outcome with the invocation ID. Do not also report the same outcome through thread.step() unless it is a distinct event.