This workflow corresponds to n8n.io template #13229 — we link there as the canonical source.
This workflow follows the HTTP Request → Slack 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": "W3unQdoRSdzDXDyPfCKdj",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "File Hash Reputation Checker",
"tags": [
{
"id": "PQsDv8dbNswnsItE",
"name": "cybersecurity",
"createdAt": "2026-02-04T07:53:18.370Z",
"updatedAt": "2026-02-04T07:53:18.370Z"
},
{
"id": "jI1EvO6QTAu5XPp6",
"name": "virus total",
"createdAt": "2026-02-04T07:53:38.155Z",
"updatedAt": "2026-02-04T07:53:38.155Z"
},
{
"id": "mOOHD7ZEi5V8NM1I",
"name": "malware",
"createdAt": "2026-02-04T07:53:56.067Z",
"updatedAt": "2026-02-04T07:53:56.067Z"
},
{
"id": "qfS2esG6Rh52i4DR",
"name": "slack",
"createdAt": "2026-01-29T06:09:26.747Z",
"updatedAt": "2026-01-29T06:09:26.747Z"
},
{
"id": "ql9O8hOXPjaCNbht",
"name": "hash",
"createdAt": "2026-02-04T07:53:09.179Z",
"updatedAt": "2026-02-04T07:53:09.179Z"
}
],
"nodes": [
{
"id": "34008e71-38bb-4de3-a060-1eb96f1686fa",
"name": "Receive File Hash",
"type": "n8n-nodes-base.webhook",
"position": [
-48,
176
],
"parameters": {
"path": "/hash-check",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 2.1
},
{
"id": "9985ba85-7a31-44d0-beb3-d1a7541c0ef8",
"name": "Respond - Clean or Unknown",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
1520,
272
],
"parameters": {
"options": {},
"respondWith": "json",
"responseBody": "={\n \"hash\": \"{{ $json.hash }}\",\n \"verdict\": \"{{$json.verdict}}\",\n \"malicious\":{{ $json.malicious }},\n \"suspicious\":{{ $json.suspicious }},\n \"detections\": \"{{$json.malicious}}/{{$json.total}}\"\n} "
},
"typeVersion": 1.5
},
{
"id": "3f542484-250d-416e-aa4e-4aeada8b029d",
"name": "Slack - Malicious Hash Alert",
"type": "n8n-nodes-base.slack",
"position": [
1520,
80
],
"parameters": {
"text": "=\ud83d\udea8 MALICIOUS FILE DETECTED\nHash: {{ $json.hash }}\nDetections: {{$json.malicious}}/{{$json.total}}\nFamily: {{$json.malware_family}}",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "C0A252GLT70",
"cachedResultName": "all-team-sawi"
},
"otherOptions": {
"includeLinkToWorkflow": false
}
},
"credentials": {
"slackApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.4
},
{
"id": "9119e5d5-bc35-4e7d-9a2c-5006b7063cea",
"name": "IF - Malicious Verdict",
"type": "n8n-nodes-base.if",
"position": [
1296,
160
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "91bdc517-211b-4c07-a9ae-8cad6c6093f0",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.verdict ===\"Malicious\" }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.3
},
{
"id": "84b36197-ed3a-4d5a-8017-d237c2daf6fd",
"name": "Function - Calculate Verdict",
"type": "n8n-nodes-base.code",
"position": [
1088,
80
],
"parameters": {
"jsCode": "const stats = $json.data.attributes.last_analysis_stats;\n\nconst malicious = stats.malicious || 0;\nconst suspicious = stats.suspicious || 0;\nconst total = Object.values(stats).reduce((a, b) => a + b, 0);\n\nlet verdict = \"Clean\";\nif (malicious > 0) verdict = \"Malicious\";\nelse if (suspicious > 0) verdict = \"Suspicious\";\n\nreturn [{\n json: { \n hash: $json.data.id,\n verdict,\n malicious,\n suspicious,\n total,\n malware_family: $json.data.attributes.popular_threat_classification?.suggested_threat_label || \"N/A\"\n }\n}];\n"
},
"typeVersion": 2
},
{
"id": "189900ed-8e3d-4f24-87a2-284769506024",
"name": "Respond - Invalid Hash",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
656,
288
],
"parameters": {
"options": {},
"respondWith": "json",
"responseBody": "{\n \"status\": \"error\",\n \"message\": \"Invalid hash format. Provide MD5, SHA1, or SHA256.\"\n}\n"
},
"typeVersion": 1.5
},
{
"id": "cc43ad57-4842-48dc-959b-8185dcb16501",
"name": "HTTP - VirusTotal Hash Lookup",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueRegularOutput",
"position": [
656,
96
],
"parameters": {
"": "",
"url": "=https://www.virustotal.com/api/v3/files/{{ $json.hash }}",
"method": "GET",
"options": {},
"sendBody": false,
"sendQuery": false,
"curlImport": "",
"infoMessage": "",
"sendHeaders": true,
"authentication": "predefinedCredentialType",
"specifyHeaders": "keypair",
"headerParameters": {},
"httpVariantWarning": "",
"nodeCredentialType": "virusTotalApi",
"provideSslCertificates": false
},
"credentials": {
"virusTotalApi": {
"name": "<your credential>"
}
},
"typeVersion": 4.3,
"extendsCredential": "virusTotalApi"
},
{
"id": "d31682ad-58d9-49e3-9b49-ee1037cf97b5",
"name": "IF - Hash Exists in VT",
"type": "n8n-nodes-base.if",
"position": [
864,
176
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "b7a5c678-f4ef-4a15-b865-07fc9079c7dd",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{$json.error === undefined}}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.3
},
{
"id": "78006d40-ec95-4738-8356-1bc84ada73d0",
"name": "IF - Valid Hash Format",
"type": "n8n-nodes-base.if",
"position": [
416,
176
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "or",
"conditions": [
{
"id": "4bcd63f1-eed7-49f5-bb21-ce0153cec8c2",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.hash.length.toString() }}",
"rightValue": "=32"
},
{
"id": "7067a87e-6396-4174-b061-ffcf6adb16fb",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.hash.length.toString() }}",
"rightValue": "40"
},
{
"id": "165d9c7a-35a9-4958-92dc-7ff49e9d88fe",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.hash.length.toString() }}",
"rightValue": "64"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "35faaee9-f154-47bf-8fc0-9dbfe4a3d324",
"name": "Respond - Unknown Hash",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
1088,
288
],
"parameters": {
"options": {},
"respondWith": "json",
"responseBody": "={\n \n \"verdict\": \"Unknown\",\n \"message\": \"{{ $json.error.message }}\"\n} "
},
"typeVersion": 1.5
},
{
"id": "d93e59a7-750a-4e8f-8a5f-e28a4c8f4f32",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-80,
32
],
"parameters": {
"color": 7,
"width": 416,
"height": 432,
"content": "## 1. Webhook Input & Normalization\n"
},
"typeVersion": 1
},
{
"id": "9200acad-94ac-4906-bcff-8b6019b29216",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
352,
32
],
"parameters": {
"color": 7,
"height": 432,
"content": "## 2. Hash Validation\n"
},
"typeVersion": 1
},
{
"id": "b5644510-eb31-484c-b1ab-311c62c9c472",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
608,
32
],
"parameters": {
"color": 7,
"width": 400,
"height": 432,
"content": "## 3. VirusTotal Lookup\n"
},
"typeVersion": 1
},
{
"id": "b69d7f7a-c2d3-4000-ac97-97d8ff2f55b3",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1024,
32
],
"parameters": {
"color": 7,
"width": 416,
"height": 432,
"content": "## 4. Verdict Calculation\n"
},
"typeVersion": 1
},
{
"id": "b61abd46-d1c3-40b7-b7a5-19498391e414",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1456,
32
],
"parameters": {
"color": 7,
"width": 432,
"height": 432,
"content": "## 5. Alerts & Responses\n"
},
"typeVersion": 1
},
{
"id": "f074671e-f814-4ba9-a6d7-ea3d5a73f1c3",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-544,
-96
],
"parameters": {
"width": 432,
"height": 752,
"content": "## File Hash Reputation Checker\nThis is a security automation workflow that validates files hashes (**MD5**, **SHA1**, **SHA256**) and checks their reputation using the **VirusTotal API**. \n\nThe workflow accepts a file hash via an **HTTP webhook**, normalizes and validates the input, then queries VirusTotal to retrieve detection statistics. Based on the analysis results, it determines whether the file is **Malicious**, **Suspicious**, **Clean**, or **Unknown**.\n\n### How it works\n1. Receives a file hash via webhook **(POST)** or Slack using Slash command.\n2. Normalizes and validates hash format.\n3. Queries **VirusTotal** for hash reputation.\n4. Calculates verdict from detection stats.\n5. Sends Slack alert if **malicious**.\n6. Returns a **JSON** response with verdict and detections.\n\n### Setup steps\n1. Add your **VirusTotal API** key to n8n credentials.\n2. Configure **Slack API** credentials and channel.\n3. Activate the workflow.\n4. Send a **POST** request with `{ \"text\": \"<file_hash>\" }` or submit file hash directly from Slack using `/hash-check <file hash>`.\n\n### Customization\n- Adjust verdict thresholds in the verdict function.\n- Add additional notifications (email, SIEM, ticketing).\n- Extend to support file uploads or multiple hashes. "
},
"typeVersion": 1
},
{
"id": "f712dae4-6336-4250-b8af-884ab56f8b25",
"name": "Normalize Hash from Webhook",
"type": "n8n-nodes-base.set",
"position": [
176,
176
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "0f7b31e4-7305-4f80-93fb-663246db1063",
"name": "hash",
"type": "string",
"value": "={{ $json.body.text.toLowerCase().trim() }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "2f7ebeae-77e0-44b0-a4f2-7ca207474757",
"name": "Send a message",
"type": "n8n-nodes-base.slack",
"position": [
1728,
272
],
"parameters": {
"text": "={{\n $json.verdict === 'Suspicious'\n ? `\u26a0\ufe0f *SUSPICIOUS FILE*\nHash: ${$json.hash}\nDetections: ${$json.suspicious}/${$json.total}`\n\n : $json.verdict === 'Clean'\n ? `\u2705 *CLEAN FILE*\nHash: ${$json.hash}\nDetections: 0/${$json.total}`\n\n : `\u2139\ufe0f *UNKNOWN FILE*\nHash: ${$json.hash}\nNot found in VirusTotal`\n}}\n",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "C0A252GLT70",
"cachedResultName": "all-team-sawi"
},
"otherOptions": {
"includeLinkToWorkflow": false
}
},
"credentials": {
"slackApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.4
}
],
"active": true,
"settings": {
"timezone": "Asia/Manila",
"callerPolicy": "workflowsFromSameOwner",
"errorWorkflow": "o4jqXmki9xPDSHf4J09Ld",
"timeSavedMode": "fixed",
"availableInMCP": true,
"executionOrder": "v1",
"timeSavedPerExecution": 3
},
"versionId": "961b130f-a21f-49e2-9cb4-bce11931aee8",
"connections": {
"Receive File Hash": {
"main": [
[
{
"node": "Normalize Hash from Webhook",
"type": "main",
"index": 0
}
]
]
},
"IF - Hash Exists in VT": {
"main": [
[
{
"node": "Function - Calculate Verdict",
"type": "main",
"index": 0
}
],
[
{
"node": "Respond - Unknown Hash",
"type": "main",
"index": 0
}
]
]
},
"IF - Malicious Verdict": {
"main": [
[
{
"node": "Slack - Malicious Hash Alert",
"type": "main",
"index": 0
}
],
[
{
"node": "Respond - Clean or Unknown",
"type": "main",
"index": 0
}
]
]
},
"IF - Valid Hash Format": {
"main": [
[
{
"node": "HTTP - VirusTotal Hash Lookup",
"type": "main",
"index": 0
}
],
[
{
"node": "Respond - Invalid Hash",
"type": "main",
"index": 0
}
]
]
},
"Respond - Clean or Unknown": {
"main": [
[
{
"node": "Send a message",
"type": "main",
"index": 0
}
]
]
},
"Normalize Hash from Webhook": {
"main": [
[
{
"node": "IF - Valid Hash Format",
"type": "main",
"index": 0
}
]
]
},
"Function - Calculate Verdict": {
"main": [
[
{
"node": "IF - Malicious Verdict",
"type": "main",
"index": 0
}
]
]
},
"HTTP - VirusTotal Hash Lookup": {
"main": [
[
{
"node": "IF - Hash Exists in VT",
"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.
slackApivirusTotalApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
File Hash Reputation Checker is a security automation workflow that validates file hashes (MD5, SHA1, SHA256) and checks their reputation using the VirusTotal API. It is designed for SOC teams, security engineers, and automation pipelines that need fast and consistent malware…
Source: https://n8n.io/workflows/13229/ — 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.
🛡️ Jamf Policy Integrity Monitor
Notify_user_in_Slack_of_quarantined_email_and_create_Jira_ticket_if_opened. Uses httpRequest, jira, stickyNote, slack. Webhook trigger; 13 nodes.
This n8n workflow serves as an incident response and notification system for handling potentially malicious emails flagged by Sublime Security. It begins with a Webhook trigger that Sublime Security u
This workflow is built for n8n admins, automation agencies, solopreneurs, and ops teams running multiple workflows in production who need to know the moment something breaks.
This workflow solves the problem of manually copying line items from one deal to another in HubSpot, reducing manual work and minimizing errors. Triggers upon receiving a webhook with deal IDs. Retrie