When to use Data Transformers
- Format external data (e.g. strip symbols from phone numbers or rewrite salutations) before you reference it inside prompts.
- Enforce guard rails by comparing values or routing between true/false outputs.
- Share the same transformation across multiple agents, pre-call actions, or flow nodes and keep everything in sync.
Open the workspace view
1
In the left navigation choose Build → Data Transformers.
2
Select the workspace you want to manage (you must use a non-system workspace ID).
3
Use the search bar to filter by name or description, or page through the list if you have many definitions.
Create or edit a transformer
- Click Create Data Transformer (or use the menu beside an existing item and choose Edit).
- Provide a Name and optional Description so team-members understand what the transformer does.
- Under Inputs, enter a test Value for
input1. Use Add Input if the transformer needs more than one incoming value (input2,input3, and so on). - Build the Expression Pipeline:
- Each block (e.g.
expr1,expr2) represents one transformation step. - Choose the Transformation type and set the block’s Input:
{{input1}}(or any{{input#}}) runs against that input’s value.- Any
{{expr#}}lets you chain from a previous block’s output.
- Fill out the parameters that appear for the selected type (see the table below).
- Add more blocks with Add Expression or remove a block with the ✕ icon (except the first one).
- Each block (e.g.
- Click Run to try the full chain against your test values. The Output box shows the result of the last block so you can verify the logic.
- Click Create (or Update when editing). Your transformer is instantly available anywhere variables are inserted.
Supported expression types
You can mix and match types inside the same pipeline. Every block outputs plain text, so downstream steps (and the agent) can read the result immediately.
Empty inputs are handled gracefully. If an input value is empty — or an expression references an input that was never supplied — the reference resolves to an empty string and the pipeline keeps running, instead of failing the transformation. This means transformers attached to optional variables (for example, a CRM field that is sometimes blank) no longer need guard expressions just to survive missing data. Pad String is the one exception: an empty input comes out as a full-length run of the pad character rather than as an empty string.
Behaviour worth knowing
- Extract Number (min–max) matches on the whole run of digits. With a maximum of 3, a four-digit run such as
2019is skipped entirely rather than clipped to201— so a date in the text will not be mistaken for a 3-digit code. - String Length counts characters the way software does, not the way the eye does: an emoji counts as 2.
- Pad String counts length in whole characters, while String Length counts the way software does — an emoji is one position to Pad String and
2to String Length. Chaining String Length into a Pad StringtargetLengthwill therefore not line up on emoji or other astral characters. - Pad String accepts an emoji or an accented letter as a pad character, but rejects one built from several code points — a combining accent, or a multi-person emoji such as 👨👩👧 — rather than padding by visual clusters.
- Extract Email covers everyday addresses. It does not match accented or non-Latin local parts, quoted local parts, or intranet addresses without a dot (
user@localhost). - Regex Extract and Find & Replace cap the work a pattern can do — input up to 100,000 characters, patterns up to 1,000 characters, and up to 10,000 matches — and return a clear error rather than stalling if a pattern exceeds them.
- Modulo (%) truncates both values to whole numbers first, and the sign of the result follows the first value:
-7modulo3is-1, not2;7modulo-3is1; and10.9modulo3.9is1. - The two Extract Letter transformers match on the whole run of letters, exactly as Extract Number (min–max) does — a run that is too long is skipped rather than clipped. Only ASCII letters count, so digits, spaces and punctuation end a run, and accented or non-Latin letters are not letters at all.
- Round Number sends an exact half away from zero (
-2.5rounds to-3), while Floor (down) and Ceil (up) go toward negative and positive infinity (-2.1floors to-3). A blank or non-numeric input counts as0rather than failing the chain. - Unlike Random Number, which never fails a chain, the Extract Letter transformers, Arithmetic and Pad String do fail the expression at run time if a referenced parameter resolves to an invalid number, a range whose bounds are the wrong way round, a zero divisor, or — for Pad String — a pad character that is blank or longer than one character. An empty result from an Extract Letter transformer is not a failure — it simply means no run matched.
- Datetime, Date and Date Offset return a millisecond timestamp, not a date to read out to a caller. When one of them is the last block and you click Run, the Output box shows the result as a readable UTC date —
2026-01-08T00:00:00Z, or2026-01-08for Date — but a later block, and your agents, flows and actions, always receive the number. Use these results for comparisons. - Date Offset month and year steps stop at the end of a shorter month: 31 January plus one month and 31 March minus one month both give 28 February (29 in a leap year).
- Date Offset in
Days,Weeks,MonthsorYearskeeps the local clock time across a daylight-saving change in the selected Timezone, whileHourscounts elapsed time. From 09:00 on the day before the clocks go forward, one day later is 09:00, but 24 hours later is 10:00. An input that carries its own offset, such as+11:00, stays on that fixed offset instead, with no daylight-saving adjustment. - An offset in the input, such as
+11:00orZ, takes precedence over Timezone in Datetime and Date Offset only when the Format reads it — with aZ,ZZorZZZtoken, withISO, or, for a trailingZonly, with a quoted'Z'. Otherwise, input that carries an offset doesn’t match the format and the block fails. - With a date-only Format, Date Offset and Datetime read the date as midnight in the selected Timezone, whereas Date always uses midnight UTC. Keep Timezone on
UTCwhen you compare a Date Offset result with a Date result, or the two will be hours apart. - A literal Value in Date Offset that isn’t a whole number of
0or more is rejected when you save or run. A referenced Value that resolves to blank, a decimal, a negative number or text counts as0, so the date passes through unchanged rather than failing the block. - To offset a value that is already a timestamp — the output of an earlier Datetime block, for example — set Format on the Date Offset block to
x(milliseconds) orX(seconds). - For all three date transformers, input that doesn’t match the Format fails the block with an error saying so, and a blank input returns a blank result. A later Compare treats a blank result as text rather than a number, so a missing date can still come out
true— if the date can be blank, check for that first. Useyyyyfor the year:YYYYis rejected. - The Co-pilot can add date steps, but only in a fixed set of formats:
yyyy-MM-ddordd/MM/yyyyfor Date;yyyy-MM-dd HH:mm:ss,yyyy-MM-dd'T'HH:mm:ssoryyyy-MM-dd'T'HH:mm:ssZfor Datetime; and any of those five for Date Offset. ForISO, a timestamp or any other format, edit the block’s Format yourself.
Tips for complex pipelines
- Use descriptive descriptions so future editors understand why a pipeline exists.
- When chaining expressions, double-check each block’s Input field;
expr2defaults to the previous block, but you can point it at any earlier result. - Clicking Run often helps you catch whitespace or case-sensitivity issues before anyone attaches the transformer to production prompts.
Apply a transformer to variables
Wherever the variable popover appears (Guidelines, Initial Message, flows, etc.), you can apply a transformer in-line:- Type
{{to open the variable popper and select a variable as usual. - Enable Apply data transformation at the bottom of the popper.
- Pick the transformer by name — the popper auto-completes transformer names and shows a preview of the expression chain so you can verify the pipeline before inserting. The inserted snippet renders as
[TransformerName({{variableName}})], and the stored value includes the transformer ID so the backend can execute the pipeline automatically.
Manage safely
- Usage-aware deletion – clicking Delete runs a usage check first. If the transformer is referenced by any agent, action, or flow node you will see a detailed report and deletion is blocked until you remove those references. See Deleting a transformer.
- Workspace-wide search – the list view fetches every transformer in the workspace so you can filter locally without pagination round trips.
- Exports & clones – AI Agent exports/imports and duplicates automatically carry along any referenced transformers and rebuild usage links in the target workspace.
Deleting a transformer
Deletion is refused by the platform itself, not only by the Studio screen. A transformer referenced by any agent — from a Set Variable step, a Decision step, or a pre-conversation or post-conversation action — cannot be deleted, and the refusal reads “This data transformer is in use by one or more agents and cannot be deleted.” with the full usage breakdown. In Studio a refused delete shows “Failed to delete data transformer” and the transformer stays in your list. Previously the only protection was the usage check in Studio, so a direct API call — or a Studio delete that raced someone wiring the transformer into a flow at the same moment — deleted it anyway and left those agents pointing at something that no longer existed. If usage cannot be verified at all, the delete is refused rather than allowed through.Related pages
AI Agents
Inject transformed values into greetings, guidelines, and agent settings.
Pre-Call Actions
Combine transformers with API responses before a call starts.