Template Variables
Use {{field_name}} references in intake bot schemas to personalize questions and content at runtime.
Template variables let intake bot authors reference previous answers anywhere in the schema using a {{field_name}} placeholder. They are resolved at runtime for each respondent — the schema you read via the API always contains the raw {{field_name}} syntax.
Syntax
{{field_name}}Where field_name is the name property of any question field that appears earlier in the schema.
Examples
{ "label": "Great {{full_name}}, which plan suits you best?" }
{ "helper_text": "Since you chose {{service_type}}, we need a few more details." }
{ "body": "Thanks {{full_name}}! Based on your interest in {{service_type}}..." }Where Template Variables Appear
| Location | Field | Supported |
|---|---|---|
| Question label | label | Yes |
| Helper text | helper_text | Yes |
| Placeholder text | placeholder | Yes |
| Content block body | body | Yes |
| CTA URL | ctas[].url | Yes |
| AI goal / instruction | ai_intelligence.goal | Yes |
| AI content block prompt | ai_generation.prompt | Yes |
Scoping Rules
- A variable can only reference fields that appear before it in the schema (no forward references).
- Private fields are excluded from template resolution in AI contexts. They can appear in visible content, but are never sent to AI models.
- If the referenced field has not been answered yet, the placeholder resolves to an empty string.
Reading Schemas via the API
When you retrieve a schema via GET /intake-bots/:id, template variables are returned as-is in the JSON — they are not pre-resolved:
{
"label": "Great {{full_name}}, which plan suits you best?",
"helper_text": "Since you chose {{service_type}}, we need a few more details."
}Resolution only happens at runtime inside the intake bot session for each respondent. If you are building an integration that reads a schema to understand the bot's structure, treat {{field_name}} as a documentation hint about personalization intent.
Resolving Variables Yourself
If you are building a custom frontend or preview tool and want to resolve template variables against a known set of answers:
function resolveTemplate(text, answers) {
return text.replace(/\{\{(\w+)\}\}/g, (_, key) => answers[key] ?? '');
}
const label = resolveTemplate(
'Great {{full_name}}, which plan suits you best?',
{ full_name: 'Jane Doe', service_type: 'Enterprise' }
);
// → "Great Jane Doe, which plan suits you best?"CTA URLs with Template Variables
When a content block CTA has action: "modal" or action: "link" and the url contains template variables, values are URL-encoded before being substituted:
https://cal.com/book?name={{full_name}}&email={{email}}
→ https://cal.com/book?name=Jane%20Doe&email=jane%40example.comNote: Private field values are never included in CTA URLs, regardless of the template reference.