Inside Wunderkind + Braze: How Identity‑Resolved Signals Flow into Canvas via Custom Events and User Aliases
When you plug Wunderkind Signals into Braze Canvas, you are not just adding another webhook. You are wiring Wunderkind’s identity graph and behavioral decisioning directly into Braze’s custom events and user model, so Canvas can orchestrate high‑intent journeys using richer data and a far larger addressable audience. This walkthrough traces what actually happens under the hood—from an anonymous browser session all the way to /canvas/trigger/send.
From anonymous session to identity‑resolved Signal
A visit begins as an anonymous browser session. Wunderkind’s Identity Network resolves that session to an actionable email address using its graph of 9B+ recognizable devices and over a billion consumer profiles, allowing brands to identify 3–6x more of their traffic than typical ESP/CDP identity alone.
As the user browses, Wunderkind tracks high‑intent events—adds to cart, product views, category depth, and catalog changes (back‑in‑stock, price drop, low stock). These behaviors are evaluated against campaign logic in Wunderkind Core and, when they qualify, are turned into Signals such as cart abandonment, product abandonment, category abandonment, or a catalog alert.
Each Signal packages structured context—channel, purpose, user type, and item‑level metadata—into an internal payload that will eventually become Braze canvas_entry_properties and an Items[] array.
Preparing Braze user aliases via /users/export/ids
Before Wunderkind can hit the Canvas trigger endpoint, it must be sure Braze can actually resolve each recipient. The integration uses a dedicated ESP profile (EspName: "brazecanvas") and Canvas‑specific extra fields that store the target canvas_id for each campaign.
For every recipient in a batch, Wunderkind first calls Braze’s /users/export/ids API to confirm the presence of a user_alias keyed by wknd_email_id:
- If a profile already has a
user_aliaswithalias_label: "wknd_email_id", no extra work is needed. - If not, Wunderkind creates it via
/users/alias/new, then immediately associates the alias with the email using/users/trackso Braze has a fully realized profile before any Canvas send is triggered.
Because Braze does not expose a “flush complete” hook for these user updates, the integration deliberately introduces a small ~10‑second delay before triggering Canvas. This guards against race conditions where a send would otherwise arrive before alias creation has fully propagated in Braze.
User aliasing strategy: wknd_email_id
Wunderkind standardizes on a Braze user_alias label of wknd_email_id. This keeps Wunderkind’s identity layer logically separate from any client‑defined external_id strategy while still giving Canvas a stable key to address:
"user_alias": { "alias_name": "wknd.test.21@blackhole.ibx2.net", "alias_label": "wknd_email_id" }json
Operationally, this means:
- Wunderkind owns lifecycle of the
wknd_email_idalias for send‑level identity. - Clients are free to continue using
external_id, subscription groups, and custom attributes as they do today for segmentation, suppression, and reporting.
If a client later chooses to merge multiple Braze profiles, Braze’s own /users/merge API can be applied without changing the Wunderkind aliasing scheme.
Batching and /canvas/trigger/send with entry properties
Once aliases are in place, Wunderkind groups Signals into batches and invokes Braze’s /canvas/trigger/send endpoint. Batching is enabled by default with a maximum of 50 recipients per batch, and batches are grouped by canvas_id to minimize API overhead and keep targeting logic coherent at the Canvas level.
A representative request looks like this:
{ "canvas_id": "a3d9cdd8-9c3f-42bd-980e-78735e27f56a", "recipients": [ { "user_alias": { "alias_name": "wknd.test.21@blackhole.ibx2.net", "alias_label": "wknd_email_id" }, "email": "wknd.test.21@blackhole.ibx2.net", "canvas_entry_properties": { "Origin": "wunderkind", "DataOnly": "Y", "UserType": "prospect", "WkChannel": "email", "WkPurpose": "product abandonment", "WKCouponCode": "", "WKCouponPurpose": "", "Items": [ { "WkCopy": "Product name", "WkId": "012345", "WkImageUrl": "some-url.jpg", "WkUrl": "some-url.com" }, { "WkCopy": "Product name", "WkId": "012345", "WkImageUrl": "some-url.jpg", "WkUrl": "some-url.com" } ] } } ] }json
Key points for practitioners:
canvas_idis injected from Wunderkind Core campaign settings and maps 1:1 to a Braze Canvas configured for a given Signal type (e.g., Cart vs Product vs Category Abandonment).UserTypelets Canvas decision splits route prospects and customers down different paths without additional API variation.WkPurposeenables generic Canvas logic that can still branch behaviorally by purpose where needed.Items[]carries the dynamic product payload that renders in Braze using Liquid and Content Blocks.
Because entry properties are defined at the Canvas entry event, they can be referenced consistently across all Message steps in the journey.
Mapping canvas_entry_properties and Items[] into Liquid and Content Blocks
On the Braze side, Wunderkind’s integration auto‑provisions a set of HTML Content Blocks and a link template when the client connects their workspace via the Platform Integration Hub.
The standard blocks include variants like:
In an HTML editor template, a simple implementation might look like:
<body> } <div> <a href="}">Unsubscribe</a> </div> </body>html
Behind that content block, Braze uses Liquid to iterate over canvas_entry_properties.Items and output images, copy, and URLs. The mock JSON used for QA looks like:
[ { "WkCopy": "Lorem ipsum dolor sit amet", "WkImageUrl": "https://assets.bounceexchange.com/.../test1.png", "WkUrl": "https://www.wunderkind.co/", "WkId": "12345" }, { "WkCopy": "Lorem ipsum dolor sit amet consectetur", "WkImageUrl": "https://assets.bounceexchange.com/.../test5.png", "WkUrl": "https://www.wunderkind.co/", "WkId": "12345" } ]json
Braze admins can preview dynamic products by pasting this JSON into the Canvas message “Context → Items” panel and verify that the chosen Content Block renders as expected before going live.
For drag‑and‑drop templates, the same blocks are embedded via an HTML element that contains only the Liquid tag (for example, }), with responsive CSS injected either through the template’s <style> block or Braze’s Custom Head HTML.
How this feels inside Braze Canvas
Operationally, Braze remains the system of execution:
- You create and tag Canvases like
Wunderkind - Cart AbandonmentorWunderkind - Price Drop, using API‑Triggered entry and a sharedactive_signal_emailcustom attribute to coordinate cross‑Canvas priority and cleanup. - You define entry/exit audiences, purchase suppressions, consent checks, and frequency caps per normal Braze best practices.
- Wunderkind simply calls
/canvas/trigger/sendwith alias + entry properties whenever its decisioning engine determines that a user should enter that flow.
For lifecycle engineers and solutions architects, the net effect is that Spark‑like identity and intent resolution is abstracted into a Signals layer, while Braze’s Canvas logic, templates, link templates, and content blocks continue to behave exactly as expected—only now with a much richer, identity‑resolved firehose of triggers powering them.