Skip to main content

Use conditional logic in prompt templates

What you'll build: a vip-support-triage prompt whose system message changes shape depending on the caller's input — one paragraph for VIP customers, a loop that lists out an array of open tickets — using the same {% if %} / {% for %} syntax you'd write in Jinja2 or Django templates.

Every prompt message in AcruxCore is a template, not a plain string. {{ variable }} substitutes a value, which covers most prompts. But a template can also carry logic: skip a paragraph when something doesn't apply, or repeat a block once per item in a list. AcruxCore renders templates with nunjucks, a JavaScript templating engine that implements the same tag syntax as Python's Jinja2 — so {% if %}, {% else %}, {% for %}, and filters like {{ x | default('...') }} all work exactly as they do in either engine.

1. Create the prompt​

On Prompts, click New prompt and name it vip-support-triage.

New prompt dialog with the name field filled in as vip-support-triage and a description about adapting to VIP status

2. Write the template with {% if %} and {% for %}​

In the Editor, the system message's placeholder text already hints at this: "Use {{ variables }} and {% logic %}." Write a system message that branches on a is_vip flag and loops over a tickets list:

You are a support triage agent for {{ company }}.
{% if is_vip %}This customer is VIP — prioritize them and skip standard hold times.{% else %}Standard support flow applies.{% endif %}
{% if tickets and tickets.length %}Open tickets:
{% for ticket in tickets %}- #{{ ticket.id }}: {{ ticket.title }}
{% endfor %}{% else %}No open tickets.{% endif %}

The user message is just {{ customer_message }}. Set the Default model to whichever chat model you have configured, then Commit new version.

Prompt editor showing the system message with if/else and for-loop tags syntax-highlighted in a different color from the surrounding text, and a Default model dropdown set to gpt-4o-mini

The editor highlights {{ }} and {% %} the same way — both are template syntax, not plain text, and both get replaced or evaluated at render time.

3. Preview the rendered output​

Switch to Preview. It lists every variable your template reads from the outside — company, customer_message, is_vip, tickets — and leaves out ticket, since that name is bound by the {% for %} loop itself, not something your app provides. Fill in a company, a message, and a truthy is_vip, and the VIP branch renders live:

Preview tab with company, customer_message, is_vip, and tickets variable fields, and rendered output showing the VIP branch: "This customer is VIP — prioritize them and skip standard hold times. No open tickets."

Clear is_vip and the same template falls through to the {% else %} branch instead — no version change needed, just a different input:

Preview tab with is_vip cleared, showing the rendered output fall through to "Standard support flow applies."

The Preview tab only accepts plain text per variable, so it can't exercise the {% for %} loop with a real list — tickets needs an actual array, not a string. Test the loop against the real render endpoint instead, covered next.

Doing this over the API​

Your app renders the same template server-side before sending it to a model — this is what the SDK's render call and the gateway's promptVersionId option both do under the hood. Passing a real array for tickets drives the {% for %} loop correctly:

curl -X POST "$ACRUXCORE_BASE_URL/prompts/vip-support-triage/production/render" \
-H "Authorization: Bearer $ACRUXCORE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"variables": {
"company": "Acme",
"customer_message": "Can you check on my two open issues?",
"is_vip": true,
"tickets": [{"id": 101, "title": "Order delayed"}, {"id": 102, "title": "Refund request"}],
"ticket": null
}
}'
{
"messages": [
{
"role": "system",
"content": "You are a support triage agent for Acme.\nThis customer is VIP — prioritize them and skip standard hold times.\nOpen tickets:\n- #101: Order delayed\n- #102: Refund request\n"
},
{"role": "user", "content": "Can you check on my two open issues?"}
],
"tools": [],
"model": "gpt-4o-mini",
"versionId": "e0397984-a9ff-4665-935d-947b41c1f7ff",
"versionNumber": 1
}

One thing worth knowing: render currently requires a value for every name the template references, including a {% for %} loop's own loop variable (ticket above) — its value is never actually read, so any placeholder like null satisfies it. Leaving it out entirely returns a 400 naming it as missing.

What's next​