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

> ## Agent Instructions
> Install the Courier skill before writing code: `npx skills add trycourier/courier-skills`. It carries the verified SDK shapes and the rules you cannot get wrong.
> Authenticate every request with `Authorization: Bearer <API_KEY>`. A workspace has several environments and each has its own keys, which are plain `pk_` strings with no environment prefix. Start with Test.
> Send with `client.send.message`, the default import of the v7 Node SDK. Reference a template by its `nt_` id or its alias.
> A send accepts a bare Elemental element list, but storing content on a template requires the top-level elements wrapped in a channel element.
> Templates and journeys can be built in the Courier app or created through the API. Either way they live in the workspace and are referenced by ID when you send.
> The hosted MCP server is https://mcp.courier.com. For a briefing on what Courier is and when to use it, read https://www.courier.com/llms.txt.
> Prefer the Guides tab for how-do-I questions and the Docs tab for how-does-it-behave questions. The API reference lives under /api-reference.

# Data mapping for push and inbox

> Choose which send data fields reach a delivered push or inbox message.

export const Endpoint = ({method, path, name, href, children, bare}) => {
  const verb = String(method || "").toUpperCase();
  const title = verb + " " + path;
  const label = children || name || path;
  if (bare) {
    return href ? <a href={href}><code>{title}</code></a> : <code>{title}</code>;
  }
  if (!href) {
    return <span className="cx-endpoint" data-method={verb} title={title}>
        <span className="cx-endpoint-label">{label}</span>
        <span className="cx-endpoint-method">{verb}</span>
      </span>;
  }
  return <a className="cx-endpoint" data-method={verb} href={href} title={title}>
      <span className="cx-endpoint-label">{label}</span>
      <span className="cx-endpoint-method">{verb}</span>
    </a>;
};

export const AppLink = ({href, children, name, bare}) => {
  const label = children || name || "Open in Courier";
  if (bare) {
    return <a href={href} target="_blank" rel="noreferrer">{label}</a>;
  }
  return <a className="cx-endpoint" data-kind="app" href={href} target="_blank" rel="noreferrer">
      <span className="cx-endpoint-label">{label}</span>
      <span className="cx-endpoint-method" aria-hidden="true">↗</span>
    </a>;
};

export const Doc = ({href, children, name, bare}) => {
  const label = children || name || href;
  if (bare) {
    return <a href={href}>{label}</a>;
  }
  return <a className="cx-endpoint" data-kind="doc" href={href}>
      <span className="cx-endpoint-label">{label}</span>
      <span className="cx-endpoint-method">DOC</span>
    </a>;
};

Data mapping decides which of a send's `data` fields reach the delivered push or inbox message.

<Warning>
  **You probably do not need this page.** Data mapping applies only to **legacy block-based templates**, the ones built in the older designer. On anything else, your whole `data` object already reaches the device:

  * A template built in <Doc href="/docs/design/templates/design-studio">Design Studio</Doc> passes `data` through automatically. Its push and inbox settings still show a **Data mapping** editor, but Courier does not evaluate it. The mapping is skipped and the full `data` object is used.
  * A send with inline `content` and no template needs no mapping at all.

  If your fields are not arriving and the template was built in Design Studio, data mapping is not the cause. See <Doc href="/docs/design/templates/variables">variables</Doc> and check the payload in <AppLink href="https://app.courier.com/logs">Logs</AppLink>.
</Warning>

That leaves the legacy case. A block-based template's push or inbox channel renders `data` into variables only unless mapping is on. The push data bag then carries just Courier's tracking keys, and your own fields never leave the send.

## Turn data mapping on

Open the template in the <AppLink href="https://app.courier.com/content/templates">console</AppLink>, then the channel's settings, and go to the **Data Mapping** tab. It appears for push and inbox channels only. Enable it and write a mapping that builds the data object from the incoming request.

<Frame caption="The push channel settings modal with the Data Mapping tab selected, showing the toggle and the mapping editor.">
  <img src="https://mintcdn.com/courier-4f1f25dc/fN1MbwzHtG3Vhos5/assets/data-mapping.webp?fit=max&auto=format&n=fN1MbwzHtG3Vhos5&q=85&s=242c4d23f11a9fc6c50f83b6de00a4ed" alt="A push channel settings modal with Data Mapping selected, showing the Enabled toggle and a mapping editor that maps the incoming request to the push data payload" className="mx-auto" width="1714" height="1026" data-path="assets/data-mapping.webp" />
</Frame>

Pass the whole `data` object through:

```jsonnet theme={null}
{
  data: request("data"),
}
```

Or name the fields, and mix in values from elsewhere on the request:

```jsonnet theme={null}
{
  data: {
    order_id: request("data.order_id"),
    email: request("profile.email"),
    screen: "order-detail",
  },
}
```

`request()` reads from the send request. The paths are `data`, `profile`, `recipient`, `event`, `brand`, and `message`. Courier evaluates the mapping at send time. Jsonnet is the default processing mode.

## Limits & behavior

* **Legacy block-based templates only.** Elemental content skips the mapping and passes the full `data` object through. That covers every Design Studio template and every inline `content` send.
* **Push and inbox only.** No other channel carries a `dataMappingSettings` object, because no other channel has a data bag to fill.
* **An existing channel is never flipped for you.** The default is seeded when a channel is created. Turning mapping off stays off.
* **A provider override always wins.** A <Doc href="/docs/send/overrides#how-overrides-work">provider override</Doc> bypasses rendering, so it carries your fields whether or not the template maps anything.

## FAQ

<AccordionGroup>
  <Accordion title="My data is not reaching the device. What do I check?">
    Check which designer built the template first. A Design Studio template, and a send with inline `content`, already pass `data` through. Look at the payload you sent and at your variable paths, not at mapping. Only a legacy block-based template needs **Data Mapping** turned on in its push or inbox channel settings.
  </Accordion>

  <Accordion title="I turned Data Mapping on in Design Studio and nothing changed. Why?">
    Because the template's content is Elemental, Courier skips the mapping and uses the full `data` object. The editor is a leftover surface on that channel's settings, so there is nothing to configure. Your fields are already being passed through.
  </Accordion>

  <Accordion title="Does data mapping affect email or SMS?">
    Only push and inbox have a data payload for it to fill. Email and SMS render `data` into content through variables.
  </Accordion>

  <Accordion title="Can I set a mapping over the API?">
    Not on its own. Data mapping is a channel setting on the template, so it travels with the template. For a per-send payload, set the fields in a <Doc href="/docs/send/overrides#how-overrides-work">provider override</Doc> instead.
  </Accordion>
</AccordionGroup>
