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

# Profile field mapping

> Sync any Omneo Profile attribute into a Shopify customer metafield by creating the metafield definition in Shopify, then mapping it in the Omneo CX app.

Any Omneo Profile attribute can be synced into a Shopify customer metafield. The mapping surface is general purpose, so you are not limited to a fixed list of supported fields: if the value exists on the Omneo Profile and a metafield exists in Shopify to receive it, you can connect the two without an Omneo release.

<Info>
  This page covers Profile field mapping. For mapping Shopify product fields into Omneo, see the product **Field mapping** section in [Setting up the Shopify extension](/extensions/shopify/setup).
</Info>

Configuration is two steps, in this order.

<Steps>
  <Step title="Create the metafield in Shopify">
    Shopify will not store a value in a metafield that has no definition, so the metafield must exist before you can map to it.
  </Step>

  <Step title="Map the field in the Omneo CX app">
    Choose the Omneo field, choose the Shopify field, and the extension writes the value on every sync.
  </Step>
</Steps>

## Fields you do not need to map

A core set of fields syncs by default in both directions. Do not create mappings for these. Custom mappings are applied on top of the defaults and are resolved last, so a custom row targeting one of these fields overrides the default behaviour, which is rarely what you want.

### Shopify Account to Omneo Profile

Applied on every sync, on both create and update:

| Omneo Profile field  | Source                  | Behaviour                                                                                         |
| -------------------- | ----------------------- | ------------------------------------------------------------------------------------------------- |
| `first_name`         | Shopify first name      | Falls back to `Unknown`. On update, `Unknown` is dropped so it never overwrites an existing name. |
| `last_name`          | Shopify last name       | Same fallback and update behaviour as `first_name`.                                               |
| `email`              | Shopify email           | Falls back to `{customerID}@example.com` when the Shopify record has no email.                    |
| `mobile_phone`       | Shopify phone           | Written only when a phone number exists.                                                          |
| `tags`               | Shopify tags            | Filtered by the tag whitelist, prefixed, then sorted.                                             |
| `joined_location_id` | Default or POS location | Written only when a location resolves and the Profile does not already have one.                  |

Applied only when the Profile is first created:

| Omneo Profile field                              | Source                                  | Behaviour                                                                                                                |
| ------------------------------------------------ | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `identities`                                     | Identity handle and Shopify customer ID | The primary matching identity, plus any additional mapped identities. See [Mapping Identities](#mapping-identities).     |
| `joined_at`                                      | Shopify created date                    | Recorded in UTC.                                                                                                         |
| `preferred_location_id` and `joined_location_id` | Default location                        | Written only when a default location is set.                                                                             |
| `region_id`                                      | Default region                          | Written only when a default region is set.                                                                               |
| `attributes.comms`                               | Marketing consent                       | Email and SMS opt-in state with consent timestamps. Skipped when marketing updates are disabled, except on first create. |
| `statuses`                                       | Shopify customer state                  | Set to `['guest']` when a newly created Shopify Account is disabled.                                                     |
| `addresses`                                      | Shopify addresses                       | Each address that has an `address1`, mapped and linked back to Shopify.                                                  |

### Omneo Profile to Shopify Account

| Shopify field               | Source              | Behaviour                                                                          |
| --------------------------- | ------------------- | ---------------------------------------------------------------------------------- |
| `firstName`                 | `first_name`        | Skipped when the value is `unknown`.                                               |
| `lastName`                  | `last_name`         | Skipped when the value is `unknown`.                                               |
| `email`                     | `email`             |                                                                                    |
| `phone`                     | `mobile_phone_e164` |                                                                                    |
| `tags`                      | Omneo tags          | Prefixed, `cx-` by default.                                                        |
| `metafields[omneo.balance]` | Balance fields      | Always written. See [The legacy balance metafield](#the-legacy-balance-metafield). |
| Marketing consent           | `attributes.comms`  | Email and SMS consent state.                                                       |
| Addresses                   | Profile addresses   | Written on create.                                                                 |

## Step 1: Create the metafield in Shopify

Go to **Settings > Custom data > Customers** in Shopify admin:

```text theme={null}
https://admin.shopify.com/store/[tenant]/settings/custom_data/customer/metafields
```

Select **Add definition** and create one definition for each Omneo value you want to sync.

### Definition settings

| Setting                | What it does                                                                                                                                                                                         | Guidance for Omneo fields                                                                                                                                                                                       |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Name**               | The human readable label shown wherever the metafield appears in Shopify admin.                                                                                                                      | Name it for the business meaning, not the Omneo field path. Use `Omneo Tier`, not `tier.name`. Prefixing with `Omneo` groups the synced fields together visually.                                               |
| **Namespace and key**  | The unique identifier for the metafield, in `namespace.key` form. Shopify prefills it from the name and restricts it to letters, numbers, underscores, and dashes.                                   | Replace the default `custom` namespace with `omneo`. This separates Omneo owned values from fields the merchant maintains by hand, and it matches the namespace the extension already uses for `omneo.balance`. |
| **Type**               | The content type of the value, chosen from Shopify's list of presets, for example single line text, integer, date, or JSON.                                                                          | Match the shape of the Omneo attribute. Text values such as a Tier name are `Single line text`. Point balances are `Integer`. Structured payloads are `JSON`.                                                   |
| **One** or **List of** | The selector to the left of the content type. **One** stores a single value. **List of** stores an ordered array of values of that type.                                                             | Use **One** unless the Omneo attribute genuinely holds multiple values. A mapping that writes a single string into a list type will not validate.                                                               |
| **Description**        | Optional free text explaining what the field holds and where it comes from.                                                                                                                          | Say that Omneo owns the value, so nobody on the merchant team edits it by hand and wonders why it reverts. For example, "The Profile's current Omneo tier".                                                     |
| **Validation**         | Optional rules constraining accepted values. The available rules depend on the type, for example minimum and maximum length for text, minimum and maximum for numbers, or a list of allowed choices. | Leave validation open unless you are certain of the value set. A validation rule that the Omneo value fails rejects the write, and the field then stays stale.                                                  |

<Warning>
  The type of a definition cannot be changed after it is saved. Changing a type means deleting the definition, which deletes the stored values, and creating it again. Confirm the type before you save.
</Warning>

### Options

| Option                                | What it does                                                                                                                                      | Guidance for Omneo fields                                                                                                                                                                                                       |
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Storefront API access**             | Exposes the metafield to the Storefront API so Liquid themes and custom storefronts can read it.                                                  | Turn on for any value the storefront needs to display, such as a tier badge or a points balance. Leave off for internal values.                                                                                                 |
| **Customer Account API access**       | Controls what a signed-in Profile can do with the metafield through the Customer Account API. Shopify offers no access, read, and read and write. | Grant the lowest level the experience needs. Omneo is the system of record for these values, so read is the right default. Read and write allows the Profile to overwrite what Omneo synced, which the next sync then reverses. |
| **Filter or group data in Analytics** | Makes the metafield available as a filter and grouping dimension in Shopify Analytics.                                                            | Turn on for values the merchant will report on, such as tier or lifecycle status.                                                                                                                                               |
| **Definition pinned**                 | Pins the metafield to the top of the Shopify Account detail page in admin so staff see it without expanding the metafields section.               | Pin the handful of fields that store and service staff actually use. Leave the rest unpinned.                                                                                                                                   |

## Step 2: Map the field in the Omneo CX app

Go to **Omneo CX > Settings > Profiles** in Shopify admin and open the **Field Mapping** tab:

```text theme={null}
https://admin.shopify.com/store/[tenant]/apps/omneo-cx/app/settings/profiles?tab=mapping
```

The **Profile settings** screen carries five tabs. Field Mapping is the last of them.

| Tab                 | Purpose                                                                                                                                                           |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Identity**        | The Omneo identity handle that links Omneo Profiles to Shopify Accounts, and the mapping of additional Identities. See [Mapping Identities](#mapping-identities). |
| **Tags & Sync**     | Tag whitelist, tag prefix, and sync controls.                                                                                                                     |
| **Webhook Filters** | Which Shopify webhook events the extension acts on.                                                                                                               |
| **Marketing**       | Marketing consent handling.                                                                                                                                       |
| **Field Mapping**   | Per field mapping between Omneo and Shopify, covered here.                                                                                                        |

Mappings are applied every time a Profile is synced.

### Anatomy of a mapping row

Select **Add mapping** to create a row. Each row is one field, in one direction.

| Control                         | What it does                                                                                                                                                                                                                                                                                                    |
| ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Omneo** and **Shopify** pills | Show the direction of the mapping, reading left to right. `Omneo → Shopify` writes an Omneo value into Shopify.                                                                                                                                                                                                 |
| **Omneo field**                 | The source attribute on the Omneo Profile, in dot notation. Nested values are addressed through their parent, for example `tier.name`.                                                                                                                                                                          |
| **Shopify field**               | The destination on the Shopify Account. Native fields and any customer metafield defined in Step 1 are both valid targets. Metafields are addressed as `namespace.key`, for example `omneo.current_tier`.                                                                                                       |
| **Enter manually**              | Switches the selector to a free text input. Use it when the field you need does not appear in the list, which happens with newly created metafields and with less common Omneo attributes. Type the exact path, because it is not validated against a schema.                                                   |
| **Format**                      | Optional. Resolves the value through a format instead of copying it across unchanged. Product mapping offers `Direct` and `Template` formats, documented in [Setting up the Shopify extension](/extensions/shopify/setup). Check the options presented on the row for the formats available to Profile mapping. |
| **Array Select**                | Optional. For source attributes that hold an array, selects which entry is used instead of writing the whole array.                                                                                                                                                                                             |
| **Default**                     | Optional. A fallback value used when the source attribute is empty.                                                                                                                                                                                                                                             |
| Delete icon                     | Removes the mapping. Values already written to Shopify are not cleared, so remove the mapping and then clear the metafield if the value must not persist.                                                                                                                                                       |

**Format**, **Array Select**, and **Default** are available independently on each side of the row.

## Mapping Identities

An **Identity** is an external ID associated with an Omneo Profile: the named slot that holds a Profile's unique identifier in a third-party system, such as a Shopify customer ID, a loyalty card number, or a staff number. Each Identity has a handle and an identifier, referenced together as `handle:identifier`, for example `shopify:12345`. Identities are what let Omneo unify one person's data across every system that knows them. See [Identities](/concepts/profiles/identities) for the concept and [Working with identities](/dev-guides/profiles/working-with-identities) for the API.

<Warning>
  Identities cannot be mapped through a Field Mapping row. The extension filters `identities` out of field mapping in both directions, because Identities are attached through the dedicated Identities API rather than written as a Profile attribute. A mapping row that targets `identities` is ignored.
</Warning>

Map Identities in the **Identity** tab of **Profile settings** instead. That tab handles two things:

| Setting          | Purpose                                                                                                                                                           |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Identity handle  | The handle used for the primary link between an Omneo Profile and a Shopify Account, `shopify` by default. Do not change this once Profiles have started syncing. |
| Identity mapping | Maps additional Omneo Identities to Shopify fields, including custom metafields, so an external ID held in Omneo can be written into Shopify and used there.      |

Identity mapping uses the same row model as Field Mapping: a source, a destination, and the optional modifiers. The difference is which side of the Profile the value is read from.

<Note>
  The Shopify Extension claims the `shopify` handle. Do not reuse it for a mapped Identity, and do not point another Extension at it. Handle collisions cause the owning Extension to behave incorrectly.
</Note>

## Sync behaviour

* Mapped fields update automatically whenever the underlying attribute changes on the Omneo side. You do not need to trigger anything.
* Before launch, run a bulk resync so existing Profiles are brought up to date. New mappings apply from the moment they are saved, so without a resync the values populate slowly as each Profile happens to change.
* A mapping writes on sync only. Editing a metafield by hand in Shopify admin holds until the next sync of that Profile overwrites it.
* Custom mappings are resolved after the default field mapping, so a custom row pointed at a default target wins. Use this deliberately or not at all, because overriding a default such as `email` or `tags` changes behaviour the rest of the extension depends on.

## Example: syncing the current tier

Mapping the Omneo Tier name into a customer metafield:

| Step                   | Value                            |
| ---------------------- | -------------------------------- |
| Shopify metafield name | `Omneo Tier`                     |
| Namespace and key      | `omneo.current_tier`             |
| Type                   | One, Single line text            |
| Description            | The Profile's current Omneo tier |
| Omneo field            | `tier.name`                      |
| Shopify field          | `omneo.current_tier`             |

Adapt the pattern to whatever fields and naming approach suit the brand.

## Reading the value on the storefront

With **Storefront API access** enabled, a synced metafield is available in Liquid on the customer object:

```liquid theme={null}
{% if customer.metafields.omneo.current_tier %}
  <span class="tier-badge">{{ customer.metafields.omneo.current_tier.value }}</span>
{% endif %}
```

Syncing to a metafield suits values that are stable between purchases, such as tier or lifecycle status. For values that change often, or that are not synced at all, query Omneo directly using the token flow in [Shopify Authentication](/extensions/shopify/authentication).

## Recommended practice

<Tip>
  Record every field you plan to sync in a shared Data Dictionary before you create the definitions: business meaning, Omneo field path, Shopify namespace and key, type, and owner. Metafield types cannot be changed after creation and namespaces are hard to rename once values are live, so agreeing the naming convention up front is much cheaper than correcting it later.
</Tip>

## The legacy balance metafield

`omneo.balance` predates the field mapping system. It is a hardwired feature of the extension, it still works, and it holds a structured array of balance data for the Profile. The extension appends it to every Omneo to Shopify sync, so it is always present and always current without any configuration.

<Note>
  Do not create a definition for `omneo.balance` or map to it manually. The extension maintains it. Create separate metafields if you need individual balance values in their own fields.
</Note>

See [Setting up the Shopify extension](/extensions/shopify/setup) for the rest of the sync configuration, and [Shopify](/extensions/shopify/overview) for what the extension syncs overall.
