calyx-voe

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

Package Information

Released: 4 mo ago
Downloads: 0 weekly / 0 monthly
Latest Version: 0.1.0
Author: n8n-nodes-calyx-voe contributors

Documentation

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.

  1. Open n8n Cloud → Settings → Community Nodes.
  2. Click Install a community node.
  3. Paste the package name: n8n-nodes-calyx-voe
  4. Tick "I understand the risks" and click Install.
  5. 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 n8n

Use

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, MIME application/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.

Discussion