The webhook url doesn't have a connector and it's only triggering by itself without connecting to other nodes
No error message visible on n8n, however on my n8n logs;
captyn_n8n | Initializing n8n process
captyn_n8n | n8n ready on 0.0.0.0, port 5678
captyn_n8n | n8n Task Broker ready on 127.0.0.1, port 5679
captyn_n8n | Failed to start Python task runner in internal mode. because Python 3 is missing from this system. Launching a Python runner in internal mode is intended only for debugging and is not recommended for production. Users are encouraged to deploy in external mode. See: https://docs.n8n.io/hosting/configuration/task-runners/#setting-up-external-mode
captyn_n8n | [license SDK] Skipping renewal on init: license cert is not initialized
captyn_n8n | Registered runner "JS Task Runner" (YVKHHyUL4TXyV89SPlJ85)
captyn_n8n | Version: 2.2.4
captyn_n8n |
captyn_n8n | Editor is now accessible via:
captyn_n8n | https://n8n.captyn.shop
captyn_n8n | (node:7) [DEP0060] DeprecationWarning: The util._extend API is deprecated. Please use Object.assign() instead.
captyn_n8n | (Use node --trace-deprecation ... to show where the warning was created)
captyn_n8n | User attempted to access a workflow without permissions
captyn_n8n | User attempted to access a workflow without permissions
captyn_n8n | User attempted to access a workflow without permissions
captyn_n8n | User attempted to access a workflow without permissions
(Select the nodes on your canvas and use the keyboard shortcuts CMD+C/CTRL+C and CMD+V/CTRL+V to copy and paste the workflow.)
⚠️ WARNING ⚠️ If you have sensitive data in your workflow (like API keys), please remove it before sharing.
```{
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "verify-email",
"options": {}
},
"name": "Email Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [
48,
-160
],
"webhookId": "email-verification-webhook",
"id": "aaf5cfa4-1bf3-4ff6-90b7-45efbfdda569"
},
{
"parameters": {
"conditions": {
"string": [
{
"value1": "={{$json[\"body\"]?.to || $json[\"to\"]}}",
"operation": "isNotEmpty"
},
{
"value1": "={{$json[\"body\"]?.verificationCode || $json[\"verificationCode\"]}}",
"operation": "isNotEmpty"
},
{
"value1": "={{$json[\"body\"]?.type || $json[\"type\"]}}",
"value2": "email_verification"
}
]
}
},
"name": "Validate Input",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
64,
48
],
"id": "1e5ba7de-aa9d-481d-9baf-965cb17ddce1"
},
{
"parameters": {
"functionCode": "const data = items[0].json;\n\n// Safely extract fields\nconst toAddress = data.to || (data.body && data.body.to) || null;\nif (!toAddress) {\n throw new Error('Email address (to) is required');\n}\n\n// Safely extract 'name' for personalization\nconst userName = data.name || (data.body && data.body.name) || toAddress.split('@')[0];\n\n// Use the verification code sent from backend\nconst verificationCode = data.verificationCode || (data.body && data.body.verificationCode) || null;\nif (!verificationCode) {\n throw new Error('Verification code is required');\n}\n\nconst enhancedData = {\n ...data,\n to: toAddress,\n name: userName,\n verificationCode,\n timestamp: new Date().toISOString(),\n expiresAt: new Date(Date.now() + 900000).toISOString() // 15 minutes\n};\n\nreturn [{ json: enhancedData }];"
},
"name": "Prepare Data",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
384,
32
],
"id": "fc022789-aff6-4021-b313-c0275dacb321"
},
{
"parameters": {
"functionCode": "const data = items[0].json;\n\nconst name = data.name || data.to || 'there';\nconst verificationCode = data.verificationCode;\nconst to = data.to;\n\nconst emailBody = `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>Email Verification</title>\n <style>\n body {\n font-family: Arial, sans-serif;\n line-height: 1.6;\n color: #333333;\n max-width: 600px;\n margin: 0 auto;\n padding: 20px;\n background-color: #f9f9f9;\n }\n .header {\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n padding: 30px;\n text-align: center;\n border-radius: 10px 10px 0 0;\n }\n .content {\n background: white;\n padding: 30px;\n border-radius: 0 0 10px 10px;\n box-shadow: 0 0 5px rgba(0,0,0,0.1);\n }\n .verification-code {\n background: #f8f9fa;\n border: 2px solid #667eea;\n border-radius: 8px;\n padding: 20px;\n margin: 20px 0;\n text-align: center;\n font-family: 'Courier New', monospace;\n font-size: 24px;\n font-weight: bold;\n color: #667eea;\n letter-spacing: 3px;\n }\n .footer {\n text-align: center;\n margin-top: 30px;\n color: #666666;\n font-size: 14px;\n }\n </style>\n</head>\n<body>\n <div class=\"header\">\n <h1>🚀 Welcome to CAPTYN GLOBAL!</h1>\n </div>\n <div class=\"content\">\n <h2>Hi ${name}! 👋</h2>\n <p>Thank you for joining CAPTYN GLOBAL! We're excited to have you on board.</p>\n <p>To complete your registration, please verify your email address using the 6-digit code below:</p>\n <div class=\"verification-code\">${verificationCode}</div>\n <p>Enter this code on the verification page to complete your account setup.</p>\n <p><strong>Important:</strong> This verification code will expire in 15 minutes.</p>\n <p>If you didn't create an account with us, please ignore this email.</p>\n </div>\n <div class=\"footer\">\n <p>Best regards,<br>The CAPTYN GLOBAL Team</p>\n <p>🌐 <a href=\"https://captyn.shop\" target=\"_blank\" style=\"color:#667eea;\">captyn.shop</a> | 📧 [email protected]</p>\n </div>\n</body>\n</html>`;\n\nconst subject = 'Verify your email address - CAPTYN GLOBAL';\n\nreturn [{ json: { ...data, subject, emailBody, to } }];\n"
},
"name": "Build Email",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
992,
16
],
"id": "cf4398e1-9510-4856-8ded-cad791204055"
},
{
"parameters": {
"fromEmail": "[email protected]",
"toEmail": "={{$json[\"to\"]}}",
"subject": "={{$json[\"subject\"]}}",
"html": "={{$json[\"emailBody\"]}}",
"options": {}
},
"name": "Send Email",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 1,
"position": [
992,
336
],
"id": "609fd5ec-d032-4a87-845f-f0fcd3928f98",
"credentials": {
"smtp": {
"id": "EAqXVT9dbPiRB310",
"name": "SMTP account"
}
}
}
],
"connections": {
"Validate Input": {
"main": [
[
{
"node": "Prepare Data",
"type": "main",
"index": 0
}
]
]
},
"Prepare Data": {
"main": [
[
{
"node": "Build Email",
"type": "main",
"index": 0
}
]
]
},
"Build Email": {
"main": [
[
{
"node": "Send Email",
"type": "main",
"index": 0
}
]
]
},
"Send Email": {
"main": [
[]
]
}
},
"pinData": {},
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "5385f97c04254559b129f4e9ecb07e38e9a33ab251f5c0d0136e2b1ff05722a5"
}
}
## Share the output returned by the last node
<!-- If you need help with data transformations, please also share your expected output. -->
it just triggers the first node.
## Debug info
### core
- n8nVersion: 2.2.4
- platform: docker (self-hosted)
- nodeJsVersion: 22.21.1
- nodeEnv: production
- database: sqlite
- executionMode: regular
- concurrency: -1
- license: community
### storage
- success: all
- error: all
- progress: false
- manual: true
- binaryMode: filesystem
### pruning
- enabled: true
- maxAge: 336 hours
- maxCount: 10000 executions
### client
- userAgent: mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/143.0.0.0 safari/537.36
- isTouchDevice: false
Generated at: 2026-01-10T18:11:22.928Z}