> ## 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.

# User Signals & Journeys

> Connect what your users do to the AI traces behind it

An AI trace (input, output, reasoning) only tells you what the model did. It doesn't tell you whether that was actually useful: did the user accept it, edit it, cancel it, escalate it to a human? That's what a **signal** is: an event you send us about user or product behavior.

A **journey** is the thread that ties a user's signals to the AI traces that happened around them, even across multiple calls or agents. Every signal and every trace carries the same `journey_id`, so DataFramer can line them up into one timeline.

## The pieces

<CardGroup cols={2}>
  <Card title="Browser SDK" icon="browser" href="/user-signals/browser-sdk">
    `@dataframer/signals`: runs in your frontend, sends `track`/`identify`/`group` events, and generates the journey id.
  </Card>

  <Card title="Server Instrumentation" icon="server" href="/user-signals/server-instrumentation">
    `dataframer-journey`: runs in your backend, picks up the journey id, and stamps it onto your Langfuse traces automatically.
  </Card>

  <Card title="Connect AI Observability" icon="plug" href="/user-signals/connect-langfuse-langsmith">
    Already using an observability tool? Connect it and DataFramer pulls the traces in directly. Langfuse and LangSmith are supported today.
  </Card>
</CardGroup>

## How it fits together

```
Browser                    Your Backend                 DataFramer
--------                   ------------                 ----------
@dataframer/signals   -->  dataframer-journey      -->  Trace has
sends track/identify/      stamps journey_id onto        metadata.journey_id
group events, tagged       every Langfuse trace
with journey_id                                     -->  Signal has the
                                                          same journey_id

                            Both land on DataFramer with the same journey_id
                            and get lined up into one timeline.
```

You only need the browser SDK if you want to capture user/product events. You only need the server library if you want your AI traces auto-tagged with the journey id. If your traces already live in an observability tool (Langfuse or LangSmith today), you don't need either: just [connect it](/user-signals/connect-langfuse-langsmith) and DataFramer pulls them in. Most setups combine the SDK with one of the other two.

<Note>
  Both packages are already published: `npm install @dataframer/signals` and `pip install dataframer-journey` work today. This feature is early; reach out at [info@dataframer.ai](mailto:info@dataframer.ai) if you hit anything unexpected.
</Note>
