What n8n gives you that hosted tools do not
n8n is a workflow automation tool you can run yourself. That single property changes the calculation for document processing, because invoices and bank statements are exactly the kind of files people are reluctant to route through a third-party cloud. With self-hosted n8n the documents travel from your storage to our API and nowhere else — there is no intermediate platform holding a copy.
The honest starting point: there is no FlowParse node in the n8n library yet. You call our REST API with the built-in HTTP Request node, which is how most APIs are used in n8n and is fully supported. The base64 step, which is the fiddly part everywhere, is handled by the Extract From File node with the *Move File to Base64 String* operation.
What you get is the same extraction as the document extraction API: automatic classification, typed fields, line items or transactions, plus a free validation score you can branch on. The difference is where the workflow runs and what it costs to run it often.
What you need
The prerequisites are mostly on your side rather than ours, which is the trade-off of self-hosting: no platform tier to buy, but something to run and keep updated.
| Requirement | Notes |
|---|---|
| An n8n instance | Self-hosted (Docker is the usual route) or n8n Cloud |
| HTTP Request node | Built in — no plan tier, no premium app |
| Extract From File node | Built in — converts binary to a base64 string |
| FlowParse API key | Get an API key — use a dedicated one per workflow |
| A page balance | Any paid plan or a top-up — see pricing |
The shape of the workflow
Four nodes is the minimum useful workflow, five with a quality gate. The trigger is the only part that differs between one built on email and one built on a watched folder.
1. Trigger
Email (IMAP), a watched folder, a webhook from your own app, or a schedule.
2. Extract From File
Move File to Base64 String — turns the binary into the text our API expects.
3. HTTP Request
POST to /api/v1/extract with the bearer key and a JSON body.
4. Validate + IF
Free call to /api/v1/validate, then an IF node splitting clean from questionable.
5. Deliver
Write to Postgres, Sheets, a file, or produce an accounting export.
Getting the file into the request
Our API takes the document as a base64 string in the `file` field, and n8n handles binary data as a separate channel from JSON — so you cannot simply reference the binary in a JSON body. The Extract From File node bridges that: set the operation to *Move File to Base64 String*, point it at your binary property (usually `data`), and name the destination property, for example `fileB64`.
The node then puts the encoded string into the item's JSON, where the HTTP Request node can reference it as an expression. If you prefer, a Code node does the same thing with direct access to the binary buffer, which is occasionally useful when you need to compress or re-orient an image first — but for the ordinary case Extract From File is one node and no code.
Configuring the HTTP Request node
Set the node to POST with JSON body and add the Authorization header. The body references the property that Extract From File produced. Everything else is default.
| Setting | Value |
|---|---|
| Method | POST |
| URL | https://flowparse.io/api/v1/extract |
| Authentication | None (set the header manually) or a Header Auth credential |
| Header | Authorization: Bearer pf_live_xxx |
| Send Body | On — JSON |
| Specify Body | Using JSON |
| JSON body | {"file": "{{ $json.fileB64 }}", "filename": "{{ $json.fileName }}"} |
{
"file": "{{ $json.fileB64 }}",
"filename": "{{ $json.fileName }}"
}Storing the key properly
Do not paste the key into the header field of the node, tempting as it is. n8n has a Header Auth credential type: create one with the name `Authorization` and the value `Bearer pf_live_xxx`, then select it in the node's Authentication setting. The key is then stored encrypted in n8n's credential store rather than sitting in plain text inside a workflow that gets exported, shared or committed to git.
This matters more in n8n than in hosted platforms precisely because self-hosted workflows are often version-controlled. A key in a workflow JSON is a key in your repository. Use a dedicated key per workflow so revoking one never breaks another — keys are managed at get an API key.
What comes back
The HTTP Request node parses JSON automatically, so every field is immediately available to downstream nodes as `$json`. The envelope is always `{ type, pages, billedPages, data }`, and `type` reports what the document was classified as — so one workflow handles a mixed intake without you routing by filename.
{
"type": "bank_statement",
"pages": 8,
"billedPages": 8,
"data": {
"type": "bank_statement",
"data": {
"bank_name": "Northern Trust Bank",
"account_holder": "Digits Ltd",
"currency": "EUR",
"opening_balance": 12400.55,
"closing_balance": 18320.10,
"transactions": [ /* … */ ]
}
}
}An IF node that keeps bad data out
Add a second HTTP Request node calling `/api/v1/validate` with the extracted data. It costs nothing, returns a 0–100 score and a grade, and for bank statements checks the extracted transactions against the statement's own opening and closing balance — the one check that can prove an extraction incomplete without a human comparing anything.
Follow it with an IF node: true branch writes to your destination, false branch creates a task, posts to Slack or files the document for review. In an unattended workflow this is not optional polish; it is the difference between automation you can trust and a fast route for wrong numbers into your ledger. The rules are on the validation engine.
Processing hundreds of documents
This is where self-hosting pays for itself. Hosted platforms meter every step, so a thousand documents through a five-step workflow is five thousand billable operations. On your own n8n instance the same run costs you compute you are already paying for — only the pages billed by our API move.
Use the Loop Over Items node to process documents in controlled batches rather than firing everything at once. Two habits matter: cap the batch size so a large backlog cannot drain your page budget in minutes, and make the workflow idempotent on a file hash so a retry does not create a second record. When you want one consolidated workbook instead of a record per document, `/api/v1/merge` combines up to 100 extracted documents into a single Excel file — the API side of Smart Merge.
Error branches that do not lose work
Set the HTTP Request node's *On Error* behaviour to Continue (using error output) so failures take a second branch instead of halting the run. Then handle each status deliberately — losing a month of processing to one bad scan is the failure mode worth engineering against.
| Status | Meaning | Branch behaviour |
|---|---|---|
| 400 | Malformed body or base64 | Stop and alert — this is a build error |
| 401 | Key wrong or missing | Stop and alert — check the Header Auth credential |
| 422 | Unreadable document (not billed) | Route to review; request a better scan |
| 429 | Page budget exhausted | Pause the workflow; resume after topping up |
| 503 | Temporary | Retry with backoff — n8n's retry settings handle this |
Receiving documents from your own systems
n8n's Webhook node gives your workflow a URL that anything on your network can POST to, which is the cleanest way to connect an internal application to document extraction without embedding our API in that application's codebase. Your app posts the file, the workflow extracts and validates, and the result goes back to your database — or to your app through a Respond to Webhook node.
Worth being precise about direction here, because it is a common misunderstanding: that webhook is yours, not ours. Our API is a plain synchronous request and response — you POST a document and the structured data comes back in that same response. FlowParse does not call you back later. The webhook automation guide covers this architecture properly, including what to do when a caller should not be kept waiting.
What self-hosting actually costs you
The advantages are real: documents never touch a third-party automation platform, there is no per-task meter, and you can reach internal systems a cloud tool cannot see — a file share, an on-premise ERP, a database behind your firewall. For a finance team with a compliance posture, that is often the deciding argument rather than a nice-to-have.
The costs are equally real and worth stating. You run it: a container to keep alive, updates to apply, backups of the workflows and credential store, and someone who notices when it stops. n8n Cloud removes that at the price of the data-locality argument. If nobody on the team wants to own a service, Make is the more honest choice — an automation nobody maintains is worse than one you pay for.
Example — statements to a database and a workbook
A workflow that earns its keep in a practice: an IMAP trigger watches a shared mailbox, Extract From File encodes each attachment, HTTP Request extracts, a validate call and IF node split clean from questionable, and the clean branch writes transactions to Postgres while also calling `/api/v1/export` to produce an `.xlsx` saved to a client folder.
The questionable branch does not throw anything away — it writes the document and the failing check to a review table, so the exceptions are a queue somebody works through rather than files that quietly vanish. That single design decision is what makes an unattended pipeline defensible when an auditor asks how a number reached the books.
Producing ledger files instead of rows
When the destination is an accounting system rather than a database, call `/api/v1/export` with a format such as `qbo`, `qfx`, `ofx`, `xero`, `datev` or `1c`. The response carries the finished file base64-encoded, which a Convert to File node turns back into a binary you can save or email.
This removes the retyping step, which is where errors actually enter the books. It does not sign into your accounting software — see PDF to QBO and bank statement to Xero for what the files contain and how they import.
What you actually pay for
On self-hosted n8n the workflow itself is free to run beyond the server you already have, so the only meter that moves is ours: pages extracted and files exported, with validation, reconciliation and export previews free. That makes n8n markedly cheaper than hosted platforms at volume, and the gap widens with every extra step in the workflow.
| Step | n8n cost (self-hosted) | FlowParse cost |
|---|---|---|
| Trigger and file handling | Your own compute | — |
| HTTP → /api/v1/extract | Your own compute | Per page |
| HTTP → /api/v1/validate | Your own compute | Free |
| HTTP → /api/v1/export | Your own compute | Per page (preview free) |
| Database write / file save | Your own compute | — |
What teams build on it
Regulated finance teams
Documents stay inside the network; only the extraction call leaves, over HTTPS.
High-volume practices
Thousands of statements a month without per-task platform fees.
Internal tooling
A webhook endpoint your own applications post documents to.
Legacy integration
Reach on-premise file shares and ERPs a cloud automation platform cannot see.
Proving it before it runs unattended
Execute the workflow manually with a real document, not a fixture, and inspect each node's output — particularly that Extract From File produced a plausible base64 string rather than an empty property, which is the most common first-attempt failure.
Then test what happens when things go wrong: feed an unreadable scan and confirm the 422 takes the error branch instead of stopping the run; feed a statement whose balances do not reconcile and confirm the IF node routes it to review. Validation is free, so the only cost is your own compute. Pin the workflow to a dedicated key while testing so the usage is easy to see in the dashboard.
Running it well
Store the key as a Header Auth credential rather than inline, so exported workflows and git history stay clean. Always validate and always branch on the result. Persist the raw extraction JSON next to whatever you derive from it, so a questioned figure can be traced to what the document said rather than reconstructed.
Operationally: cap batch sizes, make jobs idempotent on a file hash, set the HTTP node to continue on error rather than halt, and keep documents and extracted JSON out of your logs — on a self-hosted box the logs are usually the least protected thing you have. Watch the 422 rate as an early signal that input quality has changed upstream.
Where to go from here
The endpoint reference is in the API docs. For per-document detail see the invoice parsing API, the receipt OCR API and the bank statement API; for spreadsheets see the PDF to Excel API. To compare platforms, see Zapier and Make, or browse all integrations.
Run it on your own infrastructure
Self-hosted document extraction — your documents, your network, only the extraction call leaves.
