Welcome to the new site. If you have any issues accessing models, use store.hemrock.com.
Sign in

Send K-1s

Auto-redact SSNs, encrypt PDFs, and send K-1s securely from Gmail. All processing runs locally.

Overview

SendK1s takes a folder of K-1 PDFs and processes them for secure distribution. Automatically redacts SSNs/TINs, encrypts each PDF with unique passwords, and sends them directly through your Gmail. Everything runs locally, no data uploads to external services.

Built for CFOs and investment managers distributing K-1s to limited partners in SPVs and funds without relying on dedicated SPV management platforms.

More background on the motivation and workflow at Send K-1s

Quick start

npm install  
brew install pdftk-java  
cp .env.example .env  
npm run ui  

Open http://localhost:3000 and follow the web interface to authorize Gmail and process your K-1s.

Typical workflow

  1. Prepare K-1 PDFs: redact (optional) and encrypt
  2. Test matching to verify PDF filenames match your LP CSV before sending
  3. Send K-1s via Gmail or SendGrid

Web interface

The web UI runs on localhost and provides a visual interface for all operations:

  • Prepare, Choose redact only, encrypt only, or both. Select the folder containing your original PDFs.
  • Gmail authorization, Click "Authorize Gmail", sign in with Google, and you're redirected back automatically.
  • Test matching, Verify each LP has exactly one matching PDF before sending.
  • Test send, Send one LP's K-1 to a test address to review before full send.
  • Full send, Send all K-1s via Gmail. Requires confirmation before sending.

The UI runs on localhost only. All processing happens on your machine, PDFs, passwords, and credentials stay on disk.

Scripts

prepare_k1s.js (redact + encrypt)

One-step preparation of K-1 PDFs.

Command Description
npm run prepare-k1s -- <path> Redact, then encrypt (both)
npm run prepare-k1s-redact -- <path> Redact only
npm run prepare-k1s-encrypt -- <path> Encrypt only

redact_k1.js

Redacts the receiving party's SSN/TIN (the second identifier on the page) when unredacted. Covers the number with a white rectangle and prints the redacted form on top (e.g. **-***0337 for TIN, ***-**-7876 for SSN). Run redaction before encryption.

k1script.js (encryption)

Encrypts K-1 PDFs with a password derived from SSN/TIN last 4 digits and ZIP code. Uses PDFtk (default) or qpdf (USE_QPDF=1 in .env).

test_k1s.js

Tests that each LP in your CSV has exactly one matching PDF by filename. Run before sending.

Sending K-1s

LP CSV format

identifier,email  
LP001,john.doe@example.com  
ACME_LLC,contact@acme.com  
"ACME LLC",contact@acme.com;finance@acme.com  
  • identifier must match part of the K-1 PDF filename
  • Use semicolons for multiple emails per LP
  • Wrap values with commas in double quotes

Email template

First line: SUBJECT: Your subject. Remaining lines: body.

Gmail setup

  1. Google Cloud Console: create OAuth credentials (type "Web application"), download as credentials.json
  2. Add redirect URI: http://localhost:3000/auth/gmail/callback
  3. Place credentials.json in the project root (gitignored)
  4. Authorize via the web UI or terminal

SendGrid

Requires SENDGRID_API_KEY in .env. Authenticate your domain in SendGrid to avoid spoof warnings.

Environment variables

Variable Required for Description
FROM_EMAIL Gmail, SendGrid Sender email address
FROM_NAME Gmail, SendGrid Sender display name
TEST_SEND_EMAIL Test send Address to receive test emails
SENDGRID_API_KEY SendGrid SendGrid API key
USE_QPDF Optional Set to 1 to use qpdf instead of PDFtk

npm scripts

Script Description
npm run prepare-k1s -- <path> Redact + encrypt
npm run prepare-k1s-redact -- <path> Redact only
npm run prepare-k1s-encrypt -- <path> Encrypt only
npm run test-match -- <pdf_folder> [lp_csv] Test PDF/LP matching
npm run send-gmail -- ... Send via Gmail
npm run send-gmail-test -- ... Test send via Gmail
npm run send-sendgrid -- ... Send via SendGrid
npm run ui Start web interface

License

Free for single-fund management companies. Commercial license required for multi-client usage. See the full license on GitHub.