Skip to content
Expedify
6 min

Document Parser

Turns a file into text a workflow can use. The two things to know are which eleven formats it accepts, and that rescuing a scanned PDF quietly costs you model tokens.

Documents arrive constantly — a signed contract, a purchase order, a supplier's price list, a CV attached to an application. Every one of them is content your workflow cannot see, because a file is not text until something reads it.

This node reads it. Point it at a file, get back the words, and everything downstream — a model, a knowledge base, a CRM field — can work with them.

Where the file comes from

Seven of sixteen. The OCR settings are the other significant group and get their own section.

content_source

What it holds
Source of document content: input (from previous node), base64, url, file_id (from file_uploads table), or azure_blob (direct blob path) One of: input · base64 · url · file_id · azure_blob Defaults to input.

file_url

What it holds
URL to download file from (supports {{variables}})

file_id

What it holds
File ID(s) from template variable - can be single ID or array like {{trigger.file_ids}} (takes priority over selected_file_ids)

selected_file_ids

What it holds
File IDs selected from dropdown (used as fallback if file_id template is empty)

max_chars

What it holds
Maximum characters to extract Defaults to 100000.

max_pages

What it holds
Maximum pages to process (for PDFs) Defaults to 50.

include_metadata

What it holds
Include file metadata in output Defaults to true.

content_source picks the route: a file uploaded through the product, one referenced by id, a public URL, raw base64, or a path in storage. file_id is the common one — it is how a chat attachment or an uploaded document is addressed.

Eleven formats, and images are not among them. Plain text, markdown, CSV, JSON, PDF, and the Office pairs — Word, Excel, PowerPoint, old and new. A photograph of a document is rejected before anything is attempted. That surprises people, because the node has OCR — but OCR here is for PDFs whose pages are images, not for image files.

A worked example

Somebody attaches a file to a chat message. The parser reads it, and the workflow checks that there was anything to read before it does anything else.

Parse, then check you got something

The condition on char_count is the whole safety story.

YesNo

Scroll for all 5 steps →

The trigger exposes file_ids for whatever was attached, and the parser takes the list. Everything after that hangs on one number.

Branch on char_count, not on whether the node succeeded. A PDF that is one big scanned image, a password-protected file, a document that is genuinely blank — all of these parse without error and produce almost nothing. Two hundred characters is a reasonable floor for “this is a real document”; below it, say so rather than passing an empty string to a model that will invent a summary of it.

OCR, and what it costs

Some PDFs contain text. Others contain pictures of text — anything scanned, faxed, or exported from a photo. The first kind reads instantly and for nothing. The second needs optical character recognition, and this node will do it for you.

auto

What happens
The default. Extract normally, and if the average characters per page comes out below the threshold, run OCR on it. Handles the mixed case without you deciding in advance.

always

What happens
OCR every page regardless. For a pipeline where you know everything is scanned.

never

What happens
Never OCR. A scanned document returns near-nothing, and your condition catches it.

OCR is a call to a vision model, and it is billed to your organisation. It is not a local library — pages are rendered as images and sent to a model, and the usage is tracked against your account like any other model call. So a workflow that quietly handles the occasional scan is fine, and the same workflow pointed at a folder of five hundred scanned invoices is a bill you did not plan. ocr_model and ocr_dpi are the two levers: the cheaper model and 200 dpi are the defaults for a reason.

ocr_min_chars_per_page is what decides whether auto fires. Fifty characters a page is a low bar — a page with a header and a page number clears it. If documents that clearly need OCR are not getting it, raise the threshold rather than switching to always.

What comes back

{{alias.text}}

What you get
The extracted text. What everything downstream actually wants.

{{alias.char_count}} · {{alias.word_count}} · {{alias.page_count}}

What you get
The size of what you got. The first is the one to branch on.

{{alias.ocr_used}} · {{alias.ocr_pages_processed}}

What you get
Whether OCR ran and how many pages went through it. Log these — they are your only visibility into what the node spent.

What breaks

An unreadable file is a successful run with no text. This is the same failure that has appeared throughout the course, and here it is especially easy to hit, because the reasons are mundane: the PDF is a scan and OCR is off, the file is protected, the format is one of the many not in the list. The node returns, the run is green, and the next node receives an empty string.

In a batch, unsupported files are skipped rather than failing. Hand it five files where two are images and you get three files' worth of text and a successful run. Compare the number of files you sent with what came back if the count matters.

Both limits truncate silently. max_chars and max_pages stop the read at a hundred thousand characters and fifty pages by default. A sixty-page contract is read as far as page fifty, and nothing says the last ten pages exist. If you are parsing long documents, raise them deliberately and check {{alias.page_count}} against what you expected.

Parsed text is not structured data. A table in a PDF comes out as words in reading order, and a two-column layout can interleave. If you need fields rather than prose, the parser gets you the text and a model gets you the fields — this node does not do the second part.

Try it

  1. Parse an ordinary text-based PDF and read {{alias.char_count}} and {{alias.ocr_used}}. OCR should be false and the count high.
  2. Now parse a scan of the same document with ocr_fallback on never. The count collapses and nothing errors.
  3. Switch to auto and run it again. Watch ocr_used turn true and note how much longer it takes — that is the model call.
  4. Try a .png and read the error. It names the eleven formats, which is the fastest way to remember them.
  5. Set max_pages to 2 on a long document and compare {{alias.page_count}} with the real page count. That is the truncation nobody tells you about.

Next: API Request — the node for everything the other twenty could not do, and the last one in this path.

Related lessons