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
- Prepare K-1 PDFs: redact (optional) and encrypt
- Test matching to verify PDF filenames match your LP CSV before sending
- 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
- Google Cloud Console: create OAuth credentials (type "Web application"), download as
credentials.json - Add redirect URI:
http://localhost:3000/auth/gmail/callback - Place
credentials.jsonin the project root (gitignored) - 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.