Mapping Templates
Transform mapped values with Liquid templates. Combine fields, apply filters, set fallbacks, and use conditionals when mapping webhook and destination data in Ours Privacy.
Mapping templates let you transform a value as you map it, instead of sending the raw payload field through unchanged. Reach for them when a field needs to be combined, reformatted, given a fallback, or chosen conditionally before it reaches Ours Privacy or a destination.
Templates use Liquid, the same templating language popularized by Shopify. If you have never used Liquid, the Liquid playground is a quick way to experiment with the syntax.
Available today on webhook source mappings. Mapping templates are live for Webhook sources. Support for destination mappings is rolling out shortly.
How a mapping value is read
Every mapping field accepts one of three forms. Ours Privacy picks the right one automatically based on what you type:
- A plain value with no
{{ }}is sent as-is.checkout_completedmaps to the literal stringcheckout_completed. - A field path reads a value straight from the incoming payload. This is the most common form and what most mappings use. The original type is preserved, so a number stays a number.
- A template with a filter, an operator, or a conditional transforms a value before it is mapped.
{{ amount | divided_by: 100 }}runs the calculation before the value is stored.
You never have to choose a mode. Most fields are a simple path; add a filter or a conditional only when you need to transform the value.
Mapping a field directly
A field path is the standard way to map a value, and it is all most mappings need. Write either form:
$order.id
{{ order.id }}Both read order.id from the incoming payload and map it unchanged. Nested fields use dot notation, and the value keeps its original type, so a number stays a number and a boolean stays a boolean.
Use a path whenever the incoming value is already in the shape you want. Reach for a template (below) only when the value needs to be combined, reformatted, given a fallback, or chosen conditionally.
Reading payload fields inside a template
Inside a template, top-level fields are available by name and nested fields use dot notation:
{{ nested.customer.email | downcase }}If a field name collides with a reserved word, read it through the payload alias instead:
{{ payload.event | snake_case }}Missing fields render as empty rather than causing an error, so always pair an optional field with a fallback (see Set a fallback value below).
Available filters
Chain filters with the pipe (|) character to transform a value. Up to 8 filters can be applied to a single value.
| Filter | What it does | Example |
|---|---|---|
default | Falls back when the value is missing or empty | {{ email | default: "n/a" }} |
upcase / downcase | Changes letter case | {{ tier | downcase }} |
capitalize | Capitalizes the first letter | {{ name | capitalize }} |
snake_case / kebab_case / camel_case | Reformats a label into a single token | {{ "Gold Member" | snake_case }} |
strip | Trims surrounding whitespace | {{ name | strip }} |
append / prepend | Adds text before or after | {{ id | prepend: "ord_" }} |
replace / replace_first | Substitutes text | {{ sku | replace: "-", "_" }} |
slice | Takes part of a string | {{ code | slice: 0, 4 }} |
plus / minus / times / divided_by / modulo | Math operations | {{ amount | divided_by: 100 }} |
round | Rounds a number | {{ price | round: 2 }} |
to_number / to_boolean | Casts a string into a number or boolean | {{ "49.99" | to_number }} |
date | Formats a date string | {{ isoDate | date: "%Y-%m-%d" }} |
Conditionals
Use if, unless, and case to choose a value. These are the only block tags available; there are no loops and no variable assignment.
{% if amount > 1000 %}high_value_order{% else %}standard_order{% endif %}Examples
Common transformations, grouped by what you are trying to do.
Combine fields into one value
{{ order.id | prepend: "ord_" }}Set a fallback value
When a field may be absent, supply a default so the mapping is never empty:
{{ nested.customer.email | default: "unknown@example.com" }}Convert cents to a decimal amount
A single {{ ... }} expression preserves the result's type, so this maps a number, not a string:
{{ amount | divided_by: 100 }}Normalize an event name
Turn an inconsistent label into a clean, lowercase token:
{{ event | snake_case }}Choose an event name conditionally
{% if amount > 10000 %}enterprise_signup{% else %}signup{% endif %}Cast a string field to the right type
Some senders deliver numbers and booleans as text. Cast them so downstream destinations receive the expected type:
{{ payload.is_subscribed | to_boolean }}Tidy a messy label
Trim whitespace and lowercase a tier name in one chain:
{{ nested.customer.loyaltyTier | strip | downcase }}FAQs
Do I have to use templates?
No. Plain field paths like $order.id and {{ order.id }} work exactly as before. Templates are only used when you add a filter, an operator, or a conditional.
Why is my number arriving as a string?
A value made of mixed text and expressions (for example Order {{ order.id }}) is always sent as a string. To preserve a number or boolean, use a single {{ ... }} expression on its own with no surrounding text.
What happens when a field is missing?
Missing fields render as empty instead of failing. Add the default filter to supply a fallback, for example {{ email | default: "n/a" }}.
Can I loop over a list, such as line items?
No. Loops (for) and variable assignment (assign) are not available. Templates are limited to reading fields, filtering values, and the if / unless / case conditionals.
Are there limits?
Yes. A template can be up to 4096 characters, can apply up to 8 filters to a single value, and can produce up to 8192 bytes of output. Property names like constructor and __proto__ are blocked.
Where can I test my template?
Paste your template and a sample payload into the Liquid playground to preview the result, then confirm the live output in the Recent Events Dashboard.
Next Steps
- Configure incoming mappings on a Webhook source.
- Review destination transformation options in Data Mapping.
- Confirm field types and null handling in Data Types and Field Values.
- Verify your mapped output in the Recent Events Dashboard.
How is this guide?

