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

# Collect and Correlate

> How DataFramer ingests signals and traces and stitches them into one journey

Once the [browser SDK](/user-signals/browser-sdk) and [server library](/user-signals/server-instrumentation) are wired in, DataFramer does the collecting and stitching for you. This page explains what happens behind the scenes: there's nothing you need to build here.

## Collect

Two independent streams land on DataFramer:

* **Signals**: `track`/`identify`/`group` events from the browser SDK, ingested through `/api/signals/*`.
* **Traces**: your AI calls, either [pulled from a connected observability tool](/user-signals/connect-langfuse-langsmith) (Langfuse or LangSmith today), or auto-tagged as they're created if you're on Langfuse v2 and using `dataframer-journey`.

Both carry the same `journey_id`, generated by the browser SDK and propagated by the server library.

## Correlate

DataFramer matches signals to traces on two keys:

1. **`journey_id`**: the primary match. Any signal and any trace sharing a journey id are grouped into the same journey timeline.
2. **Direct datapoint id**: some signals (like a reviewer's edit) point at one exact trace explicitly, independent of journey id. This is resolved immediately at ingest, so it's exact even if the journey correlation is looser.

The result is a single timeline per journey: product events, interleaved with the AI traces that happened inside it, even if those traces came from different agents or tools.

## Next steps

<Card title="View & Filter Journeys" icon="route" href="/journeys/overview">
  See the stitched result in the Journeys UI
</Card>
