Cleaners

What a Cleaner does

A Cleaner is a set of rules that runs over rows of data: the rows a flow has extracted, or a spreadsheet you upload. It standardises formats, converts currencies and units, translates text, computes new columns, looks values up against your own data, flags outliers, collects values from a reviewer, and can trigger actions when a row breaks a rule.

Extraction answers “what does this document say?”. A Cleaner answers “what shape does that have to be in before it can go into our systems?”: one date format, one currency, part numbers matched to your catalogue, a total that adds up.

A flowA Cleaner
Works onA documentThe rows a flow produced, or an uploaded CSV or Excel file
ProducesRaw extracted fieldsNormalised, enriched and validated columns
Typical jobRead the invoiceConvert EUR to USD, reformat the dates, flag the total that does not match
Attached toNothing: it is the starting pointAny number of flows (each flow has at most one Cleaner), or run on its own

One execution of a Cleaner over a batch of rows is called a sweep.

Creating a Cleaner

Click Create Cleaner on the Cleaners page. Tavnit first asks “Where does the data come from?” and offers four starting points.

OptionWhat happens
From a flowPick the flow whose output this Cleaner will receive. Its output fields become the base fields, and the name is suggested from the flow.
From a fileUpload a sample CSV or Excel file. Its header row becomes the base fields.
From a templateDuplicate one of your existing Cleaners, with all its fields and settings, and edit the copy.
Start from scratchOpen the full builder and define everything by hand.

For From a flow and From a file, the next step also offers Suggest cleaning rules with AI. Leave it off and the Cleaner is created with just the base fields. Turn it on and, optionally, describe what you want to clean or compute (for example “Normalize supplier names and format the RUC without dashes”), then click Suggest rules.

How AI rule suggestions work

The AI studies your columns and real sample values (for a flow, rows from its most recent completed run) and drafts rules such as AI formatting, date and number formats, formulas, categories, conditionals and conversions. You can uncheck any suggestion or open it in the same editor the builder uses; a rule marked “Needs attention” needs a fix before it is valid. Everything stays editable after the Cleaner is created.

Start from scratch opens the builder, where you name the Cleaner and work through the same sections the detail page has:

  1. 1Base Fields. Choose a Data Source: Manual to define columns from scratch, From Flow to import a flow's output fields, or From File to parse a CSV or Excel header row. At least one field is needed.
  2. 2Computed fields. Add any of the field types in the reference below. Optional: a Cleaner with only base fields is a valid pass-through.
  3. 3Outputs. An email address and a webhook URL for sweeps the Cleaner runs on its own. Optional.
  4. 4Skip Rows. Drop the first N rows or empty rows of uploads. Optional.

To have every run of a flow swept automatically, link the Cleaner to it: tick Link this cleaner to the flow when you build from a flow, or choose the Cleaner in the flow's Cleaner setting. A flow can have only one Cleaner; one Cleaner can serve several flows, listed under Linked Flows on its detail page. Creating and editing Cleaners requires the Admin or Owner role.

Keep base fields in step with the flow

If a linked flow's fields change, use Sync from Flow (or Resync fields next to the flow under Linked Flows). It shows what is new in the flow, which types changed and what no longer exists, and applies the differences. Removing a column is optional, and computed fields that reference a removed column must be updated by hand.

Field type reference

Every column in a Cleaner has a type that decides what it does. The detail page groups them in its left rail under Input and Computed, with a count for each. This is the complete set, in the order the app lists them.

A Tavnit Cleaner detail page. The left rail lists every field type — Base Fields, AI Formatted, Date Format, Number Format, Calculated, Category, HS Code, Lookup, Bucket Check, Conditional Actions, Conditional, Currency, Translation, Unit Conv. and Summary — with a count beside each, next to the Cleaner's base field list.
Field types are grouped in the Cleaner's left rail, with a count showing how many of each this Cleaner uses.
Field typeWhat it produces
Base FieldsA column from the incoming data, passed through to the output.
AI FormattedAn AI rewrite driven by your instructions: normalising a supplier name, tidying an address, standardising a description. Reads the input columns you pick, or the whole row.
Date FormatA date column re-rendered in one output format, with optional AI conversion for values the input format cannot parse.
Number FormatA numeric column with a fixed number of decimals (0 to 6) and your choice of thousands and decimal separators.
CalculatedA value derived by an arithmetic formula from other columns in the same row.
CategoryAn AI classification into a fixed list of at least two options you define: expense type, department, priority.
HS CodeAn AI tariff classification against the Panama tariff schedule (HS 2022).
Human InputA column a reviewer fills in during human review, as free text or from a menu. See below.
LookupA value pulled from a Bucket by matching this row against it (a catalogue price, a customer code), with a fallback value when nothing matches. Match conditions can compare values exactly or use AI matching.
Bucket CheckA yes/no answer to whether this row already exists in a Bucket. Useful for de-duplication.
Conditional ActionsNot a value: a rule that fires actions when a row matches. See below.
ConditionalAn if/else value: if, else-if and else branches that test the row's contents, each with its own output value.
CurrencyA monetary value converted to a target currency, at a live rate or a fixed rate you set. The source currency can be auto-detected.
TranslationText translated into a target language, optionally keeping formatting and skipping rows already in that language.
Unit Conv.A measurement converted between units: mass, length, volume, temperature, area, speed or data size.
SummaryOne aggregate computed across all rows of the sweep, written on every row.
Anomaly Checktrue/false for values that stand out from the rest of the sweep. Deterministic, no AI.
Date CalculationDays, weeks, months or years between two dates, or a date shifted from today or from a column. Deterministic, no AI.
Replace the column, or add a new one

Most computed fields have an output mode. Replace column overwrites a column in place: you pick the column, and the field takes its name. New column keeps the original and writes the result alongside it under a name you choose. Keep the original when a reviewer will need to see what the document actually said, for example when converting currency.

Any field can be marked Exclude from output: it stays available to computed columns but does not appear in what the Cleaner delivers. That is how you use an intermediate value (a raw amount, a lookup key) without shipping it downstream.

Formatting and conversion options

The formatting and conversion types each have a small set of settings. These are the ones that change the result.

Field typeSettings
Date FormatInput format (dd/mm/yyyy or mm/dd/yyyy) and output format (yyyy-MM-dd, dd/MM/yyyy, MM/dd/yyyy or MMM d, yyyy). Turn on AI conversion and values the input format cannot parse, in any language or notation, are converted by AI into the output format. Add optional special instructions (for example “source date + 40 days”) and every value is processed by AI instead.
Number FormatDecimals, thousands separator (none, comma, period or space) and decimal separator.
AI FormattedThe input columns the AI reads (none selected means the whole row) and instructions describing the transformation.
CategoryThe options, the columns the AI evaluates (none selected means the whole row) and optional instructions.
CurrencySource currency (or auto-detect), target currency, and live rate or fixed rate. In live mode the editor previews the current rate.
TranslationSource and target language, preserve formatting, and only translate if not already in the target language.
Unit Conv.Category, source unit (or auto-detect) and target unit.

Conditional Actions

A Conditional Actions field is a rule: when a row matches these conditions, do these things. It is the only field type that changes what happens to the data rather than what a cell contains, and it is how validation failures become something other than a number in a table.

ActionWhat it does
Skip RowDrops the matching row from the output entirely: the way to filter out subtotals, blank lines and header junk.
Human in the LoopPauses the flow run for human review and assigns the reviewers you name on the action. The matching rows and fields are flagged in the review screen.
Send EmailSends a notification to the recipients you list, with a subject and body you write. One send per rule per sweep, not one per matching row.
Send WebhookPOSTs a notification to a URL you specify. Same one-send-per-rule behaviour.
Edit Bucket RowWrites a value back into the Bucket row a Lookup field matched: marking an order received, decrementing stock, setting a status. The sweep page lists every cell changed under Bucket Changes.

Conditions are grouped, and groups combine with AND or OR, so you can express things like (total > 10,000 OR currency is not USD) AND supplier is not on the approved list. Conditions can read computed columns too, including Summary and Anomaly Check fields. A rule with no conditions at all fires on every row.

Notifications fire even if the run is rejected

Email and webhook actions are dispatched as soon as the rule matches, before any review pause. That is deliberate: alert me when this happens should not depend on whether a reviewer later approves the run. They fire on standalone sweeps too; the Human in the Loop action only applies to flow runs, since a standalone sweep has no review step.

Worked example. On an invoice Cleaner, add a Conditional Actions field with two rules. The first matches rows where the line total does not equal quantity × unit price and sends the run to Human in the Loop. The second matches any invoice over your approval threshold and emails the finance lead. Everything else flows straight through to the Bucket without a human touching it.

Calculated fields and formulas

A Calculated field evaluates an arithmetic expression against the row it is on. Reference other columns by name in braces, and start the formula with an equals sign if you like: both ={Quantity} * {Unit Price} and {Quantity} * {Unit Price} work.

SupportedNotes
+ − * / % **Add, subtract, multiply, divide, remainder, power. Parentheses group as usual.
{Field Name}A reference to another column in the same row, including other Calculated and Summary fields. Spaces in the name are fine.
Numbers written as textCoerced automatically, so “1,234.50” behaves as a number.
Blank cellsCount as zero, so a missing optional column does not break the row.
Format resultOptional decimals and separators for the displayed result. The value stays numeric, so formatted fields still work in other formulas.

Formulas are arithmetic only: there are no functions, no text operations and no conditionals. For if/else logic use a Conditional field; for totals across rows use a Summary field; for date arithmetic use Date Calculation. Dividing by zero leaves that cell blank and records an error on the row, so guard columns that can legitimately be zero.

Summary fields

Summary fields aggregate across every row in the sweep instead of computing per row, and write the result on every row. They answer “what is the total of this document?” without you having to sum the rows downstream.

AggregationResult
SumTotal of a numeric column
AverageMean of a numeric column
Minimum / MaximumSmallest and largest value
MedianMiddle value of a numeric column
Count (non-empty)How many values the column holds
Count distinctHow many distinct values appear
  • Only include rows matching: optional condition groups, so you can sum just the rows of one category or status.
  • Format result: optional decimals and separators, as on Calculated fields. The value stays numeric.
  • Multi-value cells: when a column holds several values per row (a multi-value flow field, such as every deduction line on a payslip), each value counts. Sum adds them all, Count counts each one and Average divides by the number of values.
  • Summary results can be used in formulas and in Conditional Actions conditions.

Human Input fields

A Human Input field is a column nobody extracts: a reviewer types or picks its value on the review screen. Use it for information that is not in the document, such as the warehouse a delivery goes to or an approval code.

  • Input type: Free text, or Menu. A menu takes its options from the distinct values of a Bucket column, optionally filtered by conditions on other Bucket columns or on the current row's values.
  • Value is mandatory: when on, approval is blocked until every row has a value. Turn it off to allow blanks.
  • Reviewers: pick at least one. They are added to the reviewers of the run.
Every flow run goes to review

While a Cleaner has a Human Input field in its output, every flow run through that Cleaner pauses for human review, whatever the data looks like. Standalone sweeps have no review step and deliver the column blank. A Human Input field excluded from the output has no effect.

Anomaly Check

An Anomaly Check flags rows whose value in one column stands out from the rest of the sweep: a quantity far from the others, or a code from a category almost nothing else uses. It returns true when the value stands out and false otherwise. It is deterministic and uses no AI.

SettingWhat it does
Column to checkAny earlier column, including computed ones such as HS Code or Calculated.
DetectionAuto (numeric columns get outlier detection, everything else rare-value detection), Numeric outliers, or Rare values.
Numeric outliersCompares each value to the sweep's median using a robust spread, so one outlier cannot hide itself. Tune the sensitivity cutoff (higher means fewer flags) and the direction: both sides, only unusually low or only unusually high.
Rare valuesFlags values whose group falls below a share of rows you set. Compare only the first N characters to group codes, for example 2 for HS chapters or 4 for headings.
Compare withinOptionally judge each value only against rows that share another column's value.
Minimum rowsSweeps with fewer values than this flag nothing.

An Anomaly Check only produces a flag. To act on it, add a Conditional Actions rule such as this field equals true → Human in the Loop. The review screen then shows why each value was flagged.

Date Calculation

A Date Calculation does date arithmetic on every row, deterministically and without AI. It has two modes.

CalculationReturns
Difference between two datesA whole number of units from Start to End (End − Start), negative when End is earlier. Start and End are each a column or Today, but not both Today. Use it for days until an expiry date, or an age.
Shift a dateA date (YYYY-MM-DD) moved forward or back by a whole amount of days, weeks, months or years from a column or from Today. A negative amount moves it earlier.
  • Units for a difference: Days, Weeks (whole weeks), Months (complete, like an age), Calendar months (month boundaries crossed, ignoring the day) and Years (complete).
  • Today is your organization's date when the data is processed.
  • A blank date gives a blank cell. Pair the result with a Conditional field (for example days_to_expiry >= 30 → yes, else → no) to flag rows.

HS Code classification

The HS Code field assigns a customs tariff code to each row from its product description. It works down the Panama tariff schedule (HS 2022): section, then chapter, then heading, then national tariff line, rather than pattern-matching a description against a code list.

  • Benchmark Fields: the columns the classifier reads, usually the product description, sometimes with material or use alongside it. Leave it unset and the whole row is used.
  • Instructions for AI: the cases your catalogue gets wrong, such as how to treat kits, spare parts, or goods that could sit in two chapters.
  • Section preselect (recommended): starts the cascade at the 22 HS sections before chapters.
  • Output Format: the code only (for example 0101.29.00.00.00) or the code plus its description.
  • Rows are classified independently, so one hard row does not affect the others.
It is a classification, not a ruling

Tariff classification is a judgement call that customs authorities make. Treat the output as a strong first pass to be checked, not as a filing-ready declaration. It is a good candidate for an Anomaly Check on the first characters of the code, or for human review before delivery.

Shaping and delivering the output

After the computed columns, a Cleaner can drop junk rows, choose and order the columns it ships, reshape long data into wide, and send the result to an email address or a webhook.

SettingWhat it does
Skip RowsDon't skip any rows, skip the first N rows, or skip empty rows of manual uploads before cleaning: for spreadsheets with title rows above the header.
Output FieldsChooses which fields appear in the cleaned output, and in what order: drag them to set the column order. That order is the column order everywhere the output goes. At least one field must stay included.
PivotDelivers rows in wide format: one column per distinct value of a label column (sizes, for example), filled from a value column. See below.
Email OutputEmails the cleaned result to this address after each sweep the Cleaner runs on its own.
WebhookPOSTs the cleaned result to this URL after each sweep the Cleaner runs on its own. HTTPS only. See webhooks.
Which sweeps use the Cleaner's own outputs

The Cleaner's Email Output and Webhook deliver the sweeps it runs on its own: Clean Dataset uploads and API sweeps. A flow run's sweep delivers through that flow's own email output and webhook instead, so nothing receives the same document twice.

Pivot is the delivery format, not just a view. Choose the Column to explode, the column the Values from, how to Group rows by (all other columns automatically, or columns you choose), and what to do when a label repeats within a group: sum the values, keep the first value, or keep the first value and flag a warning. Optional Summary columns (Sum, Average, Minimum, Maximum or Count) are computed per row across the exploded columns and appear at the far right. Under Apply to, choose the webhook payload, the email output and downloads; when downloads are on, the sweep page opens on the pivoted view.

Pivot does not reach Buckets

Stored rows stay in long format, and Bucket exports always receive the un-pivoted rows, so the stored table keeps one row per record.

Sweeps

A sweep is one execution of a Cleaner over a batch of rows.

How a sweep startsWhen to use it
Linked to a flowEvery run of that flow is swept as soon as extraction completes. This is the normal setup.
Clean DatasetUpload a CSV, XLSX or XLS file with the Clean button on the Cleaner (or Clean Dataset on the Cleaners page): a supplier price list, a legacy export.
APISend a file or JSON rows to the Cleaner from your own systems. See below.

The sweep page

Open any sweep from the Cleaner's Sweep History to see exactly what it did. The page updates live while the sweep is processing.

  • Status (Processing, Completed, Failed or Cancelled) with the Rows and Source of the sweep.
  • Warnings: per-row problems such as a formula that divided by zero or a value that could not be read as a number. Problems stay attached to the row that caused them, so one bad row does not fail the sweep.
  • Sweep Information: the Cleaner, when the sweep was created, and the source run and flow when it came from a flow.
  • The data table, with a Cleaned / Pivoted / Raw toggle to compare the output with what came in, and Expand for a full-screen view. You can select and copy cells.
  • CSV and JSON export of the current view. With a pivot applied to downloads, the export has the pivoted shape.
  • Outputs: a log of each delivery (email, webhook, notifications) and whether it succeeded.
  • Bucket Changes: every Bucket cell the sweep's Edit Bucket Row actions changed.

Running a Cleaner from the API

A Cleaner can run on its own from your systems, with no flow involved. Copy its ID from the Cleaner ID panel and authenticate with your API key.

EndpointWhat it does
POST /api/sweeps/runMultipart upload of a CSV or XLSX file with cleaner_id and file (optional sheet_name).
POST /api/cleaners/<cleaner_id>/processThe same, and also accepts rows as JSON ({"rows": [...]}) instead of a file.

Both return HTTP 202 with a sweep_id. When the sweep completes, the Cleaner's own Email Output and Webhook deliver the cleaned rows. See the API page for authentication and the response shape.

Where a Cleaner sits in the pipeline

Cleaning happens after extraction and before delivery. That order matters: everything downstream (the review screen, the webhook payload, the Bucket rows, an agent's input variables) sees the cleaned output, not the raw extraction.

  1. 1The flow extracts rows from the document.
  2. 2The linked Cleaner sweeps those rows: formats, conversions, lookups, computed columns.
  3. 3Conditional Actions fire: rows are dropped, notifications go out, review may be requested. A Human Input field always requests review.
  4. 4If review was triggered, the run pauses and a reviewer sees the cleaned table.
  5. 5On completion, results are delivered through the flow's outputs: email, webhook, Bucket, form fill, or a chained agent.

The Pipeline Map shows this for your own workspace, including which flows share a Cleaner.

Troubleshooting

ProblemWhat to check
A column is empty in the outputOpen the sweep's Warnings. A Lookup with no match returns its fallback value (or nothing); a formula that divided by zero leaves the cell blank.
A column is missing from the outputIt may be excluded under Output Fields, or it is a Conditional Actions rule, which never produces a column.
The Cleaner's webhook did not fire on a flow runExpected: flow runs deliver through the flow's own outputs. The Cleaner's Email Output and Webhook cover Clean Dataset and API sweeps.
Every run of a flow goes to reviewThe Cleaner has a Human Input field in its output, or a Conditional Actions rule with no conditions sends everything to Human in the Loop.
A computed field reads a column the flow no longer producesUse Sync from Flow, then update the computed fields that referenced the removed column.
The Bucket rows are not pivotedExpected: Bucket exports always receive un-pivoted rows.