Visibility rules let you conditionally show or hide rows in your email based on context values supplied at render time. This allows a single template to serve multiple audiences — for example, showing a "Pro features" row only when plan = pro.

How it works

  1. In the builder, select a row and open its settings.

  2. Add a Visibility Rule using the condition editor.

  3. At render time, pass a context object containing key–value pairs.

  4. The Render API evaluates each rule and includes or excludes rows accordingly.

Context values are not injected into email content — they only drive show/hide logic. For dynamic text content, use merge tags.

Creating a rule in the editor

  1. Click a row to select it.

  2. In the Settings panel, expand Visibility.

  3. Click + Add Rule.

  4. Choose:

    • Field — the context key to evaluate (e.g. plan)

    • Operator — see Supported operators below

    • Value — the comparison value (e.g. pro)

Visibility rule editor showing a plan equals pro condition
Figure 1. Visibility rule editor showing a plan equals pro condition

Multiple rules on a single row use AND logic — all conditions must be satisfied for the row to appear.

Visibility rule detected in visibility tab
Figure 2. Active visibility rules listed in the Visibility tab
Visibility rule for free users
Figure 3. Visibility rule configured for free-tier users
Visibility rule for pro users
Figure 4. Visibility rule configured for pro-tier users

Supported operators

Operator Behaviour Example

==

Strict equality

plan == pro

!=

Strict inequality

country != us

contains

Value contains the specified substring

email contains gmail

not_contains

Value does not contain the specified substring

email not_contains yahoo

starts_with

Value starts with the specified substring

email starts_with admin

ends_with

Value ends with the specified substring

email ends_with .com

in

Value is one of a comma-separated list

plan in pro,enterprise

not_in

Value is not one of the listed values

country not_in us,ca

>

Numeric greater than

age > 17

>=

Numeric greater than or equal

account_days >= 30

<

Numeric less than

days_remaining < 7

Numeric less than or equal

usage_pct ⇐ 100

is_empty

Value is missing, null, or an empty string

promo_code is_empty

is_not_empty

Value exists and is not empty

promo_code is_not_empty

date_before

Date occurs before the specified date

signup_date date_before 2026-01-01

date_after

Date occurs after the specified date

signup_date date_after 2026-01-01

date_on

Date matches the specified date

signup_date date_on 2026-01-01

contains, starts_with, and ends_with operate on string values. >, >=, <, and operate on numeric values. Date operators expect ISO-8601 date values (for example, 2026-01-01).

Passing context at render time

  • JavaScript

  • Python

  • REST API

await client.renderHtml("template-id", {
  context: {
    plan:         "pro",
    country:      "usa",
    age:          25,
    country_rank: "2",
    expiry:       "2028",
  },
})
client.render_html("template-id", {
    "context": {
        "plan":         "pro",
        "country":      "usa",
        "age":          25,
        "country_rank": "2",
        "expiry":       "2028",
    },
})
{
  "template_id": "550e8400-e29b-41d4-a716-446655440000",
  "target": "html",
  "dynamic_data": {
    "context": {
      "plan": "pro",
      "country": "usa",
      "age": 25
    }
  }
}

Default behaviour (no context supplied)

If you call renderHtml("template-id") without a context:

  • All rows without a visibility rule are shown.

  • Rows with a visibility rule are hidden by default unless the rule evaluates to true. Since no context is provided, the rule cannot be satisfied, so the row is hidden.

Design your templates so the "no context" render is safe to show — for example, keep promotional upsell rows behind rules so they’re only shown when relevant context is present.

Combining visibility rules and merge tags

You can use both in the same template:

await client.render({
  templateId: "template-id",
  target: "html",
  dynamicData: {
    merge_tags: {
      text: { name: "Noruwa", promo_label: "Save 30%" },
      url:  { promo_url: "https://app.example.com/upgrade" },
    },
    context: {
      plan:    "free",
      country: "usa",
    },
  },
})

Here the name merge tag fills in visible content, while plan and country drive which rows are shown.