How they fit together — start with contact structured data, survey variables, URL parameters or API calls, then use repeats and visibility rules to turn that context into a dynamic survey.
About the examples — they explain how the feature works. In normal use, Dayalogs or your AI assistant prepares this structure for you and you review the result rather than writing every field by hand.
Structured audience data
Use structured data already stored on the contact record to drive the survey.
API calls
Load structured data from your own systems before the survey starts, without exposing credentials in the browser.
Flow controls
Use visibility rules and repeats to decide what appears and how many times it appears.
Live survey data does not have to come from an API — repeats and conditions can also use structured data already stored on the contact record, such as products, children, locations, or purchases attached to a personalized link.
Data sources
Data in Dayalogs can already be present on the personalized contact, can arrive through the survey URL, can be stored in survey variables, or can be fetched from an external API. The flow tools later in this guide can use these sources together.
Structured audience data
Personalized links in Dayalogs can carry more than simple fields like name or email. A contact record can also contain structured data, including grouped values and lists, and the survey can read that data directly.
This is useful when the survey already knows something about the respondent before the first page: a list of recent purchases, household members, stores, classes, employees, children, or products that should drive the flow.
- Use scalar contact values for interpolation and simple conditions.
- Use contact arrays when a repeat needs one iteration per item.
- Use grouped values when several pieces of information belong together, such as one product’s name, category and price.
For example, a contact could include a last_products list, and the survey could ask one follow-up per product without calling any external API. In practice, this means many surveys can run entirely from the data already attached to the personalized link.
Survey variables and URL parameters
Survey variables are named, non-visible values inside the survey definition. They are useful when you want to normalize one value once and then reuse it in interpolation, conditions, endings, or exports.
URL parameters arrive through the survey link and are available through @urlparams. That makes them useful for campaign identifiers, partner codes, panel respondent ids, channel tags, or any other external context passed in the URL.
- Use
@urlparamswhen the value comes from the incoming survey link. - Use survey variables when you want one internal name the rest of the survey can reuse.
- Use a variable when several blocks, conditions or endings should refer to the same normalized value.
A common pattern is to read @urlparams.gid or @contact.department once, map it into a survey variable, and then reuse that variable across the survey instead of repeating the original path everywhere.
API calls
An API call lets the survey fetch structured data from one of your systems before the respondent sees the first question. The call runs server-side, so you can use secrets or auth headers without exposing them in the public page.
That returned data can then be reused in question text, visibility rules, or repeats.
API calls are only one source of live data. If the same information is already present on the contact used by a personalized link, the survey can read it directly without making a call.
JSON markup
{
"id": "responsable",
"alias": "v_responsable",
"type": "json",
"source": {
"type": "api",
"method": "GET",
"url": "https://example.test/api/household",
"headers": { "X-SURVEY-SECRET": "example-api-secret" },
"query": { "id": "{{ @contact.id }}" },
"response_path": "response"
}
}
- API secrets live in the survey definition, usually as an auth token or custom header. The call still runs server-side, so the secret is not exposed in the public survey page.
- Treat survey files and version history as sensitive when they contain API credentials.
- Use
response_pathwhen the useful data is inside a deeper level of the API response. - For non-critical calls, consider a fallback instead of making the survey hard-fail.
Flow controls
Once that data exists, Dayalogs uses two main tools to turn it into respondent-specific behavior: visibility rules and repeats.
Conditional questions
visible_if is the main tool for conditional flow in Dayalogs. It uses positive logic: if you omit it, the item is shown; if you add it, the item is shown only when the expression is true.
Use it when part of the survey is only relevant to some respondents: a follow-up after a low score, a whole section for one audience segment, or a branch driven by URL, contact, or API data.
- Put it on a question when you only want to gate one field.
- Put it on a block when you want to gate a whole subtree of questions or nested blocks.
- Use
presentationon the block to control whether its direct questions share a screen; presentation never owns flow logic.
JSON markup
{
"id": "p24_reason",
"type": "text",
"title": "What went wrong?",
"visible_if": { "question": "p24_recommend", "op": "eq", "value": 1 }
}
You can also combine conditions with all, any, and not, or check live values instead of answers with var.
Available comparison operators
The same comparison options are available for answers and live values. What matters is the kind of value you are comparing.
answered, not_answeredvalue.eq, not_eqin, not_incontains, not_containsmulti, rank, or JSON arrays where you want to test membership of one item.lt, lte, gt, gtebetween, not_between[min, max] as the value.starts_with, not_starts_withends_with, not_ends_withmatches, not_matchesPractical rules: use contains for multi-select style arrays, in when your answer is scalar but the allowed set is plural, and the text operators only when the target is genuinely text. Negative range and text operators still require the referenced value to be present.
Repeats
A repeat loops a question or a block once per item in a list. Instead of hard-coding three versions of the same section, you declare the logic once and let Dayalogs run it once per child, product, selected option, or scale row.
Each iteration exposes a current_item object, so the repeated part can refer to the item currently in focus.
- Use a repeated block for a group of questions.
- Use a repeated question when only one field needs to loop.
- Keep a repeated group inside one repeated block so its questions share the same iteration context.
JSON markup
{
"type": "block",
"id": "children_loop",
"title": "Questions for {{ current_item.name }}",
"repeat": {
"source": { "type": "variable_path", "path": "family.children" },
"as": "child"
},
"items": [
{ "type": "question", "question": "p10_child_score" }
]
}
The most common repeat sources are a list stored in a variable, a question count, selected or unselected options from an earlier answer, or the matching rows of a scale question.
That list can come either from an API call or from structured contact data already attached to the respondent. For example, if a personalized contact record includes a last_products list with each product’s name, category, and price, the survey can repeat once per item and ask whether the price of {{ current_item.price }} for {{ current_item.name }} felt right.
For question_scale repeats, the filtering happens in the repeat source itself. If you use a source like { "type": "question_scale", "question": "p4_teachers", "op": "gt", "value": 3 }, Dayalogs only creates repeat iterations for rows whose score is above 3. Inside each matched iteration, the selected score is available as current_item.value.
If you then add a visible_if using current_item.value inside that repeated flow, it acts as an extra condition on the already-filtered iteration; it does not broaden the repeat back out to all scale rows.
How they work together
The strongest pattern is to combine all four ideas. Start with structured respondent data from a contact record or an API call, repeat over the list you loaded, and then use visible_if inside that repeated flow to reveal only the relevant follow-ups.
A typical example would be: fetch a customer file, show the products attached to that customer, and ask a few targeted questions about their most recent purchases.
Gotchas
- Conditions should reference earlier context. Avoid forward references in the flow.
- Repeat paths must resolve to arrays. An object is not enough.
- Live values are part of the survey setup. If an API response changes shape, your text, conditions, or repeats may need updating.
- Keep the condition names consistent. Use the standard operator names like
eqrather than inventing alternatives.
Quick reference
visible_if on the question itself.visible_if on the block.@urlparams, optionally normalized into a survey variable.visible_if.