Skip to main content
If your agent already exports traces to Langfuse, Arize Phoenix, or LangSmith, Coval can pull those traces into the trace viewer, run trace-based metrics (timings, LLM judges, custom metrics), and populate the transition heatmap — without re-instrumenting your agent. Connect your account once in Settings → Integrations, and Coval handles the rest after each simulation.

How it works

The flow is the same for every provider:
  1. Your agent sends traces to your platform as it does today.
  2. When a Coval simulation finishes, Coval looks up the traces that carry that simulation’s ID, around the time the simulation ran.
  3. They’re normalized to OpenTelemetry spans and written to the same trace store that native OTLP ingestion uses.
  4. The trace viewer, trace metrics, and transition heatmap work against the imported spans exactly as they do for native OTLP traces.
Imported spans are tagged with service.name set to the source (langfuse, arize, or langsmith) so they’re easy to distinguish in the viewer. If a simulation already has native OTLP traces, the import is skipped to avoid duplicate spans. For an uploaded conversation, include occurred_at when you submit it so Coval looks for traces around the time of the call. Without it, Coval looks only around the time it processed the conversation, and misses the traces of a call submitted well after it happened. Set occurred_at to the instant the audio recording starts. The trace viewer also uses it to line the audio up with the spans.
Correlation is required. Coval imports only traces that carry the simulation’s ID, for example as simulation_output_id (or session_id / coval_simulation_output_id) in your trace metadata. If none does, nothing is imported: Coval never falls back to every trace in the time window, so traces from concurrent calls aren’t mixed up. Each provider’s exact keys and code are in its tab below.

Connect your platform

Prerequisites
  • A Langfuse project with at least one completed trace
  • Langfuse Public Key and Secret Key from your project settings
Connect
  1. Open Settings → Integrations in Coval and expand the Langfuse Integration panel.
  2. Paste your Public Key and Secret Key.
  3. Set Host if you self-host Langfuse; leave the default https://us.cloud.langfuse.com for Langfuse Cloud.
  4. Save.
CorrelationCoval finds your traces by the simulation’s ID. Put it in either of these places:
  • Langfuse’s own session ID (sessionId).
  • Trace or observation metadata, under simulation_output_id, session_id, or coval_simulation_output_id.
Coval imports only traces that match. If no trace carries the simulation’s ID, nothing is imported: Coval does not fall back to importing every trace in the time window, because that would attach other callers’ traces to the wrong simulation.
Setting the ID with metadata= on a single span also works; Coval matches it on that observation and imports the whole trace it belongs to.On self-hosted Langfuse v3, only trace metadata is matched: Coval reads it through an older API (see Limits), so the session ID and observation metadata aren’t used there.VerifyAfter a simulation finishes, open the result and click View Traces. Imported spans appear with service.name = langfuse and the original Langfuse attributes preserved under langfuse.*. OTel GenAI attributes (gen_ai.request.model, gen_ai.usage.*) are emitted for LLM generations so trace metrics work out of the box.Limits
  • Each fetch attempt has a 30-second budget.
  • If no trace is found, Coval tries again about 15 seconds and then 30 seconds later, without holding up other work. A conversation you upload more than a day after the call gets a single attempt.
  • If Langfuse rate-limits a request (HTTP 429), Coval waits about as long as Langfuse’s Retry-After header asks (30 seconds if it doesn’t say; a request for more than 5 minutes is treated as 5 minutes) and tries again.
  • Each simulation gets at most three attempts in total. Its metrics run after the last one, whether or not a trace was found.
  • Langfuse Cloud and self-hosted Langfuse v4 are read through Langfuse’s v2 observations API. Coval finds the traces that carry the simulation’s ID, then reads all of their observations, following every page Langfuse returns. It imports them completely or not at all: if they can’t all be read within the attempt’s budget, nothing is imported for that simulation, so a partial trace is never stored.
  • Self-hosted Langfuse v3 doesn’t have the v2 API, so Coval reads the older traces API there. It reads up to 500 traces in the simulation’s time window (100/page × 5 pages), keeps those whose trace metadata carries the simulation’s ID, and reads up to 500 observations per trace. Traces and observations past those limits aren’t imported.
Langfuse can take up to 15 minutes to make data available on its v2 API when it comes from an older SDK (langfuse-python before 4.7.0 or langfuse-js before 5.4.0) or from an OpenTelemetry exporter that doesn’t send the x-langfuse-ingestion-version: 4 header. Coval’s retries cover about a minute, so those traces can be missed. Upgrade the SDK or set the header on your exporter.
Troubleshooting

See also