Summarize this documentation using AI
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.
- 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.
- Instrument events with JSON payloads from your storefront or CDP. For abandoned checkout, include keys like
checkout_id,value,currency, anditems(an array of objects withproduct_id,name,variant,price,quantity,image_url,url,collections). - 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).
- 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).
- 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). - 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.
- 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
productIdand another sendsproduct_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_idororder_idin 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, orreplenishable. 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_ator 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_urlcan 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 sendsvariantId. 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.