# ID Stitcher


The [ID stitcher]({{< ref "profiles/concepts/identity-graph.md" >}}) model maps and unifies all the specified identifiers across `inputs`. It tracks the user journey uniquely across all the data sources and stitches them together to a `rudder_id`.

{{< warning >}}
**When you define an ID stitcher model in `profiles.yaml`, you must also reference it from the corresponding entity in `pb_project.yaml`.**

Set `id_stitcher: models/<model_name>` on the entity (for example, `id_stitcher: models/user_id_stitcher` for the user entity). If this is missing, the intended ID stitcher is not used and you may get unintended results.
{{< /warning >}}

## Video walkthrough

{{< youtube jifDH8pvMsc >}}

## Overview

You can define an ID stitcher in the [pb_project.yaml]({{< ref "profiles/dev-docs/pb-project-yaml/" >}}) file:

```yaml
models:
    - name: model_name
      model_type: `id_stitcher`
      model_spec:
          entity_key: entity_name
          materialization:
              run_type: discrete/incremental
          incremental_timedelta: 96h
          edge_sources:
              - from: path/to_inputs_table
              - from: path/to_inputs_table
```

| Field | Description |
| :---------- | :------- |
| `name` | Model name. |
| `model_type` | Model type - set this parameter to `id_stitcher` to implement an ID stitcher. |
| `model_spec` | Defines the model configuration. |
| `entity_key` | Specifies the entity to stitch. |
| `run_type` | Run type - set this parameter to `discrete` or `incremental`. (Default is incremental). |
| `incremental_timedelta` | In incremental ID stitching, only events from the last run are typically processed to update the ID graph. However, since events can arrive in the warehouse with delays, this parameter adds a buffer period to ensure completeness. The ID stitcher will process events starting from `incremental_timedelta` before the last run timestamp, creating an overlap window to capture any delayed events. Default value: 4 days (96 hours). |
| `edge_sources` | List of inputs from [`inputs.yaml`]({{< ref "profiles/dev-docs/inputs-yaml/" >}}) and [`sql-models.yaml`]({{< ref "profiles/dev-docs/sql-model-yaml" >}}) used for identity stitching. |

## Example

```yaml
models:
    - name: user_id_stitcher
      model_type: id_stitcher
      model_spec:
          entity_key: user
          materialization:
              run_type: incremental
          incremental_timedelta: 96h
          edge_sources:
              - from: inputs/rsIdentifies
              - from: inputs/rsTracks
```

## Metadata logging

Two optional model spec flags control metadata logging for nodes and direct edges in the resulting [Identity Graph]({{< ref "profiles/concepts/identity-graph.md" >}}). Both flags are supported for **Snowflake** and **BigQuery**.

| Flag | Default value | Description |
| :--- | :--- | :--- |
| `log_direct_edge_info` | `false` | Populates `direct_edge_info.edges_by_type` on the per-row `METADATA` column with connected node IDs, their `first_seen_at` timestamps, and a per-source provenance array. |
| `log_node_metadata` | `false` | Populates `node_info` on the per-row `METADATA` column with one entry per input model that contributed the node. |

```yaml
models:
    - name: user_id_stitcher
      model_type: id_stitcher
      model_spec:
          entity_key: user
          log_direct_edge_info: true
          log_node_metadata: true
          edge_sources:
              - from: inputs/rsIdentifies
              - from: inputs/rsTracks
```

For the metadata column structure, per-source contract, and incremental-run behavior, see [Metadata and observability]({{< ref "profiles/concepts/identity-graph.md#metadata-and-observability" >}}).

When [cardinality rules]({{< ref "profiles/dev-docs/advanced-id-stitcher-features/id-graph-cardinality-rules.md" >}}) are enabled on the entity, the metadata column also carries `cardinality_info` on capped edges, and the `<material>_<entity>_CARDINALITY_AUDIT` table records every dropped edge along with the input model that contributed it.

<br />
