Validate
Branch on completeness (valid / missing)
The Validate node checks that a submission is actually complete before any expensive step runs, and splits the job two ways: everything's here, or something's missing. When something's short, it names exactly what — so the next step can ask for it.
How it works
People send in incomplete paperwork all the time: an application with no tax ID, two months of statements instead of three, a form missing a signature page. Validate catches that the moment the data comes off the page, before the AI step reads it, so you never pay to analyze a file you already know is short.
You describe what 'complete' means as a short list of checks. Each one looks at the extracted data a different way: that a specific value is present and well-formed (a tax ID, an amount over a floor), that there are enough items of a kind (at least three bank statements), that they cover enough distinct months (three different months, not three copies of one), or that they're recent enough (from the last few months). Every check has to pass for the job to be treated as complete.
When a check fails, Validate collects the plain-language name of each missing item and hands it to the next step as a ready-to-use list. Wire the 'missing' path into a Wait-for-reply → email pair and the applicant gets asked for exactly what's short, by name. It uses no AI and costs nothing to run, so it's a cheap, exact gate to put in front of the paid work.
Common use cases
Real situations where this node earns its place in a flow.
Require three months of statements
Check that an applicant actually sent three distinct months of bank statements — not two, and not three copies of one — before the underwriting pass runs.
Insist on a tax ID up front
Hold back any application missing a well-formed EIN so incomplete files never reach the paid analysis step.
Verify a document set is whole
Confirm the required pieces are all present — enough pages, recent enough, the right count — and route anything short to a follow-up instead of a reviewer's inbox.
Validate in a workflow
A simple example of where this node sits in a flow.
What you set up
- Put it after Extract (so there's structured data to check) and before Analyze.
- List your checks: a required field, a minimum count, distinct months of coverage, or a recency window — each with a plain name for what it's asking for.
- Wire the two paths: 'valid' continues to Analyze; 'missing' goes to a Wait-for-reply → email so the customer can send what's short.
Common questions
How is this different from the File router?
File router judges the files themselves — size, page count, name, type — before anything is read. Validate judges the data inside them after Extract, so it can check things like 'the tax ID is present' or 'three different statement months', which a filename can't tell you.
What happens if a value is unreadable rather than missing?
Each check decides. Date-based checks (distinct months, recency) skip an unreadable value by default rather than treat it as missing, so an OCR miss doesn't ask a customer for statements they already sent. A required-field check can be set to treat unreadable as missing.
Does it cost anything?
No. It runs on your rules, not AI, so it's free and instant — which is the point of putting it in front of the paid Analyze step.
Settings you configure on this node, stored under data.config in the workflow JSON. Leave a field unset to use its default.
checksreqCompleteness checks { checks: [{ kind, label, onMissing?, ... }] } evaluated against the extracted data; ALL must pass to route out-valid, any failure routes out-invalid. kind: field (path, op, value — Router operators), count (collection files|documents, minCount, optional where {field,op,value}), distinct (path, minCount, bucket 'month'|'raw'), recency (path, withinMonths, minCount). onMissing 'fail'|'skip' controls unreadable/absent values (skip is the default for distinct/recency). The failed labels become {data.missing}.
Type: JSON string
How this node appears inside a workflow's nodes[] array (the shape you see in the Developer export / import). A full workflow is { nodes: [...], edges: [...] }.
{
"id": "validate",
"type": "card",
"position": {
"x": 160,
"y": 120
},
"data": {
"type": "validate",
"kind": "processor",
"title": "Validate",
"subtitle": "Branch on completeness (valid / missing)",
"config": {
"checks": "[]"
}
}
}