Formula Fields

Work out a value from the other fields on an item — days until a deadline, a cost per view, a status line that writes itself.

Most fields hold something a person typed. A Formula field holds something Bluprint works out — from the other fields on the same item, every time any of them changes.

That turns information you already have into information you can act on. You know the publish date; a formula turns it into 12 days left. You know the budget and the views; a formula turns them into a cost per view you can sort the whole Channel by.

Create one

  1. Open Manage Fields
    Open the active Channel menu and choose Manage Fields, then pick the kind of item the formula belongs to.
  2. Add a field
    Choose Fields, then New field, and pick Formula from the type list.
  3. Write the expression
    Type your formula in the editor. Refer to another field by name inside curly braces, as in {Word Count} * 2.
  4. Check what it returns
    Bluprint tells you the shape it produces and shows the answer for a real item underneath.
  5. Save it
    Name the field and create it. Every existing item fills in straight away.
The formula editor with a completed expression, its inferred result type, and a live preview.

The editor helps as you type

The editor is built to be written in, not just pasted into.

  • Colours separate the parts at a glance: functions, field references, text, and numbers each look different, and a name Bluprint does not recognise turns red — usually a typo, or a field reference missing its braces.
  • Type { and the field list opens, narrowing as you type. Pick one with the arrow keys and Enter, or click it.
  • Inside a function, a panel appears beside the editor with that function's arguments, what it does, and a worked example. The argument you are currently on is underlined. Put your cursor on a function's name and you get that function's panel, even when it sits inside another one.
  • Matching brackets light up as your cursor moves between them, which is how you find the one you forgot to close.
The formula editor mid-expression with the DATETIME_DIFF signature panel open beside it.

The preview

Underneath the editor, Bluprint runs your formula against a real Idea from the Channel and shows the result. It updates as you type, so you can tell a formula that is valid from a formula that is right.

It picks an Idea that actually produces an answer, rather than the most recent one — a formula tested against an item with half its fields empty tells you nothing. Use Change idea to try it against a specific one.

What you can write

Refer to fields with {Field Name}, combine them with + - * /, join text with &, and compare with = != < <= > >=.

You wantTry
Days until a deadlineDATETIME_DIFF({Publish Date}, TODAY(), "days")
A status line that writes itselfIF({Approved}, "Ready", "In review")
Cost per viewROUND({Budget} / {Views}, 2)
A full title with its stageCONCATENATE({Title}, " — ", {Stage})
Whether something is overdueAND(NOT({Done}), IS_BEFORE({Publish Date}, TODAY()))
How long an item has been openDATETIME_DIFF(TODAY(), CREATED_TIME(), "days")
When a field was last touchedLAST_MODIFIED_TIME({Status})

Coming from Airtable? The function names and syntax are deliberately the same, so most formulas paste across and work.

What kinds of value can a formula produce?

Four: text, a number, a checkbox, or a date. Bluprint works out which from what you wrote and tells you underneath the editor. A number result can be shown as a plain number, currency, a duration, or a percentage — pick that under Show as.

Can a formula read another formula?

Yes. Build a Days Left formula, then read {Days Left} from a second one. Bluprint keeps them in the right order and refuses to save a formula that would end up referring to itself, directly or through a chain.

What happens to items where a field is empty?

An empty field counts as zero in arithmetic and as empty text elsewhere. That is what makes the standard guard work — IF({Views} = 0, 0, {Budget} / {Views}) safely covers an Idea whose views were never filled in. Use ISBLANK() when you need to tell a real zero from an empty one.

Every function

All 65 of them, grouped by what they work on. {Field Name} in an example stands for a field of your own — swap in whatever your Channel calls it.

Logic

FunctionWhat it doesExample
IF(condition, then, else)Returns one value when the condition holds and another when it does not.IF({Done}, "Shipped", "In progress")
SWITCH(value, pattern1, result1, ..., default)Matches a value against a list of patterns and returns the first result that matches.SWITCH({Stage}, "Draft", 1, "Final", 3, 0)
IFERROR(value, fallback)Returns the fallback when the first expression cannot be worked out.IFERROR({Budget} / {Views}, 0)
AND(value1, value2, ...)True when every value is true.AND({Finished}, {Reviewed})
OR(value1, value2, ...)True when any value is true.OR({Finished}, {Approved})
XOR(value1, value2, ...)True when an odd number of the values are true.XOR({Finished}, {Approved})
NOT(value)Flips true to false and false to true.NOT({Done})
TRUE()The value true.IF(TRUE(), "always", "never")
FALSE()The value false.IF(FALSE(), "never", "always")
BLANK()An empty value. Use it to leave a cell blank.IF({Done}, BLANK(), "Still open")
ISBLANK(value)True when the value is empty.ISBLANK({Due Date})

Text

FunctionWhat it doesExample
CONCATENATE(text1, text2, ...)Joins every value into one piece of text.CONCATENATE({Title}, " — ", {Stage})
LEN(text)How many characters the text has.LEN({Title})
LOWER(text)The text in lower case.LOWER({Title})
UPPER(text)The text in upper case.UPPER({Title})
TRIM(text)The text with leading and trailing spaces removed.TRIM({Title})
LEFT(text, count)The first few characters of the text.LEFT({Title}, 20)
RIGHT(text, count)The last few characters of the text.RIGHT({Title}, 4)
MID(text, start, count)A run of characters from the middle of the text. The first character is at 1.MID({Title}, 1, 10)
FIND(needle, haystack, start)Where the needle first appears in the text, counting from 1. Zero when it does not.FIND("draft", {Title})
SEARCH(needle, haystack, start)Like FIND, but ignores case and returns blank when the needle is absent.SEARCH("draft", {Title})
SUBSTITUTE(text, old, new, index)Replaces occurrences of one piece of text with another. Without an index, replaces them all.SUBSTITUTE({Title}, "v1", "v2")
REPLACE(text, start, count, replacement)Replaces a run of characters, by position, with other text.REPLACE({Title}, 1, 5, "Final")
REPT(text, count)Repeats the text a number of times.REPT("*", {Priority Score})
T(value)The value when it is text, and blank when it is not.T({Notes})
ENCODE_URL_COMPONENT(text)Escapes the text so it can be used inside a URL.ENCODE_URL_COMPONENT({Title})

Numbers

FunctionWhat it doesExample
SUM(number1, number2, ...)Adds every number together.SUM({Filming Hours}, {Editing Hours})
AVERAGE(number1, number2, ...)The mean of the numbers. Blank when there are none.AVERAGE({Views}, {Likes})
MIN(value1, value2, ...)The smallest value. Compares dates as dates and numbers as numbers.MIN({Budget}, 1000)
MAX(value1, value2, ...)The largest value. Compares dates as dates and numbers as numbers.MAX({Budget}, 1000)
COUNT(value1, value2, ...)How many of the values are numbers.COUNT({Views}, {Likes})
COUNTA(value1, value2, ...)How many of the values are not empty.COUNTA({Tags})
ROUND(number, places)Rounds to the nearest value with the given number of decimal places.ROUND({Budget} / {Views}, 2)
ROUNDUP(number, places)Rounds away from zero.ROUNDUP({Edit Hours}, 0)
ROUNDDOWN(number, places)Rounds toward zero.ROUNDDOWN({Edit Hours}, 0)
INT(number)The largest whole number that is not greater than the value.INT({Edit Hours})
ABS(number)The value without its sign.ABS({Budget} - {Spend})
SQRT(number)The square root.SQRT({Views})
POWER(base, exponent)The base raised to the exponent.POWER({Views}, 2)
MOD(number, divisor)The remainder after dividing.MOD({Episode Number}, 2)
VALUE(text)Reads a number out of text. Blank when there is none.VALUE({Budget Note})

Dates

FunctionWhat it doesExample
NOW()The current date and time.DATETIME_DIFF(NOW(), {Created}, "hours")
TODAY()Today's date, with no time of day.DATETIME_DIFF({Due Date}, TODAY(), "days")
DATEADD(date, count, 'days')Moves a date forward or back by a number of units.DATEADD({Due Date}, -3, "days")
DATETIME_DIFF(date1, date2, 'days')How many whole units separate two dates. Negative when the first is earlier.DATETIME_DIFF({Publish Date}, {Shoot Date}, "days")
DATETIME_FORMAT(date, 'YYYY-MM-DD')Renders a date as text using a pattern such as YYYY-MM-DD or MMM D, YYYY.DATETIME_FORMAT({Due Date}, "MMM D, YYYY")
DATETIME_PARSE(text)Reads a date out of text. Blank when there is none.DATETIME_PARSE({Due Note})
IS_BEFORE(date1, date2)True when the first date comes before the second.IS_BEFORE({Shoot Date}, {Publish Date})
IS_AFTER(date1, date2)True when the first date comes after the second.IS_AFTER({Publish Date}, TODAY())
IS_SAME(date1, date2, 'days')True when two dates fall in the same unit — the same day, month, or year.IS_SAME({Shoot Date}, {Publish Date}, "days")
YEAR(date)The four-digit year.YEAR({Publish Date})
MONTH(date)The month, from 1 to 12.MONTH({Publish Date})
DAY(date)The day of the month.DAY({Publish Date})
HOUR(date)The hour, from 0 to 23.HOUR({Shoot Date})
MINUTE(date)The minute, from 0 to 59.MINUTE({Shoot Date})
SECOND(date)The second, from 0 to 59.SECOND({Shoot Date})
WEEKDAY(date)The day of the week, with Sunday as 0.WEEKDAY({Publish Date})
WEEKNUM(date)The week of the year.WEEKNUM({Publish Date})
CREATED_TIME()When this record was created.DATETIME_DIFF(TODAY(), CREATED_TIME(), "days")
LAST_MODIFIED_TIME(field1, field2, ...)When the named fields were last changed, whichever is most recent. With no fields, when the record itself last changed.LAST_MODIFIED_TIME({Status}, {Notes})
DATESTR(date)The date as YYYY-MM-DD text.DATESTR({Publish Date})

Lists

FunctionWhat it doesExample
ARRAYJOIN(values, separator)Joins a list of values into text, separated by a string.ARRAYJOIN({Platforms}, " / ")
ARRAYUNIQUE(values)The list with duplicates removed.ARRAYJOIN(ARRAYUNIQUE({Tags}))
ARRAYCOMPACT(values)The list with empty values removed.ARRAYJOIN(ARRAYCOMPACT({Tags}))
ARRAYFLATTEN(values)Flattens nested lists into one list.ARRAYJOIN(ARRAYFLATTEN({Tags}))

Sorting, filtering, and grouping

A formula behaves like whatever it produces. A formula returning a number sorts numerically, one returning a date sorts chronologically, and both work in the Use the Idea Catalog filter builder and the Use the Idea Catalog sort builder like any other field. Group a board by a formula that returns text and you get a board organised by something nobody had to maintain.

There is one exception, and Bluprint will tell you about it when it applies. A formula that reads the current date — anything using TODAY() or NOW() — changes on its own with no edit behind it, so its value cannot be kept ready for sorting. Those formulas display correctly everywhere; they just do not appear in the sort and filter menus.

Common mistakes

Typing a field name without braces

Views + 1 is not a formula — Bluprint reads Views as a function name it does not know and colours it red. It is {Views} + 1. The editor offers the correction in the message it shows.

Expecting a formula to update a field

A formula produces its own value; it never writes into the fields it reads. If you want one field to change another, that is an automation, not a formula.

Renaming a field and expecting formulas to break

They do not. Bluprint stores which field a formula points at, not what it was called, so a rename flows through to every formula reading it. The editor shows the new name the next time you open it.

Asking when a built-in field was last changed

LAST_MODIFIED_TIME() with no fields tells you when the item last changed. Naming a specific field only works for fields your team added — Bluprint's built-in fields share one timestamp between them, so singling one out would report a change that was really somewhere else.

Last updated 2026-09-16