Data Mapping
JSONPath Data Mapping Guide
Data mapping in Peach allows you to extract information from incoming event payloads (like Shopify webhooks or custom API calls) and map them directly into variables, template placeholders, recipients, or deduplication keys.
This guide explains how to use JSONPath to map payload fields, from basic properties to complex structures and calculations.
1. Mappings Scopes in Peach
There are three main contexts where you will define data mappings in Peach:
- Recipient Mapping (recipient)
- Purpose: Tells Peach who should receive the message.
- Required fields: Typically maps a phone number (e.g. phone_number) and optionally a name.
- Note: If Peach cannot resolve the recipient's phone number, the automation will silently fail to send.
- Template Variables (variable)
- Purpose: Provides the dynamic content required by your WhatsApp template placeholders (e.g., {{1}}, {{2}} or named keys).
- Usage: Maps keys like customer_name or order_id to their values in the webhook payload.
- Deduplication Key (dedup_key)
- Purpose: Prevents duplicate messages from being sent if the source system sends the same event multiple times.
- Usage: Maps to a unique transaction ID (e.g. $.order.id or $.checkout.token).
2. Basic JSONPath Syntax
JSONPath is like XPath or CSS selectors, but for JSON objects. All JSONPaths in Peach must start with $. (which refers to the root of the event payload).
Static Values (No $. Prefix)
If a value doesn't start with $., Peach treats it as a static string fallback.
- Example: Mapping first_name to Valued Customer will always output "Valued Customer" regardless of the payload.
Direct Path Matching
- Payload:
{
"customer": {
"first_name": "Alice",
"phone": "+1234567890"
}
}- Mapping: $.customer.first_name -> Resolves to: "Alice"
- Mapping: $.customer.phone -> Resolves to: "+1234567890"
3. Peach-Specific Features & Smart Defaults
Peach has built-in smarts to make mapping easier and more resilient.
Subscriber & Contact Interchangeability
Peach automatically maps subscriber and contact as aliases.
- If your payload has a contact object but you write $.subscriber.name, it resolves correctly.
- Likewise, if your payload has a subscriber object and you write $.contact.name, it also resolves correctly.
Recursive / Deep Scanning ($..)
If you don't know the exact path of a field, or if it can appear at different levels of the JSON structure, use $.. to search recursively.
- Payload:
{
"customer": {
"default_address": {
"phone": "+1999999999"
}
}
}- Mapping: $..phone
- Resolves to: "+1999999999" (Peach finds the first non-nil match in the object structure).
4. Working with Lists (Arrays)
If your payload contains lists of items (e.g., order line items), you can extract items or count them.
Extracting a Specific Item (Index Subscript)
Use [0] to get the first item in a list (indexing starts at 0).
- Payload:
{
"items": [
{ "title": "Blue T-Shirt" },
{ "title": "Red Socks" }
]
}- Mapping: $.items[0].title -> Resolves to: "Blue T-Shirt"
Joining Multiple Items
Use [*] to select all items. If multiple matches are found, Peach automatically joins them with a comma.
- Mapping: $.items[*].title
- Resolves to: "Blue T-Shirt, Red Socks"
Array Length / Count Helpers
Peach supports .length, .size, and .count helpers directly at the end of your JSONPath.
- Mapping: $.items.length (or $.items.size, $.items.count)
- Resolves to: 2 (returns the count of items in the list).
5. Structured JSON Mapping (Fenced JSON Blocks)
Sometimes, you need to map complex parameters (like media file attachments with customized headers). You can provide structured JSON wrapped in markdown-style code fences: ```json ... ```. Peach will parse the JSON block and resolve any internal values starting with $. dynamically.
Example: Media Headers
When sending a document or image template, you might need to map both the URL and the filename dynamically.
- Value Input:
```json
{
"link": "$.data.invoice.pdf_url",
"filename": "$.data.invoice.display_name"
}- Payload:
{
"data": {
"invoice": {
"pdf_url": "https://example.com/inv_102.pdf",
"display_name": "Invoice_August.pdf"
}
}
}- Resulting Output:
{
"link": "https://example.com/inv_102.pdf",
"filename": "Invoice_August.pdf"
}6. Common Recipes & Examples
Setup a Notification (Shopify Order Paid)
When setting up a stream trigger on a Shopify Order Paid event, use these common mappings:
- Recipient Phone: $.customer.phone or $.customer.default_address.phone (or $..phone for safety)
- Deduplication Key: $.id (using the Order ID to prevent double-processing)
- Template Variable (Customer Name): $.customer.first_name
- Template Variable (Item Summary): $.line_items[*].title
- Template Variable (Item Count): $.line_items.length