This workflow corresponds to n8n.io template #15438 — we link there as the canonical source.
This workflow follows the Gmail → Google Drive recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "hNNDtV2nc8aN0EBy",
"name": "Google Sheets \u2192 Certificate PDF \u2192 Gmail + Google Drive",
"tags": [],
"nodes": [
{
"id": "c1000001-0000-4000-a000-000000000001",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-544,
-128
],
"parameters": {
"width": 460,
"height": 1100,
"content": "### Google Sheets \u2192 Certificate PDF \u2192 Gmail + Google Drive\nIssue branded, archival-quality certificate PDFs the moment a new completion row lands in your Google Sheet. The PDF is archived in Drive and the **permanent Drive URL** is written back to the source sheet, giving you a full audit trail of who got their certificate and when.\n\n**Full tutorial:** [templatefox.com/n8n/automate-certificates](https://templatefox.com/n8n/automate-certificates)\n\n### How it works\n1. **Google Sheets Trigger** fires on every new completion row\n2. **TemplateFox** maps the row data to your certificate template fields and renders a branded **PDF/A-2b** (archival-grade) certificate\n3. The PDF is **downloaded** and **archived** to your Google Drive folder\n4. The certificate is **emailed** to the participant with the permanent Drive link\n5. The source row is **updated** with the Drive URL and issue timestamp\n\n### Setup\n- [ ] Create a Google Sheet with columns: `Participant Name`, `Email`, `Course`, `Completion Date`, `Instructor`\n- [ ] Add two more columns to be written back: `Certificate URL`, `Issued At`\n- [ ] Connect **Google Sheets** OAuth2 in the trigger and update nodes\n- [ ] Install the **TemplateFox** community node (`n8n-nodes-templatefox`)\n- [ ] Add your **TemplateFox** API key \u2014 [get one free](https://app.templatefox.com)\n- [ ] Select your certificate template in the TemplateFox node and map each field to the matching column from the trigger\n- [ ] Connect **Gmail** OAuth2\n- [ ] Connect **Google Drive** OAuth2 and set your archive folder ID\n\n### Customize\n- Set your organisation's logo, signatures, and constant fields **directly in the TemplateFox template editor** \u2014 no need to pass them through n8n\n- Swap PDF/A-2b for `pdf/a-3b` if your training body requires PDF/A-3 compliance\n- Add a Slack node after the Drive step to ping your training team\n- Add an `IF` node before TemplateFox to skip rows where `Score` is below your passing threshold\n- Replace the Sheets trigger with a **Schedule** trigger + a `Get Many Rows` step to issue certificates in nightly batches"
},
"typeVersion": 1
},
{
"id": "c1000001-0000-4000-a000-000000000002",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-48,
-128
],
"parameters": {
"color": 7,
"width": 280,
"height": 360,
"content": "## 1. Watch the sheet\nFires whenever a new completion row is added to your Google Sheet."
},
"typeVersion": 1
},
{
"id": "c1000001-0000-4000-a000-000000000003",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
288,
-128
],
"parameters": {
"color": 7,
"width": 280,
"height": 360,
"content": "## 2. Generate\nMap the row data to your certificate template and render a PDF/A-2b."
},
"typeVersion": 1
},
{
"id": "c1000001-0000-4000-a000-000000000004",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
608,
-128
],
"parameters": {
"color": 7,
"width": 1100,
"height": 360,
"content": "## 3. Deliver, archive & track\nDownload, archive in Drive, email the participant with the permanent link, then write the Drive URL back to the source sheet."
},
"typeVersion": 1
},
{
"id": "c1000001-0000-4000-a000-000000000010",
"name": "New Completion Row",
"type": "n8n-nodes-base.googleSheetsTrigger",
"position": [
32,
32
],
"parameters": {
"event": "rowAdded",
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "",
"cachedResultName": ""
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "",
"cachedResultName": ""
}
},
"typeVersion": 1
},
{
"id": "c1000001-0000-4000-a000-000000000011",
"name": "TemplateFox",
"type": "n8n-nodes-templatefox.templateFox",
"position": [
320,
32
],
"parameters": {
"options": {
"filename": "=certificate-{{ $json.Email || 'participant' }}",
"pdfVariant": "pdf/a-2b"
}
},
"typeVersion": 1
},
{
"id": "c1000001-0000-4000-a000-000000000012",
"name": "Download PDF",
"type": "n8n-nodes-base.httpRequest",
"position": [
624,
32
],
"parameters": {
"url": "={{ $json.url }}",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
}
},
"typeVersion": 4.2
},
{
"id": "c1000001-0000-4000-a000-000000000013",
"name": "Archive to Google Drive",
"type": "n8n-nodes-base.googleDrive",
"position": [
880,
32
],
"parameters": {
"name": "=certificate-{{ $('New Completion Row').first().json.Email || 'participant' }}.pdf",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"options": {
"simplifyOutput": false
},
"folderId": ""
},
"typeVersion": 3
},
{
"id": "c1000001-0000-4000-a000-000000000014",
"name": "Email Certificate",
"type": "n8n-nodes-base.gmail",
"position": [
1152,
32
],
"parameters": {
"sendTo": "={{ $('New Completion Row').first().json.Email }}",
"message": "=<p>Hi {{ $('New Completion Row').first().json['Participant Name'] }},</p>\n<p>Congratulations on completing <strong>{{ $('New Completion Row').first().json.Course }}</strong>! Your official certificate is ready.</p>\n<p><a href=\"{{ $json.webViewLink }}\" style=\"display:inline-block;padding:12px 20px;background:#111;color:#fff;text-decoration:none;border-radius:6px;font-weight:600\">Download your certificate (PDF)</a></p>\n<p style=\"color:#555\">\n <strong>Course:</strong> {{ $('New Completion Row').first().json.Course }}<br>\n <strong>Completed:</strong> {{ $('New Completion Row').first().json['Completion Date'] }}\n</p>\n<p>Thanks for learning with us!</p>",
"options": {},
"subject": "=\ud83c\udf93 Your certificate for {{ $('New Completion Row').first().json.Course }}"
},
"typeVersion": 2.1
},
{
"id": "c1000001-0000-4000-a000-000000000015",
"name": "Update Sheet Row",
"type": "n8n-nodes-base.googleSheets",
"position": [
1408,
32
],
"parameters": {
"columns": {
"value": {
"Email": "={{ $('New Completion Row').first().json.Email }}",
"Issued At": "={{ $now.toISO() }}",
"Certificate URL": "={{ $('Archive to Google Drive').first().json.webViewLink }}"
},
"mappingMode": "defineBelow",
"matchingColumns": [
"Email"
]
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "id",
"value": "={{ $('New Completion Row').first().json._sheet_name || '' }}"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "={{ $('New Completion Row').first().json._sheet_id || '' }}"
}
},
"typeVersion": 4.5
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"callerPolicy": "workflowsFromSameOwner",
"availableInMCP": false,
"executionOrder": "v1"
},
"versionId": "9d3e4586-0ba1-4da0-ad29-cd654d7eecab",
"connections": {
"TemplateFox": {
"main": [
[
{
"node": "Download PDF",
"type": "main",
"index": 0
}
]
]
},
"Download PDF": {
"main": [
[
{
"node": "Archive to Google Drive",
"type": "main",
"index": 0
}
]
]
},
"Email Certificate": {
"main": [
[
{
"node": "Update Sheet Row",
"type": "main",
"index": 0
}
]
]
},
"New Completion Row": {
"main": [
[
{
"node": "TemplateFox",
"type": "main",
"index": 0
}
]
]
},
"Archive to Google Drive": {
"main": [
[
{
"node": "Email Certificate",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow turns a Google Sheet into an automated certificate-issuing pipeline. The moment a new completion row is added — whether by your training team, a Zap, or a quiz platform — a branded PDF/A-2b (archival-grade) certificate is rendered by TemplateFox, archived in Google…
Source: https://n8n.io/workflows/15438/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Hiring teams often struggle with document follow-ups, offer letter generation, and stakeholder communication. Manual checks, email back-and-forth, and missing files slow down hiring and create chaos d
This workflow automates the end-to-end process of generating and sending client payment links using Google Sheets and Stripe.
This template is ideal for HR teams, startup founders, operations leads, remote-first companies, and freelancers managing onboarding manually or across multiple tools.
Automatically processes new orders added to Google Sheets. Small orders are approved instantly; large orders trigger an HTML email with one-click Approve / Reject links — each handled by an independen
General use cases include: Property managers who manage multiple buildings or units. Building owners looking to centralize tenant repair communication. Automation builders who want to learn multi-trig