Personalize and Send Certificates at Scale using PDF.co and n8n

Jun 17, 2025·3 Minutes Read

What You'll Have When Done: Personalized course completion certificates automatically created from a Google Sheets record and emailed to students at course completion.

Prerequisites

Make sure you have these set up:

  • Google Sheets with students record (Sample Here)
  • PDF.co API Key
  • n8n instance (self-hosted or n8n.cloud)
  • Google Sheets OAuth2 credentials added in n8n
  • Google Drive OAuth2 credentials added in n8n
  • Certificate template uploaded to PDF.co Files

Quick Start Options

Option A: I Want It Working Now

  • Import this workflow template → Download JSON File
  • Connect your Google and PDF.co accounts
  • Link correct Google Sheet, Google Drive Folder, and PDF Template.
  • Test with sample data
  • Schedule and run.

Option B: I Want to Build It Follow the 12-step guide below to create the automation from scratch.

What This Automation Does (Overview)

  1. Schedule Trigger runs monthly to check for certificates to send
  2. Google Sheets retrieves student records with "Pending" status
  3. Loop Processing handles one record at a time
  4. Filter Check only processes pending records
  5. PDF Generation creates personalized certificate using PDF.co
  6. Email Delivery sends certificate directly to student

Status Update marks record as "Sent" in spreadsheet

Step 1: Set Up Your Google Sheet

Create a spreadsheet with these columns or download the Students Record Sample:

  • Student Name (e.g., "John Smith")
  • Student Email (e.g., "john@email.com")
  • Course (e.g., "Advanced JavaScript")
  • Completion Date (e.g., "June 30, 2025")
  • Send Date (e.g., "June 30, 2025")
  • Status (e.g., "Pending")

Step 2: Schedule Trigger

  • Node: Schedule Trigger
  • Settings:
    • Trigger Interval: Custom (Cron)
    • Expression: 0 0 1 * * (runs monthly on 1st)
    • Or customize for your needs

Success Looks Like: Trigger fires on schedule.

Step 3: Get Student Records

  • Node: Google Sheets → Get Row(s)
  • Settings:
    • Document: Select your certificate spreadsheet
    • Sheet: Sheet1 (or your sheet name)

Success Looks Like:

[
  {
    "Student Name": "John Smith",
    "Student Email": "john@email.com",
    "Course": "Advanced JavaScript",
    "Status": "Pending"
  }
]

Step 4: Loop Over Items

  • Node: Loop Over Items → Split in Batches
  • Settings:
    • Batch Size: 1

Success Looks Like: Records process one at a time.

Step 5: Filter Pending Records

  • Node: IF Condition
  • Settings:
    • Condition: {{ $json.Status }} equals Pending
    • Only TRUE path gets connected (FALSE path stays empty)

Success Looks Like: Only pending certificates continue processing.

Step 6: Generate Personalized PDF Certificates

  • Node: PDF.co → Add Text/Images to PDF
  • Settings:
    • Url: Link to the certificate template.
    • Text Annotations:
      • Student Name: {{ $json['Student Name'] }}
      • Course: {{ $json.Course }}
      • Date: {{ $json['Completion Date'] }}
    • Advanced Options:
      • File Name: {{ $json['Student Name'] }}_{{ $json.Course }}.pdf

Success Looks Like:

{
  "url": "https://pdf-co-temp-files.s3.../certificate.pdf...",
  "name": "John_Smith_Advanced_JavaScript.pdf"
}

Step 7: Download PDF

  • Node: HTTP Request
  • Settings:
    • Method: GET
    • URL: {{ $json.url }} (from PDF.co output)
    • Authentication: None

Success Looks Like: PDF binary data in response.

Step 8: Save a Certificate Copy to Google Drive

  • Node: Google Drive → Upload
  • Settings:
    • Input Data Field: data
    • Folder: Select "Certificates" folder
    • Drive: My Drive

Success Looks Like: Certificate appears in Google Drive Folder.

Step 9: Email Certificates to Students

  • Node: HTTP Request - PDF.co Email API
  • Settings:
    • Method: POST
    • URL: https://api.pdf.co/v1/email/send
    • Headers:
      • Content-Type: application/json
      • x-api-key: YOUR_PDF_CO_API_KEY
    • Body Parameters:
      • url: {{ $('PDFco Api').item.json.url }}
      • from: your-email@domain.com
      • to: {{ $('Students Record').item.json['Student Email'] }}
      • subject: {{ $('PDFco Api').item.json.name }}
      • bodytext: "Congratulations! Your certificate is attached."
      • smtpserver: smtp.gmail.com (For Google-hosted Email)
      • smtpport: 587
      • smtpusername: your-email@domain.com
      • smtppassword: Create app password at https://myaccount.google.com/apppasswords

Success Looks Like: Email sent confirmation response.

Note: You can learn more about the Send Email API at the API Docs.

Step 10: Update Delivery Status

  • Node: Google Sheets → Update Row
  • Settings:
    • Document: Same spreadsheet
    • Column to Match: row_number
    • Value to Match: {{ $('Students Record').item.json.row_number }}
    • Status: "Sent"

Success Looks Like: Spreadsheet’s Status column shows "Sent" status.

Step 11: Rate Limit Protection

  • Node: Wait
  • Settings:
    • Amount: 1-3 seconds
    • Unit: seconds

Success Looks Like: Workflow pauses between each certificate.

Step 12: Loop Back

  • Connection: Wait node → Loop Over Items (input)
  • This creates the loop that processes the next record

Congrats! You've automated certificate creation and delivery at scale.

Built something cool? Share it with us @pdfdotco

Related Tutorials

See Related Tutorials