n8n-nodes-calyx-voe
v0.1.0
Published
n8n community node that fills a Written Verification of Employment (WVOE) submission onto the standardized Calyx voe.frm (5/97) PDF and embeds a verifier signature. Pure pdf-lib, no external API. Lender-agnostic — pass your lender details via node paramet
Downloads
31
Maintainers
Readme
n8n-nodes-calyx-voe
A custom n8n community node that fills a Written Verification of Employment (WVOE) submission onto the standardized Calyx voe.frm (5/97) PDF and embeds the verifier signature.
- Pure
pdf-lib— no external API, no SaaS dependency. - Bundles the Calyx VOE template inside the package; nothing to host.
- Lender-agnostic — pass your lender name, address, and signer details via node parameters.
- One node, one operation: drop it in the workflow, pass the normalized submission, get back a filled-and-signed PDF as a binary attachment.
Why this exists
n8n Cloud's Code-node sandbox disallows require('pdf-lib') (and every other
PDF library). Community nodes run at the n8n process level, outside that
sandbox — so wrapping pdf-lib in a community node is the only way to do
in-cloud PDF form filling without standing up an external service.
Install (n8n Cloud)
Community-node install on n8n Cloud requires a plan tier that supports custom nodes — check your Settings → Community Nodes page; if the install button is present, you can proceed.
- Open n8n Cloud → Settings → Community Nodes.
- Click Install a community node.
- Paste the package name:
n8n-nodes-calyx-voe - Tick "I understand the risks" and click Install.
- After install, the node appears in the node search as Fill Calyx VOE PDF.
Install (self-hosted n8n)
cd ~/.n8n # or wherever your n8n install lives
npm install n8n-nodes-calyx-voe
# restart n8nUse
Drop Fill Calyx VOE PDF into a workflow immediately downstream of the node that produces the normalized WVOE submission JSON.
Required node parameters (your lender block)
| Parameter | Stamped into | |---|---| | Lender Name | Box 2 line 1 | | Lender Street Address | Box 2 line 2 | | Lender City, State, Zip | Box 2 line 3 | | Box 3 — Signature of Lender (Text) | Box 3 — the Calyx form expects a graphic signature; this node text-stamps instead. Use a desk name or specific person. | | Box 4 — Title | Box 4 — title of the box-3 signer |
These five parameters travel with the node, so the package itself stays lender-agnostic. Your lender's specific values live only inside your private n8n workflow.
Optional node parameters
| Parameter | Default | Notes |
|---|---|---|
| Signature URL Property | verifier_signature_url | Name of the $json field carrying the verifier signature URL or data: URI. Blank to skip embed. |
| Output Binary Property | data | Name of the binary property the filled PDF is written to. Use data so downstream attachment nodes pick it up. |
| File Name | =voe-{{ ... borrower_name ... }}.pdf | Output PDF filename. Expressions supported. |
Submission fields the node reads from $json
All optional except where the PDF box is required.
| Field | Goes into |
|---|---|
| borrower_name | Box 7 (Applicant Name) |
| badge_number | Box 7 (Badge # subline) |
| employer_name | Box 1 line 1 (To: Employer) |
| employer_address | Box 1 lines 2-4 (newline-separated) |
| request_id | Box 6 (Lender's No.) |
| position_title | Box 10 |
| continued_employment | Box 11 |
| start_date (YYYY-MM-DD) | Box 9 / Box 21 |
| end_date (YYYY-MM-DD) | Box 22 |
| base_pay_rate | Box 12A |
| base_pay_frequency | Box 12A checkbox (Annual / Monthly / Weekly / Hourly / Bi-weekly / Semi-monthly) |
| has_overtime (Yes/No) | Box 14 OT row |
| has_bonus (Yes/No) | Box 14 Bonus row |
| ytd_gross | Box 12B Total row, YTD |
| ytd_pay_period_end_date | Box 12B "Thru" date |
| last_full_year_gross | Box 12B Total row, Past Year |
| year_prior_gross | Box 12B Total row, Prior Year |
| ot_ytd / ot_last_12mo / ot_year_prior | Box 12B OT row |
| bonus_ytd / bonus_last_12mo / bonus_year_prior | Box 12B Bonus row |
| commission_ytd / ..._last_12mo / ..._year_prior | Box 12B Comm row |
| avg_hours_per_week | Box 15 |
| next_pay_increase_date | Box 16 |
| next_pay_increase_amount | Box 17 |
| last_pay_increase_date | Box 18 |
| last_pay_increase_amount | Box 19 |
| remarks | Box 20 |
| employment_status | Triggers Part III when "No longer employed" |
| final_partial_year_earnings | Box 23 (when previous-employer) |
| separation_reason | Box 24 |
| final_position | Box 25 |
| verifier_signature_url | Box 26 (PNG/JPG via URL or data: URI) |
| verifier_title | Box 27 |
| verifier_name | Box 29 |
| verifier_phone | Box 30 |
| verifier_email | Right of Box 30 (small) |
The base-pay total in box 12B is derived by subtracting OT/bonus/commission
from *_gross for each column, so HR's reported gross-earnings figure stays
the authoritative total.
Outputs
$json.calyx_voe_filled: true$json.calyx_voe_filename: 'voe-…pdf'$json.calyx_voe_byte_length: <bytes>$binary[<Output Binary Property>]: the filled PDF, MIMEapplication/pdf
Wire the next node — typically a Microsoft Outlook or Gmail send — to attach
the binary by the property name you chose (default data).
Coordinate tuning
If a field is misaligned on a real signed form, edit the matching top value
in nodes/CalyxVoe/fillVoe.ts (boxes are labeled inline), rebuild, republish.
License
MIT.
