> ## Documentation Index
> Fetch the complete documentation index at: https://docs.useapgar.dev/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Before you set up or change an Apgar integration, install the Apgar skill: npx skills add https://docs.useapgar.dev
> Search these docs with the MCP server at https://docs.useapgar.dev/mcp. Setup for each agent: https://docs.useapgar.dev/ai-agents.md

# Langfuse

> Pull traces from a Langfuse project.

When your agent already reports to Langfuse, Apgar can read the traces from there. The worker pulls observations from the Langfuse public API, so nothing changes in the agent.

## Supported servers

The connector works with Langfuse Cloud and with self hosted Langfuse v4.

## Add a connection

In **Settings, Connections**, add a Langfuse connection:

| Field | Meaning |
| - | - |
| `host` | Base URL of the Langfuse server, for example `https://cloud.langfuse.com` |
| `public_key` | Project public key |
| `secret_key` | Project secret key. Stored encrypted, shown masked afterwards |
| `fetch_content` | Request observation input and output. Default `true` |

Apgar authenticates with HTTP Basic (`public_key:secret_key`) and reads the project id from `GET /api/public/projects`, taking the first project the keys can see. Use **Test** to check the keys. A connection that an agent uses cannot be deleted until that agent is changed or deleted.

`fetch_content` lets Apgar read observation input and output. The output is reduced to its length and JSON validity, tool inputs to a keyed hash of the arguments, and neither is stored. Set it to `false` if you do not want content to leave Langfuse. **Output length** still works from token counts, but **Format failure rate**, **Retry rate**, and **Loop rate** are then unavailable.

## Add an agent

Choose **Add agent** with the Langfuse source, pick the connection, and describe which traces belong to the agent:

| Filter | Match |
| - | - |
| Trace name | The trace name equals this value |
| Tags | The trace has all of these tags |
| Metadata | The trace metadata has each of these key and value pairs |

A filter needs at least a trace name, a tag, or a metadata pair. One project can feed several agents. When two filters match the same trace, the agent created first owns it, and `apgar_langfuse_filter_overlap_total` counts the overlap.

> [!WARNING]
>
> The Langfuse Python SDK v4 and JS SDK v5 export only their own spans, spans that carry a `gen_ai.*` attribute, and spans from known LLM instrumentation scopes. Tool and agent spans from other instrumentation never reach Langfuse, so Apgar cannot see their errors, retries, and loops. Pass a permissive `should_export_span` (`shouldExportSpan` in JS) to the SDK if your tool spans are filtered out.

## Release, environment, and session

The connector maps Langfuse fields onto the same attributes the OTLP path uses:

| Langfuse | Apgar |
| - | - |
| Trace release | Release identifier |
| Observation environment | Environment |
| Session id | Session |
| Prompt name and version | Prompt version, as `name@version` |
| Observation type | Span kind: `agent`, `generation`, `tool`, `retriever`, and `chain` or `span` at the root |
| Observation level `ERROR` | Error status. The status message becomes the error type |
| Usage details `input`, `output` | Token counts |
| Cost details `total`, else the observation `totalCost` | Cost in US dollars |
| Trace metadata, trace tags, user id | Stored as span attributes. See [Data handling](https://docs.useapgar.dev/privacy/data-handling.md) |

Set the release on every trace, for example from your deploy pipeline. A trace without a release is stored as `untagged` and is never evaluated. A prompt version change inside one release shows up as a **Prompt version** [slice](https://docs.useapgar.dev/concepts/metrics.md#slices); it does not open a new release by itself.

Set the agent's **Release attribute** to `langfuse.release` to read the trace release, or to `langfuse.trace.metadata.<key>` to read a metadata key, for example `langfuse.trace.metadata.version` for the key `version`. Apgar reads Langfuse traces only through their Langfuse fields, so `apgar.release`, `gen_ai.agent.version`, or `service.version` leave every turn `untagged`.

The agent's **Environment** works as it does for OTLP: only turns whose Langfuse environment equals it create releases and count in comparisons. **Add agent** fills in `production`. Set it to the environment your traces carry, `default` when the SDK sets none, or clear it to accept every environment. To read the surface from Langfuse, set **Surface attribute** to `metadata.<key>` for a metadata key, or `tag:<prefix>` to use the rest of the first tag that starts with the prefix. See [Attribute reference](https://docs.useapgar.dev/send-traces/attributes.md).

## Sync cycle

The worker runs one sync cycle per connection every 60 seconds (`APGAR_LANGFUSE_SYNC_INTERVAL_SECONDS`):

1. The window runs from the watermark minus a 30 minute lookback to 2 minutes before now. The first successful cycle of a connection starts 24 hours back. It runs within a minute of saving the connection, even before an agent uses it, so an agent added later sees traces from about 30 minutes before it was added on.
2. Phase one lists the root observations in the window that match each agent filter.
3. Phase two loads the remaining observations of those traces in batches of 50 trace ids, over a window widened by one hour on each side so that late children are found.
4. The watermark moves forward only after the whole window has been read.

A request that fails with 429, a 5xx status, or a network error is retried up to 8 times, waiting `min(60, 2^attempt)` seconds plus up to one second of jitter. A numeric `Retry-After` header replaces the computed wait. After the eighth failure the cycle fails and the watermark stays put, so the next cycle re-reads the same window. A failing connection does not hold back other connections. The sync status is shown on the agent page.

The lookback covers observations that become visible late. Langfuse delays data from exporters that do not send `x-langfuse-ingestion-version: 4`, and from SDKs older than Python 4.7.0 or JS 5.4.0, by up to 15 minutes. Self hosted v4 can set `LANGFUSE_MIGRATION_V4_NATIVE_OTEL_BEHAVIOUR=direct` to remove that delay.

## Trace ids

A Langfuse trace id of 32 hex characters is kept, lowercased. Any other id is replaced with the first 32 hex characters of its SHA-256, and the original stays on the span attribute `langfuse.trace.id`. Observation ids follow the same rule with 16 characters. Apgar stores no links into Langfuse; search the trace id there to open a trace.

## Export from the Langfuse SDKs instead

The Langfuse Python SDK v4 and JS SDK v5 are built on OpenTelemetry, so the same tracer provider can also export to Apgar directly while it reports to Langfuse. Add an OTLP/HTTP exporter for Apgar as described in [OpenTelemetry](https://docs.useapgar.dev/send-traces/opentelemetry.md). The Langfuse export filter applies to the Langfuse span processor only; a second exporter on the same provider receives every span.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.