Function Reference

Last updated 23 May 2026

The Flexie Scripting function catalogue, grouped by purpose, with examples

Functions are called by name with parentheses: {{ functionName(arg1, arg2) }}. Arguments shown with = value are optional and have that default.

Lookups findOne, findMany findSum, query Maths round, max, min numberFormat Dates now, date, dateAdd daysBetween Text truncate, htmlToText extractEmails Tags addTag, removeTag matchAnyTag JSON jsonDecode jsonPath IDs uuid, uniqueId incrementAndGet… Links + QR qrCode, signUrl publicAttachmentLink Security encrypt, hashHmac jwtEncode/Decode Utility coalesce, contains memoryGet, dump {{ findSum("invoice", "total_incl_tax", "contact_id", 42, "status", "finalized") }}

1. Looking up records

These functions read data from across your Flexie account, so a template can show related information, a contact's invoices, an account's contacts, totals, counts.

Function What it does Example
findOne(type, field, value, …) Fetch a single record matching all the field/value pairs you give (joined with AND). Returns an empty result if none found. {{ findOne("lead", "email", "john@example.com") }}
findMany(type, field, value, orderBy='id', dir='ASC', limit=1000) Fetch many records matching one field, optionally sorted and capped. {{ findMany("invoice", "status", "finalized", "date_added", "DESC", 50) }}
findCount(type, field, value, …) Count records matching all field/value pairs. {{ findCount("deal", "stage_id", 5, "owner_id", 3) }}
findSum(type, column, field, value, …) Add up a numeric column across matching records. {{ findSum("invoice", "total_incl_tax", "contact_id", 42, "status", "finalized") }}
findMin(type, column, field, value, …) Smallest value of a column across matching records. {{ findMin("deal", "amount", "stage_id", 5) }}
findMax(type, column, field, value, …) Largest value of a column across matching records. {{ findMax("deal", "amount", "is_won", 1) }}
findByPhoneNumber(type, phoneField, number) Find a record by a phone number held in a specific field. {{ findByPhoneNumber("contact", "phone", "+155501234") }}
getSmartListRecords(type, listAlias) All records belonging to a saved smart list. {{ getSmartListRecords("lead", "high_value") }}
getOrganization(idOrVat) Look up an organisation by its id or VAT number. {{ getOrganization("DE123456789") }}
getUserById(userId) Fetch a user (name, email, phone, profile image, etc.). {{ getUserById(5).full_name }}
getAccountContacts(accountId) All contacts linked to an account. {{ getAccountContacts(42) }}
findDeals(type, entityId) All deals linked to a contact, account, or lead. {{ findDeals("contact", 42) }}
findCases(type, entityId) All cases linked to a record. {{ findCases("account", 10) }}
findDealsValue(type, stage='*', pipeline='*', entityId) Total deal value for a record, optionally filtered by stage (pending/won/lost/*) and pipeline. {{ findDealsValue("contact", "won", "*", 42) }}

Result limits. Look-ups that can return many rows are capped at 1,000 results to keep templates fast. Filter tightly and sort, rather than pulling everything.

Ready-made statistics

These return a small bundle of figures in one call, handy for customer summaries.

Function Returns
getDealStats(type, entityId) total, active, won, lost
getInvoiceStats(type, entityId) invoice_total, credit_memo_total, draft, sent, canceled, won, finalized, pending, active
getCaseStats(type, entityId) total, open, pending, solved, closed

In an account-context template, the account's own id is read at the top level:

This account has {{ getDealStats("account", id).won }} won deals
worth {{ findDealsValue("account", "won", "*", id) | number_format(2) }}.

Advanced: direct queries

For administrators and power users who need data the helpers above do not cover:

Function What it does
query(sql) Run a read-only data query and get the rows back. Only retrieval is allowed (SELECT and WITH only, no INSERT, UPDATE, DELETE, DROP, and no SELECT *). Results are capped at 1,000 rows. Returns the rows, or {"error": "…"} if the query is rejected.
{% set rows = query("SELECT id, email FROM leads WHERE status = 1 LIMIT 10") %}
Matching leads: {{ rows | length }}

2. Numbers and maths

Function What it does Example → result
add(a, b, …) Add all arguments. {{ add(10, 5, 3) }}18
subtract(a, b) a minus b. {{ subtract(100, 30) }}70
multiply(a, b, …) Multiply all arguments. {{ multiply(5, 4, 2) }}40
divide(a, b) a divided by b (empty if dividing by zero). {{ divide(100, 4) }}25
round(n, places=0, mode="ROUND_HALF_UP") Round to a number of decimal places. {{ round(3.14159, 2) }}3.14
squareRoot(n) Square root. {{ squareRoot(16) }}4
cubeRoot(n) Cube root. {{ cubeRoot(27) }}3
max(a, b, …) Largest of the given values (also works on a list). {{ max(1, 3, 2) }}3
min(a, b, …) Smallest of the given values (also works on a list). {{ min(1, 3, 2) }}1
random(…) A random value: random() (a number), random(5) (0 to 5), random(["a","b"]) (a random item), random("ABC") (a random character). {{ random(["a","b","c"]) }}
range(from, to, step=1) A sequence of numbers, handy in a loop. {% for i in range(1, 5) %}…{% endfor %}
numberFormat(n, decimals=0, style="none", round="ROUND_HALF_EVEN") Format with grouping. style is ",|." (1,234.56), ".|," (1.234,56), or none. {{ numberFormat(1234.5678, 2, ",|.") }}1,234.57
reverseFormattedNumber(text, style=",|.") Turn a formatted string back into a number you can calculate with. {{ reverseFormattedNumber("1.234,56", ".|,") }}1234.56
formatCurrency(amount, symbol="$", decimals=2, style=",|.", position="before") Format a money amount with a currency symbol. {{ formatCurrency(1234.5, "€", 2, ".|,", "after") }}1.234,50€

Why reverseFormattedNumber matters. Once a number has thousands separators it is text, not a number, "1,200" + 50 will not behave. Reverse it first, do the maths, then format the result.

For totals across a list of records (sumField, avgField, minField, maxField) see Filters & collections.

3. Dates and time

Function What it does Example
now(format="Y-m-d H:i:s", tz="UTC") The current date and time. {{ now("Y-m-d") }}
date(value, format="Y-m-d H:i:s", toTz="UTC", fromTz="UTC") Reformat a date and optionally convert its timezone. {{ date(date_added, "M j, Y") }}
dateAdd(date, amount, unit="days", format="Y-m-d H:i:s") Add time to a date. Units: years, months, weeks, days, hours, minutes, seconds. {{ dateAdd(due_date, 30, "days") }}
dateSubtract(date, amount, unit="days", format=…) Subtract time from a date. {{ dateSubtract(now(), 1, "months") }}
dateDiff(date1, date2, unit="days") Signed difference between two dates. {{ dateDiff(date_added, now()) }}
daysBetween(date1, date2) Whole days between two dates (always positive). {{ daysBetween(due_date, now()) }}

Format codes are the common date pieces: Y 4-digit year, m month number, d day, H hour (24h), i minutes, s seconds, M short month name, j day without leading zero, l weekday name. Example: "l, j M Y"Tuesday, 3 Jun 2025.

{# Current record = the invoice #}
{% if daysBetween(due_date, now()) > 0 and status != "paid" %}
  This invoice is {{ daysBetween(due_date, now()) }} days overdue.
{% endif %}

4. Working with text

Function What it does Example → result
truncate(text, length=100, suffix="…") Shorten text, adding a suffix. {{ truncate(subject, 30) }}
padString(value, length, char=" ", side="left") Pad to a fixed width. {{ padString(42, 6, "0") }}000042
startsWith(text, prefix) True if text begins with the prefix. {{ startsWith(phone, "+44") }}
endsWith(text, suffix) True if text ends with the suffix. {{ endsWith(file, ".pdf") }}
wordCount(text) Number of words. {{ wordCount(note.body) }}
toAlphanumeric(text) Strip everything except letters and numbers. {{ toAlphanumeric("AB-12/3") }}AB123
htmlToText(html) Convert HTML into clean plain text (great for turning an email body into SMS). {{ htmlToText(email.html) }}
findAndReplace(html, start, end, replacement) Replace whatever sits between two markers. {{ findAndReplace(body, "<!--A-->", "<!--B-->", newPart) }}
urlEncode(text) Make text safe to drop into a URL. {{ urlEncode(email) }}
md5(text) An MD5 fingerprint of the text. {{ md5(email) }}
base64encode(text) / base64decode(text) Encode or decode text in base64. {{ base64encode(payload) }}

For pattern-based find-and-replace and slug-making, see the regex_replace and slugify filters in Filters & collections.

Pulling things out of text

Function What it does
verifyEmail(text) 1 if it looks like a valid email address, else 0.
extractEmails(text) All email addresses found in a block of text.
extractPhoneNumbers(text) All phone numbers found in text.
extractWebsiteLinks(text) All web links found in text.
{% set found = extractEmails(email.text) %}
{% if found | length > 0 %}Reply-to candidate: {{ found[0] }}{% endif %}

5. Tags

Flexie stores tags as a single pipe-separated string (vip|renewal). These helpers make working with them safe.

Function What it does Example → result
addTag(tags, newTag) Append a tag. {{ addTag("red|blue", "green") }}red|blue|green
removeTag(tags, tag) Remove a tag (case-insensitive). {{ removeTag("red|blue", "BLUE") }}red
matchAnyTag(tagsA, tagsB) 1 if the two sets share at least one tag. {{ matchAnyTag(tags, "vip|gold") }}
matchAllTags(tagsA, tagsB) 1 if the two sets are identical. {{ matchAllTags(tags, "vip|gold") }}

6. JSON and structured data

When a value holds JSON (for example data received from another system), these turn it into something you can read.

Function What it does
jsonDecode(text, associative=true) Turn a JSON string into data you can read with dots or brackets.
jsonPath(data, expression) Pull a nested value out using a path like $.order.items[0].sku.
isCollection(value) True if the value is a list or array.
{% set order = jsonDecode(__data.webhook_body) %}
First item: {{ jsonPath(order, "$.items[0].name") }}

There is also a json_decode and json_path filter form, see Filters & collections.

7. Unique values and sequence numbers

Function What it does
uuid() A random globally-unique identifier.
uniqueId() A shorter unique id.
incrementAndGetSequenceNumber(type, field, matchField, matchValue) Safely bump a counter column by one and return the new value, the reliable way to generate gap-free invoice or order numbers, even under load.
Invoice no. {{ incrementAndGetSequenceNumber("invoice", "sequence_no", "year", "2026") }}
Function What it does
getAttachments(type, id, name="*", firstOnly=false) Attachment details for a record (optionally filtered by filename).
getAttachmentsPath(type, id, name="*", firstOnly=true) Direct download URLs for attachments.
addAttachments(type, id, name="*", …) Ready-made HTML links to attachments.
getFormAttachments(payload) Attachments from a form submission.
publicAttachmentLink(type, id, userId=null) A secure public link to an attachment that needs no login.
qrCode(text, border=0, width=140, height=140, bg="#FFFFFF", fg="#333333") A QR code image (SVG) for any text or URL.
Scan to pay: {{ qrCode("https://pay.example.com/invoice/" ~ id, 2, 200, 200) }}

9. Security helpers (advanced)

For building authenticated links and signed payloads when integrating with other systems. These are administrator-level tools.

Function What it does
encrypt(text) / decrypt(text) Encrypt or decrypt with your account's secret key.
signUrl(url, expiryHours) Produce a tamper-proof, time-limited link.
hashHmac(algorithm, data, secret) An HMAC signature (e.g. sha256) for verifying payloads.
jwtEncode(payload, key, alg="HS256") / jwtDecode(token, secret) Build or read a JSON Web Token.

10. Utility

Function What it does
coalesce(a, b, c, …) The first value that is not empty, a clean way to provide fallbacks.
contains(haystack, needle) True if text contains a substring, or a list contains a value.
getQueryString(name) Read a value from the current URL's query string.
memoryGet(key) Read a value from short-lived shared memory (set elsewhere by a workflow's "Memory Set" action). Read-only here.
getAiChatHistory(key="") Retrieve stored AI conversation history.
dump(value) Print a value's full contents, for debugging a template only.
Hello {{ coalesce(first_name, "there") }}!

Some specialised functions also exist for fiscal or regulatory document signing and for streaming external data files. These are configured by administrators for specific integrations and are outside everyday use.

Next steps

  • Filters & collections: transforming values with | filters and working across lists of records.
  • Recipes: these functions combined into real solutions.