AutomationFlowsWeb Scraping › Elevenlabs Post Call Webhook

Elevenlabs Post Call Webhook

elevenlabs_post_call_webhook. Uses crypto, httpRequest. Webhook trigger; 17 nodes.

Webhook trigger★★★★☆ complexity17 nodesCryptoHTTP Request
Web Scraping Trigger: Webhook Nodes: 17 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": "elevenlabs_post_call_webhook",
  "description": null,
  "active": true,
  "nodes": [
    {
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        0,
        0
      ],
      "parameters": {
        "httpMethod": "POST",
        "path": "elevenlabs/post-call",
        "responseMode": "responseNode",
        "options": {
          "rawBody": true
        }
      },
      "id": "ce3232fa-39dc-4f31-9832-e24e467c2661"
    },
    {
      "name": "Parse Signature",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        220,
        0
      ],
      "parameters": {
        "language": "javaScript",
        "jsCode": "// Extract t and v0 from the ElevenLabs-Signature header.\n// Build signing_string = \"${t}.${rawBody}\" \u2014 the input the Crypto node hashes.\n// No 'crypto' dependency here; n8n's sandbox blocks it.\nconst item = $input.first();\nconst headers = item.json.headers || {};\nconst sigHeader = headers['elevenlabs-signature'] || headers['ElevenLabs-Signature'] || '';\nconst rawBody = item.json.rawBody || (typeof item.json.body === 'string' ? item.json.body : JSON.stringify(item.json.body || item.json));\nconst parts = sigHeader.split(',').reduce((acc, p) => { const [k, v] = p.split('='); acc[k] = v; return acc; }, {});\nconst t = parts.t || '';\nconst v0 = parts.v0 || '';\nconst ageSeconds = t ? Math.abs(Math.floor(Date.now()/1000) - parseInt(t, 10)) : 999999;\nconst payload = typeof item.json.body === 'string' ? JSON.parse(item.json.body) : (item.json.body || item.json);\nreturn [{json: {\n  signing_string: t + '.' + rawBody,\n  t,\n  v0_received: v0,\n  age_seconds: ageSeconds,\n  signature_present: Boolean(t && v0),\n  payload,\n  event_type: payload.type || 'unknown',\n  received_at: new Date().toISOString()\n}}];"
      },
      "id": "d41b05ca-b3fb-4fd8-9903-c82cd3643b52"
    },
    {
      "name": "HMAC Compute",
      "type": "n8n-nodes-base.crypto",
      "typeVersion": 1,
      "position": [
        440,
        0
      ],
      "parameters": {
        "action": "hmac",
        "type": "SHA256",
        "value": "={{$json.signing_string}}",
        "secret": "<REDACTED:elevenlabs-webhook-secret>",
        "encoding": "hex",
        "dataPropertyName": "v0_computed"
      },
      "id": "1ec47101-9aba-4cbf-ac1e-36eb029aed7e"
    },
    {
      "name": "Verify Signature",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        660,
        0
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "sig-eq",
              "leftValue": "={{$json.v0_computed}}",
              "rightValue": "={{$json.v0_received}}",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            },
            {
              "id": "sig-fresh",
              "leftValue": "={{$json.age_seconds}}",
              "rightValue": 1800,
              "operator": {
                "type": "number",
                "operation": "lt"
              }
            }
          ],
          "combinator": "and"
        }
      },
      "id": "5c471f00-1071-416e-986e-5a468875e4c7"
    },
    {
      "name": "Route by Event Type",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3,
      "position": [
        880,
        -160
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {},
                "conditions": [
                  {
                    "id": "r-tr",
                    "leftValue": "={{$json.event_type}}",
                    "rightValue": "post_call_transcription",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "outputKey": "transcription",
              "renameOutput": true
            },
            {
              "conditions": {
                "options": {},
                "conditions": [
                  {
                    "id": "r-au",
                    "leftValue": "={{$json.event_type}}",
                    "rightValue": "post_call_audio",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "outputKey": "audio",
              "renameOutput": true
            },
            {
              "conditions": {
                "options": {},
                "conditions": [
                  {
                    "id": "r-fa",
                    "leftValue": "={{$json.event_type}}",
                    "rightValue": "call_initiation_failure",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "outputKey": "failure",
              "renameOutput": true
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra"
        }
      },
      "id": "9e4cf3db-1005-42ca-8c29-8c476380b1a2"
    },
    {
      "name": "Format Transcription",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1120,
        -320
      ],
      "parameters": {
        "language": "javaScript",
        "jsCode": "// Extract the structured fields from a post_call_transcription payload.\nconst item = $input.first().json;\nconst data = item.payload?.data || {};\nreturn [{json: {\n  event: 'post_call_transcription',\n  conversation_id: data.conversation_id,\n  agent_id: data.agent_id,\n  agent_name: data.agent_name,\n  status: data.status,\n  call_duration_secs: data.metadata?.call_duration_secs,\n  caller_id: data.metadata?.caller_id,\n  called_number: data.metadata?.called_number,\n  phone_provider: data.metadata?.phone_provider,\n  transcript_turns: (data.transcript || []).length,\n  summary: data.analysis?.summary,\n  evaluation_results: data.analysis?.evaluation_results || {},\n  data_collection: data.analysis?.data_collection || {},\n  has_audio: data.has_audio,\n  raw: item.payload\n}}];"
      },
      "id": "f412cba8-40a1-4bca-bf70-6382ae7eadaf"
    },
    {
      "name": "Format Audio",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1120,
        -160
      ],
      "parameters": {
        "language": "javaScript",
        "jsCode": "// Extract metadata from a post_call_audio payload. The base64-encoded audio\n// lives in payload.data.full_audio \u2014 large, may exceed n8n's default item\n// size limits. Keep only the metadata in the structured output; pass the raw\n// payload through to downstream sinks that handle binary.\nconst item = $input.first().json;\nconst data = item.payload?.data || {};\nreturn [{json: {\n  event: 'post_call_audio',\n  conversation_id: data.conversation_id,\n  agent_id: data.agent_id,\n  audio_bytes: data.full_audio ? Buffer.from(data.full_audio, 'base64').length : 0,\n  audio_base64_length: data.full_audio?.length || 0,\n  raw: item.payload\n}}];"
      },
      "id": "e4b1c7ee-cf80-4eb0-b298-4fcfbaa8521d"
    },
    {
      "name": "Format Failure",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1120,
        0
      ],
      "parameters": {
        "language": "javaScript",
        "jsCode": "// Extract failure detail from a call_initiation_failure payload \u2014 alert-worthy.\nconst item = $input.first().json;\nconst data = item.payload?.data || {};\nconst body = data.metadata?.body || {};\nreturn [{json: {\n  event: 'call_initiation_failure',\n  alert_severity: 'high',\n  conversation_id: data.conversation_id,\n  agent_id: data.agent_id,\n  failure_reason: data.failure_reason,\n  provider: data.metadata?.type,\n  from_number: body.from_number,\n  to_number: body.to_number,\n  sip_status_code: body.sip_status_code,\n  error_reason: body.error_reason,\n  call_sid: body.call_sid,\n  raw: item.payload\n}}];"
      },
      "id": "575ab6e7-694b-487a-93b8-640554a64f71"
    },
    {
      "name": "Format Unknown",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1120,
        160
      ],
      "parameters": {
        "language": "javaScript",
        "jsCode": "// Catch-all for unknown event types \u2014 log but do not alarm.\nconst item = $input.first().json;\nreturn [{json: {\n  event: 'unknown_event_type',\n  declared_type: item.event_type,\n  payload_keys: Object.keys(item.payload || {}),\n  raw: item.payload\n}}];"
      },
      "id": "86920ab7-eccc-4073-bb44-361ce899a846"
    },
    {
      "name": "Has Ingest URL?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        1340,
        -320
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true
          },
          "conditions": [
            {
              "id": "has-ing",
              "leftValue": "",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              }
            }
          ],
          "combinator": "and"
        }
      },
      "id": "bac4d4d7-ba9a-4486-912e-d761807cb287"
    },
    {
      "name": "POST Ingest",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        1560,
        -360
      ],
      "parameters": {
        "method": "POST",
        "url": "http://localhost/elevenlabs-ingest",
        "sendBody": true,
        "contentType": "json",
        "jsonBody": "={{ JSON.stringify($json) }}",
        "options": {
          "timeout": 5000,
          "response": {
            "response": {
              "neverError": true
            }
          }
        }
      },
      "id": "d05e5f59-e618-4d7c-b230-f0478082214d"
    },
    {
      "name": "Has Audio Sink URL?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        1340,
        -160
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true
          },
          "conditions": [
            {
              "id": "has-asu",
              "leftValue": "",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              }
            }
          ],
          "combinator": "and"
        }
      },
      "id": "7cf25365-a235-41f3-992b-ecf2ed910c2a"
    },
    {
      "name": "POST Audio Sink",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        1560,
        -200
      ],
      "parameters": {
        "method": "POST",
        "url": "http://localhost/elevenlabs-audio",
        "sendBody": true,
        "contentType": "json",
        "jsonBody": "={{ JSON.stringify($json) }}",
        "options": {
          "timeout": 10000,
          "response": {
            "response": {
              "neverError": true
            }
          }
        }
      },
      "id": "1d39d9d6-131c-4d70-bd7a-4d164a6cc7b8"
    },
    {
      "name": "Has Alert URL?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        1340,
        0
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true
          },
          "conditions": [
            {
              "id": "has-alert",
              "leftValue": "",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              }
            }
          ],
          "combinator": "and"
        }
      },
      "id": "1b3babb7-9610-425f-8ba2-05b2cd7c88c9"
    },
    {
      "name": "POST Alert",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        1560,
        -40
      ],
      "parameters": {
        "method": "POST",
        "url": "http://localhost/elevenlabs-alert",
        "sendBody": true,
        "contentType": "json",
        "jsonBody": "={{ JSON.stringify($json) }}",
        "options": {
          "timeout": 5000,
          "response": {
            "response": {
              "neverError": true
            }
          }
        }
      },
      "id": "8bf57dde-d036-4950-9da9-91b9ec1acf03"
    },
    {
      "name": "Respond 200",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        1800,
        -120
      ],
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({status: 'ok', event: $json.event || $json.event_type || 'unknown', conversation_id: $json.conversation_id}) }}",
        "options": {
          "responseCode": 200
        }
      },
      "id": "313e67b2-a039-448f-8ade-cb1c0afa0d7c"
    },
    {
      "name": "Respond 401",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        880,
        160
      ],
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({status: 'rejected', reason: 'signature_invalid_or_stale'}) }}",
        "options": {
          "responseCode": 401
        }
      },
      "id": "48c58c55-3c57-4d44-a698-7a8d8d65d72f"
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Parse Signature",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Signature": {
      "main": [
        [
          {
            "node": "HMAC Compute",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HMAC Compute": {
      "main": [
        [
          {
            "node": "Verify Signature",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Verify Signature": {
      "main": [
        [
          {
            "node": "Route by Event Type",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Respond 401",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route by Event Type": {
      "main": [
        [
          {
            "node": "Format Transcription",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Format Audio",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Format Failure",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Format Unknown",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Transcription": {
      "main": [
        [
          {
            "node": "Has Ingest URL?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has Ingest URL?": {
      "main": [
        [
          {
            "node": "POST Ingest",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Respond 200",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "POST Ingest": {
      "main": [
        [
          {
            "node": "Respond 200",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Audio": {
      "main": [
        [
          {
            "node": "Has Audio Sink URL?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has Audio Sink URL?": {
      "main": [
        [
          {
            "node": "POST Audio Sink",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Respond 200",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "POST Audio Sink": {
      "main": [
        [
          {
            "node": "Respond 200",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Failure": {
      "main": [
        [
          {
            "node": "Has Alert URL?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has Alert URL?": {
      "main": [
        [
          {
            "node": "POST Alert",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Respond 200",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "POST Alert": {
      "main": [
        [
          {
            "node": "Respond 200",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Unknown": {
      "main": [
        [
          {
            "node": "Respond 200",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "callerPolicy": "workflowsFromSameOwner",
    "availableInMCP": false
  },
  "tags": []
}
Pro

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

About this workflow

elevenlabs_post_call_webhook. Uses crypto, httpRequest. Webhook trigger; 17 nodes.

Source: https://github.com/wranngle/n8n_showcase/blob/main/workflows/elevenlabs/post-call-webhook.json — original creator credit. Request a take-down →

More Web Scraping workflows → · Browse all categories →

Related workflows

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

Web Scraping

elevenlabs_webhook_listener. Uses httpRequest, pipedrive, crypto. Webhook trigger; 35 nodes.

HTTP Request, Pipedrive, Crypto
Web Scraping

Community Node Disclaimer: This workflow uses KlickTipp community nodes.

Crypto, Custom, N8N Nodes Klicktipp +1
Web Scraping

Community Node Disclaimer: This workflow uses KlickTipp community nodes.

Crypto, Custom, HTTP Request +1
Web Scraping

Struggling with inaccurate Meta Ads tracking due to iOS 14+ and ad blockers? 📉 This workflow is your solution. It provides a robust, server-side endpoint to reliably send conversion events directly to

Crypto, HTTP Request
Web Scraping

VenueDesk - User Manager (Final Database Fix). Uses httpRequest, crypto. Webhook trigger; 13 nodes.

HTTP Request, Crypto