Send from n8n workflows
Install the Papier community node, connect your API key, and send versioned templates from any workflow.
BEFORE YOU START
You’ll need a self-hosted n8n instance and a Papier workspace with a published template. n8n Cloud lists only verified community nodes, so use your own n8n host until verification completes. Create a Runtime API key in the Papier console and keep it secret.
Install the community node#
In n8n, open Settings → Community Nodes, choose Install a community node, and enter @usepapier/n8n-nodes-papier. Confirm the install and wait for n8n to load the Papier node.
n8n Cloud only lists verified community nodes. The Papier node works on self-hosted n8n today; Cloud availability follows verification.
Connect your Papier API key#
Add a Papier node to your workflow and create a new Papier API credential. Paste your Runtime API key into the API Key field and save. The key travels as a Bearer token and is never written into your templates or logs.
Leave the Worker URL option on its default. It exists only for pointing a development build at a local worker.
Configure the send#
Pick the channel (Email, SMS or Push) and the Send operation. Then select the release to render: the project slug, template slug, locale, and environment (choose it from the list once the project slug is entered), plus a semver Version Range such as ^1.0.0. The newest compatible release in that environment is served, just like the SDK’s version ranges. Add the recipient fields for your channel — for push, a user’s external ID or a single subscription ID.
Map template data from previous nodes#
Fill Data with the template variables as a JSON object. Map fields from previous nodes with expressions; every execution renders with that item’s data.
{
"name": "{{ $json.name }}",
"plan": "{{ $json.plan }}"
}Publishing a new template version never breaks the workflow: compatible releases keep serving through the same range until you change it.
Run and read the result#
Run the workflow once with the Execute step button. The output item carries the resolvedVersion that was served and the accepted messages. Import this minimal workflow to start from a working shape, then swap in your own trigger and slugs.
{
"name": "Papier welcome email",
"nodes": [
{
"parameters": {},
"id": "9d5c1a2b-0000-4000-8000-000000000001",
"name": "When chat message received",
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"typeVersion": 1.1,
"position": [240, 300],
"webhookId": "00000000-0000-4000-8000-000000000001"
},
{
"parameters": {
"resource": "email",
"operation": "send",
"projectSlug": "marketing",
"templateSlug": "welcome-email",
"versionRange": "^1.0.0",
"locale": "en-US",
"data": "={{ { name: $json.name, plan: $json.plan } }}",
"toEmail": "={{ $json.email }}",
"fromEmail": "hello@example.com",
"subject": "={{ `Welcome aboard, ${$json.name}` }}"
},
"id": "9d5c1a2b-0000-4000-8000-000000000002",
"name": "Papier",
"type": "@usepapier/n8n-nodes-papier.papier",
"typeVersion": 1,
"position": [460, 300],
"credentials": {
"papierApi": {
"id": "1",
"name": "Papier API"
}
}
}
],
"connections": {
"When chat message received": {
"main": [[{ "node": "Papier", "type": "main", "index": 0 }]]
}
}
}For repeated runs, set an Idempotency Key under Additional Options: retrying with the same key returns the original message instead of sending again.