Summarize this documentation using AI
Overview
If you’re sending events into Customer.io from a storefront, app, or backend, proxying is one of those “boring” data decisions that quietly determines whether your cart recovery and repeat-purchase automations fire reliably. If you want a second set of eyes on your current tracking and identity setup, you can book a strategy call—this is exactly the kind of plumbing that makes or breaks retention performance.
In practice, teams proxy requests when they need more control over what gets sent to Customer.io (and when), without shipping new frontend code every time marketing needs a new event property or a fix.
How It Works
Proxying means your site/app sends tracking calls to your endpoint first, and your server forwards the request to Customer.io’s Track API. That extra hop sounds like overhead, but it’s where you can enforce consistency: identity rules, property naming, and guardrails that keep segments and triggers from drifting.
- Data enters Customer.io through your proxy: the proxy receives browser/app events (like
product_viewed,added_to_cart,checkout_started,order_completed) and forwards them to Customer.io. - Identity resolution happens before forwarding: you decide what identifier is authoritative (email, internal customer_id, Shopify customer ID, etc.) and ensure you send the right
identifier(or equivalent) every time. This prevents “split profiles” that wreck suppression logic and frequency caps. - Event mapping is centralized: you normalize event names and properties so segmentation stays stable. Example: force
cart_valueto always be a number, forceskuto always be a string, and standardize currency. - Trigger reliability improves: because you can dedupe noisy events, backfill missing attributes, and block malformed payloads, your campaigns stop failing silently (e.g., cart abandonment journeys that never start because
added_to_cartsometimes arrives without an identifier).
Real D2C scenario: your cart recovery flow triggers on checkout_started. On iOS Safari, the frontend occasionally fails to send the event (or sends it without the logged-in customer ID). With a proxy, you can accept a lightweight client signal, enrich it server-side with the correct customer_id/email from session data, and forward a clean event to Customer.io—so the right person enters the journey every time.
Step-by-Step Setup
The goal here is simple: accept inbound tracking calls, validate/enrich them, then forward to Customer.io in a consistent format. Keep the first version minimal—then add enrichment and guardrails once you’ve verified events are landing correctly.
- Pick the endpoint you’ll expose
Decide where your site/app will send tracking: e.g.https://track.yourbrand.com/cioor/api/track. This becomes the single ingestion point for Customer.io events. - Define your identity contract
Decide what you’ll require to forward an event:- Logged-in users: always forward with internal
customer_id(preferred) and include email as an attribute update when available. - Anonymous users: either hold events until you can associate them, or forward as anonymous only if you have a clean merge plan later.
- Logged-in users: always forward with internal
- Normalize event names and properties
Create a mapping layer so incoming events from different sources don’t create multiple “versions” of the same behavior.- Example: map
addToCart,Added To Cart, andadded_to_cartintoadded_to_cart. - Force required properties for key triggers:
sku,product_id,price,currency,quantity,cart_id.
- Example: map
- Add validation + deduping
Reject or quarantine bad payloads (missing identifier, impossible timestamps, empty SKU). Add idempotency where it matters (e.g., dedupeorder_completedby order_id so you don’t double-trigger post-purchase flows). - Forward to Customer.io Track API
From your server, send the cleaned payload to Customer.io using your server-side credentials. Keep credentials off the client—proxying is how you avoid leaking keys and losing control of ingestion. - Verify in Customer.io activity logs
Confirm:- Events appear on the right person profile (not a duplicate).
- Properties are typed as expected (numbers as numbers, timestamps as timestamps).
- Segments and campaign triggers match the same fields you’re sending.
When Should You Use This Feature
Proxying is worth it when you care about retention outcomes enough to treat tracking as production infrastructure. If your flows depend on tight timing windows and accurate identity, proxying tends to pay for itself quickly.
- Cart recovery that depends on precise triggers: you need
checkout_startedandadded_to_cartto land consistently with the right customer identifier, otherwise you’ll under-send (missed revenue) or over-send (spam + unsubscribes). - Repeat purchase programs driven by product-level behavior: if you segment on SKU/category affinities, you need normalized product IDs and consistent property naming across web/app/back office.
- Reactivation based on “last meaningful action”: if you’re calculating inactivity from events like
product_viewedorsite_active, you need deduping and bot filtering—or your “inactive” audience will be wrong. - Multi-source tracking: Shopify + custom app + subscription platform tends to create event duplication and identity drift unless you centralize rules.
Operational Considerations
Proxying doesn’t just change where data flows—it changes how stable your segmentation and orchestration can be. The operational win is consistency, but only if you set rules and enforce them.
- Segmentation accuracy depends on strict schemas: decide which events are “tier 1” (drive money) and lock their required properties. Your cart and purchase events should never be “best effort.”
- Identity drift is the silent killer: if the same person shows up as
emailon web andcustomer_idin backend, you’ll create duplicates. Your proxy should resolve to one canonical identifier before forwarding. - Event timing affects journey logic: if your proxy queues/retries events, you can accidentally deliver “abandoned cart” after the customer already purchased. Add ordering rules (or suppression checks) for key sequences like
checkout_started→order_completed. - Orchestration realities: if you run SMS + email, one bad event can trigger multiple channels. Put guardrails at ingestion (dedupe + validation) instead of trying to patch every journey.
Implementation Checklist
Before you call this “done,” make sure the proxy improves reliability rather than just adding another moving part. These are the checks we run to keep triggers and segments trustworthy.
- Canonical identifier defined (and enforced) for all forwarded events
- Event naming conventions documented and mapped (web/app/backend)
- Required properties enforced for revenue-driving events (cart + checkout + purchase)
- Deduping strategy in place for
order_completedand other high-impact events - Bot/internal traffic filtered (at least for view events used in segmentation)
- Retry + failure logging implemented (so you can see drops before revenue does)
- Customer.io profile inspection confirms events land on the expected person
- At least one critical journey tested end-to-end (e.g., abandoned checkout)
Expert Implementation Tips
Most teams proxy for security, then later realize the bigger win is data quality. If you design it like a retention system (not just a dev endpoint), you’ll get cleaner audiences and fewer false triggers.
- Build a “tiered” validation model: hard-fail purchase and checkout events if identity is missing; soft-accept low-stakes browse events but flag them.
- Attach an ingestion version: include something like
tracking_versionso you can correlate campaign performance shifts with tracking changes. - Enrich server-side whenever possible: add margin-friendly fields (category, subscription eligibility, LTV tier) at the proxy so segmentation doesn’t depend on brittle Liquid logic later.
- Use order_id as your “truth anchor”: for post-purchase flows, always key off order_id to prevent duplicates and to support clean refunds/cancellations logic downstream.
Common Mistakes to Avoid
Proxying fixes a lot, but it also makes it easier to accidentally create “two sources of truth.” Most issues show up as broken segments, duplicate profiles, or journeys that fire at the wrong time.
- Forwarding events without a stable identifier: this creates anonymous activity you can’t reliably merge later, especially across devices.
- Letting event names drift: one team sends
checkout_started, another sendsbegin_checkout, and your cart recovery trigger only listens to one. - Not typing properties consistently: strings vs numbers (e.g.,
"99.00"vs99) breaks comparisons and “spent over X” segments. - No dedupe on purchase: double-sent
order_completedwill over-trigger cross-sell, review requests, and VIP tagging. - Retrying without ordering logic: late-arriving events can trigger “abandoned” messaging after conversion, which hurts trust and deliverability.
Summary
Proxying requests is a retention reliability play: it tightens identity, normalizes events, and keeps segmentation stable. If you’re serious about cart recovery and repeat purchase automation, it’s one of the highest-leverage data-in improvements you can make.
Choose it when trigger accuracy matters more than “quickest possible tracking.”
Implement Proxying Requests with Propel
If you’re already running events into Customer.io, proxying is usually where we focus to stop identity drift and make triggers dependable across web + backend sources. When you want to pressure-test your event schema, dedupe rules, and merge strategy before it impacts revenue journeys, book a strategy call and we’ll walk through the exact requests you’re sending and what we’d tighten.
In most retention programs, the win isn’t “more events”—it’s fewer, cleaner events that you can trust to drive orchestration.