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

# Entity Mappings

> An org-wide key-value store that remembers how a source entity maps to anything else, across flows and runs

An **Entity Mapping** is a small record that remembers, for your whole organization, that an
external identifier maps to some value — for example that source employee `A123` was created in
your payroll system as salary transaction `99001`, or that department code `SALES` posts to cost
centre `4010`. Mappings are written and read by [Flow Engine](/flow-engine) nodes, so anything one
flow learns can be reused by any other flow, in any later run.

Entity mappings are deliberately **not** tied to a system integration or to the flow that wrote
them — only to your organization. That is what separates them from an
[Employee Mapping](/platform/other/employee-mapping), which ties a stored Employee to its
identifier in one specific connected system. Use employee mappings when Twine itself needs to
recognize a remote record; use entity mappings when *your flows* need to remember an arbitrary
relationship.

## How a mapping is addressed

Every mapping is identified by three parts:

* **Domain** — the [data domain](/platform/data-domains) the mapping belongs to, such as
  `employee` or `salary_transaction`.
* **Namespace** *(optional)* — a free-text label that keeps independent mapping sets apart within
  one domain. An `employee` domain can hold a `target-id` set and a `cost-centre` set side by
  side. Leaving the namespace blank uses the default set.
* **External ID** — the key within the set, typically the source system's identifier for the
  entity.

Each address holds one **value** (a plain string). Writing to an existing address replaces the
value — last write wins — so re-running a flow simply refreshes what is stored.

<Note>
  The namespace and external ID `*` is reserved for wildcard deletes (see below) and cannot be
  stored.
</Note>

## Metadata

A mapping can carry a small **metadata** map alongside its value: flat string keys with scalar
values, up to 2 KB. Metadata is for breadcrumbs about the source entity — the date a payment
occurred, the employee it belongs to — so that a later cleanup flow can reason about stored
mappings without re-fetching history from the source system. It is not a payload store; anything
larger than a few fields belongs elsewhere.

## The flow nodes

Five nodes work with the store. Their reference pages describe every field in detail:

* [Entity Mapping Put](/flow-engine/flow/entity_mapping_put) — stores or refreshes a mapping,
  optionally with metadata.
* [Entity Mapping Lookup](/flow-engine/assigns/entity_mapping_lookup) — reads one mapping into an
  assign (`nil` on a miss, so a following [Flow Guard](/flow-engine/flow-control/flow_guard) can
  branch on it).
* [Entity Mapping List](/flow-engine/assigns/entity_mapping_list) — reads a whole namespace (or
  domain) into an assign as a list of rows, ready for a
  [Flow Each](/flow-engine/flow-control/flow_each).
* [Entity Mapping Delete](/flow-engine/flow/entity_mapping_delete) — deletes a single mapping, or
  more with an explicit wildcard: `*` as the external ID clears a namespace, `*` for both
  namespace and external ID clears the whole domain. Wildcards must be typed literally in the node
  configuration — a value that merely *resolves* to `*` at runtime stops the flow instead of
  deleting, and a blank key never widens the scope.
* [Flow List Diff](/flow-engine/assigns/flow_list_diff) — compares any two lists by key and splits
  the first into "missing from" and "present in" the second. Not specific to entity mappings, but
  the natural companion for reconciliation.

## The canonical patterns

**Create-or-update against a target system.** Look the source entity up before acting: a miss
means create (and store the returned identifier), a hit means update.

1. *Entity Mapping Lookup* with the source entity's ID — the target ID lands in an assign, or
   `nil`.
2. The write action uses that assign to decide between create and update (for example the Fortnox
   *Upsert salary transaction* action, where a blank identifier creates and a present one
   updates).
3. *Entity Mapping Put* stores the identifier the target system returned, with any metadata worth
   keeping.

**Reconciliation.** When a source row disappears, its mapping — and the target record it points to
— becomes an orphan. Because flows usually sync a bounded window (say, last month's payments),
metadata makes it possible to clean up without fetching all of history:

1. Fetch the current source window.
2. *Entity Mapping List* the namespace, then filter the rows to the same window using their
   metadata (for example a stored `date`).
3. *Flow List Diff* the filtered mappings against the fetched rows — the "missing" output is
   exactly the orphans.
4. *Flow Each* over the orphans: delete the target record, then *Entity Mapping Delete* the
   mapping itself.

## Browsing and managing mappings

The **System Data → Entity Mappings** page in the Twine app lists every stored mapping for your
organization, with a search across domain, namespace, external ID, and value. From there you can
also:

* **Create a mapping manually** — useful for hand-known relationships such as department code to
  cost centre. Manual creation never overwrites an existing mapping; if the address is already
  taken you get an error instead.
* **Bulk delete** — select rows (or a whole page) and delete them after confirmation.

Every mapping the nodes delete is also recorded in the flow run's log with its scope and count, so
the run history doubles as an audit trail.
