n8n-nodes-sendletter
v1.2.0
Published
Send real, printed letters by post from n8n. Print, frank and deliver across Europe, including registered mail with proof of posting.
Maintainers
Readme
n8n-nodes-sendletter
Send a real letter — printed, folded, franked and handed to the post — from an n8n workflow. Across Europe, including registered mail with proof of posting.
This is a community node for n8n.
Installation
In n8n: Settings → Community Nodes → Install, then enter
n8n-nodes-sendletter.
Self-hosted, from the command line:
npm install n8n-nodes-sendletterCredentials
Create an API key in the account area and add it as a SendLetter API credential.
A key beginning sk_test_ runs the whole lifecycle — printed, posted, delivered
— with the trigger firing exactly as it will in production, while printing
nothing, posting nothing and charging nothing. Build the workflow with one of
those.
Nodes
SendLetter
| Resource | Operations | | --- | --- | | Letter | Prepare, Send, Get, Get Many, Cancel, Download |
Prepare creates the document and returns its exact totalCents without
charging or sending it. Set a unique Idempotency Key under Options.
After reviewing the PDF and approving the price, use Send with identical
input and the same key, enable Confirm Prepared Price, and map totalCents
to Confirmed Total (Cents). Changing the content or price is refused.
This addition is in the source package; platform installation and acceptance
of this version are still pending.
| Address | Validate |
| Pricing | Quote |
Send takes its content one of three ways: typed text that we lay out, a PDF from a binary field on the item, or a PDF at a URL. Pick one — the API refuses two rather than guessing, because the wrong document in a postbox cannot be recalled.
Set an Idempotency Key on anything that might run twice. n8n retries a
failed node and a workflow can be replayed by hand; without a key that is a
second envelope through somebody's door. Use something from the data, such as
{{$json.invoiceNumber}}.
For a PDF approval flow, connect Prepare → Send. Use the same input binary
field name and Idempotency Key in both nodes. Enable Confirm Prepared Price
on Send and map {{$json.totalCents}} from Prepare. Version 1.2.0 preserves the
original binary file through preparation, confirmation and replay, including
its filename. A direct chain no longer needs a separate Merge node to recover
the PDF. The compiled regression check is npm run test:binary.
Quote provides an indicative consumer tariff. Account-specific pricing can
differ; approve the exact totalCents returned by Prepare before sending.
Actual n8n 2.37.10 execution also passed URL preparation, binary PDF preparation/confirmation/replay, Get, Download, Cancel, Quote, Validate and both list modes (23 unique test letters). The test wallet stayed at zero. Listing more than one 100-item page is covered separately in the release evidence.
Validate answers rather than fails when an address is wrong: read valid
and problems. Put it in front of a send and you find the bad rows in a
spreadsheet before spending anything on them.
SendLetter Trigger
Starts a workflow when a letter is submitted, printed, posted, delivered, failed or refunded.
A real subscription, not polling: activating the workflow registers its webhook URL, deactivating removes it. Every callback is verified against the signing secret before the workflow runs, so an open URL cannot be used to tell your workflow a letter was delivered when it was not — which matters, because "delivered" is what closes a deadline in most of the workflows this exists for.
The trigger needs an https URL, so on a local install use a tunnel.
Leave Events empty to receive every supported status, or select the events you
need. Map letter.id to your source record, read letter.mode to distinguish
test from live and store the event's top-level id to prevent duplicate processing
when delivery is retried. A restored workflow can re-subscribe to recover a
missing signing secret. Invalid signatures receive HTTP 401 and do not start
the workflow. Temporary unsubscribe failures retain the local subscription
reference for retry; a confirmed missing subscription is treated as removed.
Version 1.2.0 has seven compiled-trigger regression tests (npm run
test:trigger). Actual n8n 2.37.10 received four fresh simulated postal statuses,
rejected unsigned/altered callbacks with HTTP 401 and accepted signed replay.
Deactivation removed the subscription and signing secret; reactivation received
four new statuses. Evidence and English/Dutch screenshots are in the main
repository's docs/integrations/AUTOMATION-PREPARE.md.
A worked example
Dunning by post, which is the reason most people install this:
- Schedule Trigger — first of the month
- Postgres / Google Sheets — invoices more than 30 days overdue
- SendLetter — Letter → Send, PDF from binary field, idempotency key
reminder-{{$json.invoiceId}}-{{$json.reminderCount}} - SendLetter Trigger in a second workflow — on
letter.delivered, write the date back to the invoice
Step 3's idempotency key is what makes it safe to re-run the whole month if step 2 fails halfway.
Errors
Refusals arrive as readable sentences rather than a status code. Two are worth handling with an IF node:
- insufficient_balance — the prepaid wallet is short. The message carries a payment link.
- rate_limited — the message says how many seconds to wait.
Everything else is a permanent refusal: retrying a bad postcode produces the same bad postcode.
Licence
MIT. Not affiliated with n8n GmbH.
