AutomationFlowsData & Sheets › Institution - Batch Credential Issuance - Fixed

Institution - Batch Credential Issuance - Fixed

Institution - Batch Credential Issuance - FIXED. Uses itemLists, mongoDb. Webhook trigger; 8 nodes.

Webhook trigger★★★★☆ complexity8 nodesItem ListsMongoDB
Data & Sheets Trigger: Webhook Nodes: 8 Complexity: ★★★★☆ Added:

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 →

Download .json
{
  "name": "Institution - Batch Credential Issuance - FIXED",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "batch-issue-acledger-v1",
        "options": {}
      },
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{$json.headers[\"x-acl-auth-key\"]}}",
              "operation": "equal",
              "value2": "={{$env.ACL_AUTH_KEY}}"
            }
          ]
        }
      },
      "name": "Security Guard",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        200,
        0
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "{\"error\": \"Unauthorized\", \"message\": \"Invalid security token\"}",
        "options": {
          "responseCode": 401
        }
      },
      "name": "Reject Request",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        200,
        200
      ]
    },
    {
      "parameters": {
        "fieldToSplitOut": "credentials"
      },
      "name": "Split Credentials",
      "type": "n8n-nodes-base.itemLists",
      "typeVersion": 1,
      "position": [
        400,
        0
      ]
    },
    {
      "parameters": {
        "jsCode": "const item = $json || {};\nconst nowIso = new Date().toISOString();\n\nconst computeUniqueHash = (ipfsURI) => {\n  const link = String(ipfsURI || '').trim();\n  if (!link) return `hash-${Date.now()}`;\n  try {\n    const crypto = require('crypto');\n    return 'hash-' + crypto.createHash('sha256').update(link).digest('hex');\n  } catch (e) {\n    let h = 0;\n    for (let i = 0; i < link.length; i++) {\n      h = ((h << 5) - h) + link.charCodeAt(i);\n      h |= 0;\n    }\n    return 'hash-fallback-' + Math.abs(h).toString(16);\n  }\n};\n\nconst makeDoc = (i = {}) => {\n  const tokenId = String(i.tokenId || ('0.0.' + (Math.floor(Math.random() * 9000000) + 1000000)));\n  const serialNumber = String(i.serialNumber || '1');\n  const universityId = i.universityId || null;\n  const studentAccountId = (i.studentAccountId === undefined) ? null : i.studentAccountId;\n  const ipfsURI = i.ipfsURI || 'ipfs://QmTest';\n  const uniqueHash = i.uniqueHash || computeUniqueHash(ipfsURI);\n  const ext = i.externalProofs || {};\n  const externalProofs = {\n    hederaTx: ext.hederaTx || null,\n    xrpTxHash: ext.xrpTxHash || null,\n    algoTxId: ext.algoTxId || null\n  };\n  return {\n    tokenId,\n    serialNumber,\n    universityId,\n    studentAccountId,\n    uniqueHash,\n    ipfsURI,\n    externalProofs,\n    createdAt: nowIso,\n    updatedAt: nowIso,\n    __v: 0\n  };\n};\n\nreturn { json: makeDoc(item) };"
      },
      "name": "Build Credential Docs",
      "type": "n8n-nodes-base.code",
      "typeVersion": 1,
      "position": [
        600,
        0
      ]
    },
    {
      "parameters": {
        "operation": "insert",
        "collection": "issued_credentials",
        "options": {}
      },
      "name": "Save to Mongo",
      "type": "n8n-nodes-base.mongoDb",
      "typeVersion": 1,
      "position": [
        800,
        0
      ],
      "credentials": {
        "mongoDb": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "aggregateItems",
        "fieldsToAggregate": {
          "fieldToAggregate": [
            {
              "fieldToAggregate": "uniqueHash",
              "renameField": "hashes"
            },
            {
              "fieldToAggregate": "tokenId",
              "renameField": "tokenIds"
            }
          ]
        }
      },
      "name": "Aggregate Results",
      "type": "n8n-nodes-base.itemLists",
      "typeVersion": 1,
      "position": [
        1000,
        0
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "{\n  \"success\": true,\n  \"message\": \"Batch processed successfully\",\n  \"count\": {{$json.hashes.length}},\n  \"hashes\": {{$json.hashes}},\n  \"tokenIds\": {{$json.tokenIds}}\n}",
        "options": {}
      },
      "name": "Respond to App",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        1200,
        0
      ]
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Security Guard",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Security Guard": {
      "main": [
        [
          {
            "node": "Split Credentials",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Reject Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Credentials": {
      "main": [
        [
          {
            "node": "Build Credential Docs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Credential Docs": {
      "main": [
        [
          {
            "node": "Save to Mongo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save to Mongo": {
      "main": [
        [
          {
            "node": "Aggregate Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate Results": {
      "main": [
        [
          {
            "node": "Respond to App",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Institution - Batch Credential Issuance - FIXED. Uses itemLists, mongoDb. Webhook trigger; 8 nodes.

Source: https://github.com/Aether-Connect-Labs/AcademicChain-Ledger/blob/main/n8n/workflows/batch-issue.json — original creator credit. Request a take-down →

More Data & Sheets workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Data & Sheets

BP_check. Uses googleSheets, @n-octo-n/n8n-nodes-json-database, httpRequest, itemLists. Webhook trigger; 99 nodes.

Google Sheets, @N Octo N/N8N Nodes Json Database, HTTP Request +2
Data & Sheets

BP_check2. Uses googleSheets, @n-octo-n/n8n-nodes-json-database, httpRequest, itemLists. Webhook trigger; 95 nodes.

Google Sheets, @N Octo N/N8N Nodes Json Database, HTTP Request +2
Data & Sheets

This workflow automates raw materials inventory management for businesses, eliminating manual stock updates, delayed material issue approvals, and missed low stock alerts. It ensures real-time stock t

Google Sheets, Gmail, Supabase +1
Data & Sheets

Orquestador Multichain AcademicChain. Uses httpRequest, moveBinaryData, mongoDb. Webhook trigger; 23 nodes.

HTTP Request, Move Binary Data, MongoDB
Data & Sheets

Enhance your support documentation with an audio-first experience. This workflow converts Supabase FAQ entries into high-quality audio using Google Cloud TTS, hosts them via a CDN, and embeds them int

HTTP Request, Item Lists