{
  "id": "lRXtQJqclgbWMSOn",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Certificate-Creator&Validation WithTemplates",
  "tags": [
    {
      "id": "DNVBijE9cEya3mqW",
      "name": "PROD",
      "createdAt": "2025-11-23T13:34:14.752Z",
      "updatedAt": "2025-11-23T13:34:14.752Z"
    },
    {
      "id": "T2GE36JapoXlWhjo",
      "name": "creator-published",
      "createdAt": "2025-11-23T13:36:13.729Z",
      "updatedAt": "2025-11-23T13:36:13.729Z"
    }
  ],
  "nodes": [
    {
      "id": "8aa6949f-3935-4b5f-993e-58109ae2dc46",
      "name": "Insert_Certificaton",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        320,
        -224
      ],
      "parameters": {
        "columns": {
          "value": {
            "Name": "={{ $('Webhook_Creation').item.json.headers.name }}",
            "Surname": "={{ $('Webhook_Creation').item.json.headers.surname }}",
            "CertificationID": "={{ $('Generate_Certification_ID').item.json.id }}"
          },
          "schema": [
            {
              "id": "Name",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Name",
              "defaultMatch": false
            },
            {
              "id": "Surname",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Surname",
              "defaultMatch": false
            },
            {
              "id": "CertificationID",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "CertificationID",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "ZyOrfuHDK22tXq81",
          "cachedResultUrl": "/projects/jmCdsRSQMosgYP5V/datatables/ZyOrfuHDK22tXq81",
          "cachedResultName": "Certifications"
        }
      },
      "typeVersion": 1,
      "alwaysOutputData": true
    },
    {
      "id": "5276e288-b7e2-4e82-8038-6ed25283e9f9",
      "name": "Generate_Certification_ID",
      "type": "n8n-nodes-base.code",
      "position": [
        -352,
        -240
      ],
      "parameters": {
        "jsCode": "const uniqueId =\n  Date.now().toString(36).toUpperCase() +\n  Math.random().toString(36).substring(2, 8).toUpperCase();\n\nreturn [{ id: uniqueId }];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "17def385-21b1-4479-86aa-bcf99964bc26",
      "name": "Find_Certification_By_ID",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        -144,
        -240
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "CertificationID",
              "keyValue": "={{ $json.id }}"
            }
          ]
        },
        "operation": "get",
        "returnAll": true,
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "ZyOrfuHDK22tXq81",
          "cachedResultUrl": "/projects/jmCdsRSQMosgYP5V/datatables/ZyOrfuHDK22tXq81",
          "cachedResultName": "Certifications"
        }
      },
      "typeVersion": 1,
      "alwaysOutputData": true
    },
    {
      "id": "aa33fda6-c7d7-419b-ac65-6888e4939b8b",
      "name": "Certification_ID_Exists",
      "type": "n8n-nodes-base.if",
      "position": [
        64,
        -240
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "416a8c8a-b9bd-4044-9987-b3320c09efd4",
              "operator": {
                "type": "string",
                "operation": "empty",
                "singleValue": true
              },
              "leftValue": "=Object",
              "rightValue": "={{ $json }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "a3a47b41-ddff-45ee-8ffc-74ab0ed0cb06",
      "name": "Email_Certification",
      "type": "n8n-nodes-base.gmail",
      "position": [
        736,
        -224
      ],
      "parameters": {
        "sendTo": "={{ $('Webhook_Creation').item.json.headers.email }}",
        "message": "Attached you find your new certification!",
        "options": {
          "attachmentsUi": {
            "attachmentsBinary": [
              {
                "property": "document.pdf"
              }
            ]
          }
        },
        "subject": "Your certification is ready!"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "29812013-9f2f-4211-bc0a-9d16fbc45f10",
      "name": "Webhook_Check",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -592,
        224
      ],
      "parameters": {
        "path": "certificationscheck2",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "0f02a5e6-368e-4d85-a95e-fa039a7670e0",
      "name": "Find_Certification_By_ID1",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        -352,
        224
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "CertificationID",
              "keyValue": "={{ $json.headers.id }}"
            }
          ]
        },
        "operation": "get",
        "returnAll": true,
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "ZyOrfuHDK22tXq81",
          "cachedResultUrl": "/projects/jmCdsRSQMosgYP5V/datatables/ZyOrfuHDK22tXq81",
          "cachedResultName": "Certifications"
        }
      },
      "typeVersion": 1,
      "alwaysOutputData": true
    },
    {
      "id": "9beea287-488e-425a-8185-aaf4938448e1",
      "name": "Certification_Exists",
      "type": "n8n-nodes-base.if",
      "position": [
        -144,
        224
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "416a8c8a-b9bd-4044-9987-b3320c09efd4",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.CertificationID }}",
              "rightValue": "={{ $('Webhook_Check').item.json.headers.id }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "1c363567-193e-45d4-9d43-82460a06fd83",
      "name": "Respond_Found",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        96,
        160
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={\n  \"ok\": \"true\",\n  \"name\": \"{{ $('Find_Certification_By_ID1').item.json.Name }}\",\n  \"surname\": \"{{ $('Find_Certification_By_ID1').item.json.Surname }}\"\n}"
      },
      "typeVersion": 1.4
    },
    {
      "id": "9169c821-6fe5-43d3-83b2-2d47c4add2d9",
      "name": "Respond_NotFound",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        96,
        288
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "{\n  \"ok\": \"false\"\n}"
      },
      "typeVersion": 1.4
    },
    {
      "id": "e5d78a9d-74cf-494f-9057-d2de3a8d0691",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -672,
        -448
      ],
      "parameters": {
        "color": 7,
        "width": 256,
        "height": 368,
        "content": "## Creation  \n## Webhook input\n\nReceives name, surname, course and email via HTTP POST on `/certifications`.  \nStarts the certificate creation flow.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "bb676994-7df9-4873-b260-8086c74ad6b1",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -400,
        -448
      ],
      "parameters": {
        "color": 7,
        "width": 864,
        "height": 368,
        "content": "## Creation \u2013 Generate & validate ID\n\nGenerates a random CertificationID, checks the Data Table for duplicates and only continues when the ID is unique.  \nIf the ID already exists, the flow loops until a free one is found.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "b876bfd4-fd59-49ca-9386-9a55cd754a78",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        480,
        -448
      ],
      "parameters": {
        "color": 7,
        "width": 448,
        "height": 368,
        "content": "## Creation \u2013 Save, PDF & email\n\nSaves the learner record with the CertificationID to the Data Table, generates the certificate PDF from an HTML template and emails it to the learner.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "80d9e416-5bde-4845-948d-f08ad893b737",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -672,
        32
      ],
      "parameters": {
        "color": 7,
        "width": 256,
        "height": 320,
        "content": "## Check \u2013 Webhook input\n\nReceives a CertificationID via HTTP POST on `/certificationscheck` and starts the verification flow.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "3e2d8f20-4f2c-4f9a-9948-455886e62039",
      "name": "Webhook_Creation",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -592,
        -240
      ],
      "parameters": {
        "path": "certifications2",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "lastNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "3adee942-b0b4-4bec-adaa-fe5bddc60f2d",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -400,
        32
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 320,
        "content": "## Check \u2013 Look up ID\n\nSearches the Certifications Data Table for the submitted CertificationID and branches depending on whether a matching record exists.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "cf2f8732-9ee6-4f3a-9022-836d788d66ce",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        272,
        176
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 176,
        "content": "## Check \u2013 Responses\n\nReturns JSON to the caller.  \nIf the ID is found: `ok: true` plus name and surname.  \nIf not found: `ok: false` so the client can show an \u201cinvalid certification\u201d message.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "338fc6e8-eb2e-4801-8a89-b4d8f35f86f2",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1344,
        -448
      ],
      "parameters": {
        "width": 640,
        "height": 560,
        "content": "## Certifications \u2013 Creator & Checker\n\n## How it works\nThis workflow manages the full lifecycle of a training certificate.  \n`/certifications` receives learner details, generates a unique CertificationID and checks that it does not exist yet.  \nIf the ID is free, the workflow stores the record, builds a PDF certificate and emails it to the learner.  \n\n`/certificationscheck` lets you verify a certificate later.  \nThe webhook receives a CertificationID, looks it up in the same Data Table and returns a simple JSON response that frontends or other services can use to show \u201cvalid\u201d or \u201cnot found\u201d.\n\n## Setup steps\n1. Create a Data Table (e.g. **Certifications**) with Name, Surname, CertificationID and any extra fields.\n2. Configure the PDF Generator node with your account API and adjust the HTML template to your branding.\n3. Connect your email account (Gmail/SMTP) in **Email_Certification**.\n4. Deploy the `/certifications` and `/certificationscheck` webhooks and use their public URLs.\n5. Test creation and verification with a few sample requests before going live.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "33d6d124-643b-4cb5-b7bc-a78266aaefec",
      "name": "Generate a PDF document",
      "type": "@pdfgeneratorapi/n8n-nodes-pdf-generator-api.pdfGeneratorApi",
      "position": [
        544,
        -224
      ],
      "parameters": {
        "data": "={\n  \"DueDate\": \"{{$now.toISODate()}}\",\n  \"Candidate\": \"{{$('Webhook_Creation').item.json.headers.name}} {{$('Webhook_Creation').item.json.headers.surname}}\",\n  \"CourseName\": \"{{ $('Webhook_Creation').item.json.headers.course }}\",\n  \"ID\": \"{{ $('Generate_Certification_ID').item.json.id }}\"\n}",
        "templateId": {
          "__rl": true,
          "mode": "list",
          "value": "1560735",
          "cachedResultName": "Certificate Example (ID: 1560735)"
        },
        "documentOutput": "file",
        "additionalFields": {}
      },
      "credentials": {
        "pdfGeneratorApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "27c846c4-3476-4aaa-b81d-19c93a130da0",
  "connections": {
    "Webhook_Check": {
      "main": [
        [
          {
            "node": "Find_Certification_By_ID1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook_Creation": {
      "main": [
        [
          {
            "node": "Generate_Certification_ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Insert_Certificaton": {
      "main": [
        [
          {
            "node": "Generate a PDF document",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Certification_Exists": {
      "main": [
        [
          {
            "node": "Respond_Found",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Respond_NotFound",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Certification_ID_Exists": {
      "main": [
        [
          {
            "node": "Generate_Certification_ID",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Insert_Certificaton",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate a PDF document": {
      "main": [
        [
          {
            "node": "Email_Certification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Find_Certification_By_ID": {
      "main": [
        [
          {
            "node": "Certification_ID_Exists",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Find_Certification_By_ID1": {
      "main": [
        [
          {
            "node": "Certification_Exists",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate_Certification_ID": {
      "main": [
        [
          {
            "node": "Find_Certification_By_ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}