Storing and Using JSON in Customer.io

Customer.io partner logo

Table of Contents

Summarize this documentation using AI

This banner was added using fs-inject

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Overview

Storing and using JSON in Customer.io is how you keep rich, structured customer context (like cart contents, product attributes, and preference data) attached to a person or an event, so messages can be truly product-aware instead of generic. For D2C retention, JSON is the difference between “You left something behind” and “Your size M, black colorway is still in stock, complete checkout with free shipping.”

If you want this data to translate into higher conversion flows quickly, Propel helps teams implement clean schemas and reusable personalization patterns inside Customer.io, so your journeys ship faster and stay maintainable. If you want to pressure test your data plan before you build, book a strategy call.

How It Works

Storing and using JSON in Customer.io works by passing structured key value data in your person attributes and event payloads, then referencing that data in segmentation rules and message personalization.

In practice, you will use JSON in three places:

  • Event payloads (best for behavior snapshots): send a Checkout Started or Added to Cart event with a JSON array of items, totals, currency, and any merchandising tags you want to personalize with.
  • Person attributes (best for “latest known state”): store things like preferred size, skin concern, last browsed category, loyalty tier, or last cart summary (careful with staleness).
  • Message rendering and decisioning: pull JSON fields into Liquid to print dynamic content, loop through arrays (like line items), and branch logic based on values (like AOV thresholds or category affinity).

Most D2C teams get the best outcomes by keeping the “truth” in events (time-stamped, attributable), and only promoting a small set of stable fields to person attributes for easy segmentation. If you need help mapping that split cleanly in Customer.io, start with the revenue-critical flows first (cart, post-purchase, winback), then expand.

Step-by-Step Setup

Storing and using JSON in Customer.io starts with a schema you can actually operationalize across cart recovery, post-purchase, and reactivation.

  1. Define your JSON schema for the use case (cart, browse, order). Keep names consistent, avoid one-off keys, and decide what is required versus optional.
  2. Instrument events with JSON payloads from your storefront or CDP. For abandoned checkout, include keys like checkout_id, value, currency, and items (an array of objects with product_id, name, variant, price, quantity, image_url, url, collections).
  3. Decide what should live on the person. Only store JSON on the profile if it is either stable (preferences) or you intentionally maintain it (like “last_cart” that you overwrite every time).
  4. Validate the payload in real traffic. Trigger the event yourself, then confirm the JSON appears as expected and keys are spelled consistently (case mismatches are a common silent failure).
  5. Use JSON in Liquid for message content. Pull top-level keys for headlines (like {{event.value}}) and loop items for product blocks (name, image, link).
  6. Use JSON-driven branching for targeting. Example: branch high intent carts (value above threshold, returning customer) into SMS plus email, and low intent into email only.
  7. Set guardrails for missing fields. Add fallbacks in Liquid (default images, default product names), and keep a “safe” generic module so messages never break.

When Should You Use This Feature

Storing and using JSON in Customer.io is the right move when message relevance depends on the specific products, variants, or order details, not just a generic segment label.

  • Abandoned cart and abandoned checkout recovery: include line items, totals, and deep links so the email renders the exact cart and the CTA returns to checkout.
  • Product discovery journeys: pass browse events with JSON like category, tags, price_range, then recommend complementary products based on what they actually viewed.
  • Post-purchase cross-sell: send an Order Completed event with items, then branch to replenishment timing or accessory upsell based on product type.
  • Reactivation with context: store last purchased category and last order value, then tailor winback offers (for example, “restock your essentials” versus “new drops in your style”).

Realistic scenario: a skincare brand wants to reduce discounting in cart recovery. They send cart JSON with items[].product_type and items[].inventory_status, then only shows an incentive if the cart contains non-core products and the shopper is new. Returning customers see social proof and routine guidance instead.

Operational Considerations

Storing and using JSON in Customer.io requires operational discipline, because small data inconsistencies create big downstream messaging issues.

  • Schema governance: document keys and types (string, number, array). If one engineer sends productId and another sends product_id, your Liquid and segments will fragment.
  • Event versus profile strategy: JSON on events is naturally time-bound and auditable. JSON on profiles can go stale fast, especially for carts. If you store “last_cart” on the profile, you must overwrite it on every cart change and clear it after purchase.
  • Segmentation performance and simplicity: keep segments based on a few reliable fields. Use JSON for personalization depth, and promote only the fields you truly need for targeting into top-level attributes.
  • Orchestration across channels: cart JSON should be consistent across email and SMS logic. If SMS cannot render product blocks, use JSON to pick a single hero item and link back to checkout.
  • Attribution and dedupe: include stable identifiers like checkout_id or order_id in JSON so you can prevent duplicate sends and set clean exit conditions.

Implementation Checklist

Storing and using JSON in Customer.io goes smoothly when you lock the data contract before building journeys.

  • JSON schema documented with required keys, optional keys, and data types
  • Consistent naming conventions (snake_case or camelCase), enforced across sources
  • Cart or checkout events include identifiers (checkout_id) and deep links
  • Order events include order_id, totals, and line items needed for cross-sell logic
  • Fallback logic in Liquid for missing images, names, or URLs
  • Segments rely on stable attributes, not fragile nested keys when avoidable
  • Exit conditions use identifiers to stop flows after purchase
  • Test events sent from staging or internal accounts and verified end to end

Expert Implementation Tips

Storing and using JSON in Customer.io becomes a revenue lever when you design it around merchandising and margin, not just personalization.

  • Pick a “hero item” consistently: in retention programs we’ve implemented for D2C brands, we often standardize on the highest priced item or highest margin item in items[] as the hero for subject lines and SMS. That keeps creative consistent and improves click quality.
  • Store merchandising tags in JSON: include fields like collection, is_core, is_new, margin_band, or replenishable. Then your flows can reduce discounting on core items and shift incentives to where you can afford them.
  • Use JSON to control frequency: attach cart_updated_at or a cart version number. Only send the next reminder if the cart has not changed since the last message, which reduces “wrong cart” complaints.
  • Keep templates modular: build one cart module that loops items, then reuse it across email variants (reminder 1, reminder 2, last chance). You change it once, you improve the whole program.

Common Mistakes to Avoid

Storing and using JSON in Customer.io can backfire when the data is messy, stale, or too complex for the team to maintain.

  • Using profile JSON for carts without a clearing rule: customers buy, but your “last_cart” still shows old items, which creates confusing post-purchase messages.
  • Over-nesting JSON: deeply nested structures make Liquid and segmentation brittle. Flatten what you can, and keep arrays predictable.
  • Missing fallbacks: one null image_url can break an entire product grid in an email. Always default to a safe layout.
  • Inconsistent key naming across platforms: Shopify app sends variant_id, your custom script sends variantId. Your template works for half your audience and silently fails for the rest.
  • Segmenting on fields that are not stable: targeting “has items[].collection = X” can be powerful, but if collection tags change frequently, your audience definitions will drift.

Summary

Use storing and using JSON when you need product-level context to drive cart recovery, post-purchase upsell, and smarter winbacks. It matters because structured data turns generic blasts into specific, shoppable messages that convert.

If you want to operationalize it across your highest revenue flows, implement it with clean schemas and reusable templates in Customer.io.

Implement with Propel

Propel helps D2C teams design JSON schemas, event payloads, and message templates that stay reliable as your catalog and journeys scale in Customer.io. book a strategy call.

Contact us

Get in touch

Our friendly team is always here to chat.

Here’s what we’ll dig into:

Where your lifecycle flows are underperforming and the revenue you’re missing

How AI-driven personalisation can move the needle on retention and LTV

Quick wins your team can action this quarter

Whether Propel AI is the right fit for your brand, stage, and stack