Data and recipient
The Data panel defines the customer context an email can use and the recipient it goes to. A purchase follow-up may need both a contact and an order; selecting those inputs makes the relationship explicit for Liquid, Adaptyle and the system that triggers the send.
Open the Data tab beside the email. It shows the expected properties and recipient, followed by a Sample section. The sample’s Edit as JSON control opens the raw values; Hide JSON returns to the record pickers.
The list is a contract. The sending context supplies its expected properties, while maxclicks adds reserved branding data. Each record input needs the identity and fields appropriate to that operation; including a second record does not automatically look it up through the first.
On narrow windows the tabs collapse to icons. Select the Data icon to open the panel over the email, then close it to return to the full canvas.
Tell the email what it needs
Each row on the list is one piece of information, with a key you use in your content: {{ contact.firstName }}, {{ order.total }}. There are two kinds.
| Kind | What it is | How the row reads |
|---|---|---|
| Record | A contact, object, or event record, one or a list of them | The schema's name, with [] after it for a list |
| JSON | Any plain value you pass in: a coupon code, a total, a nested object | JSON |
Click a row to open it. A record shows every field of its schema. A JSON row shows the shape you defined for it.
The first row is always branding, ticked and greyed out, with a note reading "The branding data is added by the system. You do not need to set it in the sample data." That is your brand kit, added for you.
A reference to something that is not on the list renders as nothing at all.
Every editor warns you before that happens: in the visual editors the variable
turns amber, and in the MJML and HTML code editors the expression is
underlined. Both carry the same message, "name" isn't in your data, so this renders empty.
Add a property
Press Add property, beside the sentence above the list. It is there on a template and on a workflow send-email step, and never on a broadcast.
- Property type, placeholder "Pick a schema or JSON…". The dropdown groups your schemas under Contact schemas, Object schemas, and Event schemas, then offers JSON property under Other. Every schema in your space is offered, and the same schema can appear on the list more than once under different keys.
- Key. It is pre-filled from the schema, and you can type your own.
- Array of records, for a record. Off means one record, on means a list.
- Shape, for a JSON property. Paste a sample payload and maxclicks works the shape out, build it by hand, or leave it open to accept anything.
- Add.
Changing Property type after you have typed a key throws the key away and starts the row over. Pick the type first, then name it.
Naming rules
- Letters, digits, and underscores only. Spaces become underscores, anything else is deleted as you type, and the panel shows you the result: "Will be normalized to
yourkey". branding,skip, andlimitare taken. Using one gives you "Reserved."- Two rows cannot share a key: "A property with this key already exists."
The pre-filled key comes from the schema and drops any dash, so a schema slugged abandoned-cart suggests abandonedcart. Rename it in the Key field before you press Add if you would rather have something else, because a key cannot be changed afterwards.
Choosing between one and a list
A list is right when the email loops over it, such as the lines on an order. The whole list cannot be the recipient: the final path must resolve to one contact or an email-format value. If it ends at the array itself, validation reports "Recipient path should not point to an array of records, it should point to either a single contact record or an email address value."
Leaving a JSON shape open
An open shape accepts any JSON, which is convenient and costs you the safety net. maxclicks can only warn you about a misspelled variable when it knows the shape, so with an open one {{ payload.tpyo.name }} passes silently and renders empty. Define the shape for anything you will reference by name.
Remove a property
Untick the row. That is the only way, and there is no delete button, no confirmation, and no undo.
Removing a property also removes its expansion selection and clears a recipient pointing to it. Existing Liquid expressions remain in the content but lose their data source, so they can render empty. Review Personalize and Checks and repair those references after changing the model.
There is no rename either. Renaming is removing and adding, with all of the above.
On a standalone template, taking the last property off the list does not stick. Reopen the editor and a property for your space's default contact schema is back, with the recipient pointed at it.
Choose who receives it
To sits at the top of the panel. It is a chain: pick a property, and if it can be opened further, another dropdown appears after a chevron for the next step down.
Only two things qualify as a recipient:
- A single contact record. Not a list, and not an object or event record.
- A value declared as an email address, including an email-format JSON value or a stored email field reached through a record.
The Data path picker lets you navigate the declared data; recipient validation determines whether the final path is usable. Selecting a plain string, object or list does not make it a valid recipient. If there is no eligible row, the code editors say so directly: "No recipient is available yet. Add a contact record property or an email address property to the data representation to pick a recipient."
Leaving it empty gives you "Recipient path is not provided." next to the To row. The blank-looking dash entry at the top of the dropdown is the clear option, and picking it does exactly that.
Contact or bare email address
The two are not interchangeable.
| A contact record | An email address value | |
|---|---|---|
| Consent | Marketing checks the contact's subscription and selected topic | No contact subscription; applicable delivery suppressions still apply |
| Unsubscribe | A personal preferences link, managed for you | No personal link |
| Marketing | Allowed | Refused |
| Reporting | Opens and clicks attach to that contact | Not attached to anyone |
Marketing email can only go to a contact, because it must carry a working unsubscribe link. Point a marketing email at an address value and you get "This is a marketing email, so it can only be sent to a subscribed contact (marketing emails carry a required unsubscribe link). To send to a direct email address, use a transactional email template instead." Marketing or transactional is fixed when the email is created, so the fix is a new email, not a setting.
A recipient path is separate from the expansion ticks used by the content. The picker initially exposes the available record and stored-field structure; an evaluated relationship is not automatically looked up because its name appears in your email. Review the configured path and its validation when using a related contact as the recipient.
In the MJML and HTML code editors there is a second To control in the block above the code, next to From. It sets the same thing but only one level deep, so if your recipient reaches deeper than one step, that control shows nothing selected. Touching it replaces the deeper setting.
Pull in computed values
Open a record row and you see its fields. Stored writable fields are ticked and locked because they travel with the record. Evaluated fields and computed attributes must be requested through expansion. Ticking one asks for it. An evaluated relationship that returns records opens those records' fields underneath, where you can select further expansions.
This is attribute expansion, and that page covers it properly.
Selected evaluated fields run their configured lookup when the record is expanded. Computed attributes instead read the published calculation selected for that read context; a missing or unavailable value is null, and a stale value can still be the last published value. Nested evaluation adds work, and a many-record evaluated result is bounded at 1,000. Select only what the email uses. See computed attributes for freshness and cost implications.
Ticks stay editable everywhere, including on a broadcast whose list is otherwise frozen, for as long as the email is still editable.
What each place locks
This is where most confusion starts. The same panel is locked differently depending on what is sending the email.
| Broadcast | Template | Workflow send-email step | |
|---|---|---|---|
| The list | Fixed to the audience contact, reach the rest with computed fields | Yours to set | Offered by the step, yours to adopt |
| Add property | Not shown | Shown | Shown |
| To | Locked to the audience contact | Yours to set | Yours to set |
| Computed field ticks | Yours, while it is still a draft | Yours | Yours |
A broadcast decides both for you
A broadcast already knows who it is mailing, so the list is one row for the audience contact, named after that schema (a Learner audience gives you learner), and the recipient is that contact. The checkboxes are dead, there is no Add property, and To is a read-only box. The sentence above the list says the properties come from the sending context.
This is a real limit, not an oversight. A broadcast goes to a whole audience, so the only thing it can hand the email is the contact it is sending to. There is nowhere for a second, unrelated record to come from, which is why the list cannot be added to.
To use anything beyond the contact's own fields, expand the contact row and tick a computed field. An evaluated relationship is how a broadcast reaches another record: give Learner an evaluated cohort, tick it, and write {{ learner.cohort.name }}. It is worked out per recipient at send, so every reader gets their own. See computed values above and the evaluated attributes reference.
If you need a genuinely free data model, with records that have nothing to do with the recipient, that is what a template is for: your own code passes the data in on each send.
If either the list or the recipient drifts from what the broadcast wants, a repair appears above the list, which stays visible while you read it:
- Data out of sync, reading "The data provided to this template has changed since it was set up. Sync the template to match it.", with a Sync data properties button.
- "The recipient no longer matches the one enforced by the sending context.", with a Sync recipient button.
Once a broadcast is scheduled or sending, the whole panel goes read-only: no ticks, no record pickers, no editing the sample.
A template sets its own
A standalone template owns both. Whatever you put on the list becomes what a send has to carry, so adding or removing a row here changes what your own code, or an integration, has to send. Every key on the list is required in the call, though each record only needs enough to identify it.
A new template does not start empty: it seeds one property for your space's default contact schema and points the recipient at it.
A workflow step offers, it does not impose
A send-email step in a workflow shows you what the step actually receives, and leaves the choice to you. Each thing the step carries is a row you can tick to take. Rows you have taken that no longer match what arrives are marked, which is where the drift shows up.
Adding a property here is a trap worth naming. Add property is available, but anything you add that the step does not carry turns red with "This property is expected but not provided.", and if you leave it there the step fails when the workflow runs. Only take rows the step gives you, and if you need something else, add a step before this one that fetches it.
The step also has its own recipient control, Sends to, in the sidebar outside the editor. It sets the same thing as To in the panel, but only offers what the step carries, and only one level deep.
Changing the workflow upstream changes what this step carries, quietly. Rows can go red on their own. Where two branches meet, only what both branches carry survives, so a property that exists on one path and not the other disappears from the step entirely.
Preview it with sample data
The Sample section below the data model holds sample data: a stand-in value for each property so the editor can render a preview. Edit as JSON opens the raw sample and generation controls; Hide JSON returns to the record pickers. The data model remains above it.
Pick a real record with the small picker on each record row and its fields fill in, ticked computed fields included: those are worked out for that record and written into the sample, so the preview shows that sample’s value at the time it was loaded. Actual sending resolves its execution data separately. A computed field you have not ticked is not available for personalization. Tick one after the record was picked and the sample repairs itself.
A test send does not check any of this. It mails whatever the preview rendered, so it tells you nothing about whether the recipient is set correctly.
Read the panel when something is wrong
The readiness chip and Checks tab cover three separate data concerns: the model, the recipient and the sample. A correct-looking list does not establish that the recipient or sample is valid.
| What you see | What it means | What to do |
|---|---|---|
| "Recipient path is not provided." | Nothing is in To | Pick a contact row or an email-address row |
| "Unknown key." on a To step | That step points at something no longer there | Repick from the dropdown |
| "Undefined path item." on a To step | The path carries on past a plain value | Shorten it back |
| "Unknown schema" as a row's type | The schema behind that row was deleted | Remove the row and add a replacement |
| "This property is expected but not provided." | The email wants something the sender does not carry | Untick it, or add it upstream |
| "The expectation of this property is not compatible to its provided form. Update it accordingly." | Same key, different shape | Tick the second row for that key, the one the sender actually carries |
| "The expectation of this property is compatible to its provided form, but not exactly the same. You may update it accordingly." | Close enough to work, worth aligning | Same, when convenient |
| Data out of sync | A broadcast's list drifted | Sync data properties |
| "Sample data does not satisfy the expected data representation with the specified attribute expansions:" | The sample no longer fits the list | Fix or regenerate the sample |
When a shape mismatch appears, the same key shows up twice in a row, once ticked and once not. The lower one is what the sender actually carries. Tick it to take it.
The Checks tab groups these under Recipient, Data and Sample & preview. Their actions open Data. For a sample problem, choose Edit as JSON in its Sample section.
On narrow windows the side tabs collapse to icons. Choose Data to open the panel over the email, then close it to return to the full canvas.
Why a later refresh may not change an active send
A standalone sample can read the latest published computed values. A broadcast revision or root workflow run instead captures the published calculation generations on its first read; child runs inherit that snapshot. Publishing a newer calculation does not replace the values already selected for that execution.
A calculation that was unavailable when that snapshot was captured remains unavailable there. If the captured generation is erased or no longer usable, execution reports an error rather than silently switching to a newer value. Compare the sample and the execution’s data context when investigating different results. See attribute expansion.
Related
- Sample data: the stand-in values the preview renders against.
- Attribute expansion: ticking computed fields, in depth.
- Evaluated attributes and computed attributes: on-demand relationships and background measures.
- Liquid and Adaptyle: using what you declared here in the content.
- Schemas: the records behind every record row.