Two ways to write expressions
JSON Operators
Structured objects where the key defines the operation. Operators start with a colon (:), accept arguments, and return a value.
:cmp evaluates first (is 72 ≥ 50?), returns true, and :if uses that result to pick the :then branch.
Inline Expressions
Variable references and simple logic embedded inside strings. Lightweight, readable, and ideal for labels, notifications, and short conditions.Composing operators
The real power of penscript comes from composing operators — nesting them to express complex logic in a single, declarative structure. Consider this: you want to display a formatted message that changes based on the number of documents a contact has uploaded.:count counts the documents, :cmp compares the count, and :if picks the right message. Each operator does one thing, and composition builds the behavior.
Or, using :case for cleaner multi-branch logic:
What you can express
Conditions and Branching
penscript handles everything from simple toggles to complex multi-condition logic. Show or hide a form element based on a previous answer::if evaluates all of them — if they all pass, the :then branch is returned.
→ Full reference: Logic & comparisons
Calculations and number formatting
Arithmetic, formatting, and number-driven logic. Calculate an insurance premium based on vehicle power:Working with collections
Iterate, transform, filter, and query arrays of data. Generate form fields dynamically based on a count the user entered:{@index} and {@position} variables track where you are in the loop. The :with operator creates a local pos variable (1-based) for display labels.
Filter a list to find only completed items:
Dates, time, and age
Create dates, format them, compare them, and do arithmetic. Check whether a contract has expired:Internationalization
Serve content in the right language automatically.:i18n operator reads the active locale from the scope and returns the matching translation. Variables inside translations are resolved normally.
→ Full reference: Internationalization
Dynamic evaluation
Define local variables, build reusable expression templates, and pipe values through transformation chains. Define intermediate values for a complex calculation::in expression has access to all of them.
Pipe a value through multiple steps:
:raw operator captures the expression without evaluating it. :eval evaluates it later, in a scope where the variables have values.
→ Full reference: Dynamic evaluation & scope
Real-world composition
These capabilities are designed to be combined. A single penscript configuration might use conditions to control which form elements appear, calculations to compute a premium, loops to generate dynamic fields, date arithmetic to set deadlines, and internationalization to serve it all in the contact’s language. Here’s a realistic fragment from a case automation — automatically moving a case to “Ready for Review” when all required documents are uploaded and the contact is an adult:Where penscript runs
penscript expressions appear throughout the platform:- Form templates — element visibility, validation, default values, computed fields, conditional steps
- Case templates — data schema defaults, status transition conditions, step visibility rules
- Automations — trigger conditions, status transitions, post-automation payloads
- Notifications — dynamic content in emails and SMS (subject lines, body text, conditional sections)
- Document generation — variable injection into Word and PDF templates
- API payloads — outbound data sent by post-automations to external systems