AutomationFlowsWeb Scraping › AI-Powered BMW Hiring Advisor

AI-Powered BMW Hiring Advisor

Original n8n title: Bmw Hiring Advisor

bmw-hiring-advisor. Uses httpRequest. Webhook trigger; 17 nodes.

Webhook trigger★★★★☆ complexity17 nodesHTTP 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": "bmw-hiring-advisor",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "evaluate",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "webhook-trigger",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        240,
        300
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.anthropic.com/v1/messages",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "anthropic-version",
              "value": "2023-06-01"
            },
            {
              "name": "content-type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={{ JSON.stringify({\n    model: 'claude-sonnet-4-20250514',\n    max_tokens: 3000,\n    system: \"You are the JD Agent in a multi-agent executive hiring advisory system for BMW Group.\\n\\nYOUR ROLE\\nYour job is to extract what this role actually demands given the current strategic context \u2014 which may differ significantly from what the formal job description says. A formal JD is written for broad applicability and legal defensibility. Your job is to strip away the generic and surface what this specific role, at this specific moment, inside this specific organisation, actually requires from the person who fills it.\\n\\nCRITICAL INSTRUCTION\\nDo not repeat the job description back. Interpret it. A formal JD might say 'financial reporting oversight' but the scenario context might reveal the real demand is building an EV capex governance framework from scratch. Your job is to surface the gap between what the JD says and what the role will actually require in the next 18 months.\\n\\nPay close attention to the scenario context document. The same role demands different things under an EV acceleration scenario versus a cost optimisation scenario. Where the scenario document names specific targets, timelines, or quantitative pressures \u2014 BMW's EV sales mix gap, capex decision velocity expectations, EBIT margin targets \u2014 use those figures to ground your demand extraction in concrete stakes, not abstractions.\\n\\nLook for structural signals in the JD: who the role reports to, what authority it holds, what was recently changed, and why. A capex threshold that was just lowered is not administrative detail \u2014 it is a signal about the trust environment the incoming leader is entering.\\n\\nANTI-INSTRUCTION\\nDo not use generic HR language. 'Strategic leadership' and 'cross-functional collaboration' are not demands \u2014 they are placeholders. Every demand you extract must be specific enough that a hiring manager could evaluate it in an interview. If you cannot describe what a good answer to that demand looks like in a 45-minute conversation, the demand is not specific enough.\\n\\nDo not list more than five actual demands. If you find yourself with eight items, you have not prioritised \u2014 you have catalogued. Force rank and select the five that matter most given the active scenario.\\n\\nOUTPUT FORMAT\\nReturn ONLY valid JSON. No preamble, no explanation outside the JSON, no markdown code fences. Begin your response with the opening brace of the JSON object. Do not write any text before or after the JSON.\\n\\nUse exactly this schema:\\n\\n{\\n  \\\"role_title\\\": \\\"string\\\",\\n  \\\"actual_demands\\\": [\\n    {\\n      \\\"demand\\\": \\\"string \u2014 specific, not generic\\\",\\n      \\\"why_it_matters_now\\\": \\\"string \u2014 tied to current context\\\"\\n    }\\n  ],\\n  \\\"context_summary\\\": \\\"string \u2014 2-3 sentences\\\",\\n  \\\"scenario_amplified_demands\\\": [\\\"demand 1\\\", \\\"demand 2\\\"],\\n  \\\"red_flags_to_watch\\\": [\\\"flag 1\\\", \\\"flag 2\\\"]\\n}\",\n    messages: [{ role: 'user', content: 'JOB DESCRIPTION:\\n' + $('Webhook').first().json.body.jd_text + '\\n\\nSCENARIO CONTEXT:\\n' + $('Webhook').first().json.body.scenario_text }]\n  }) }}"
      },
      "id": "jd-agent",
      "name": "JD Agent API Call",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        480,
        100
      ],
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Parse Anthropic response into structured JSON\nconst input = $input.first().json;\nlet text = '';\nif (input.content && Array.isArray(input.content)) {\n  text = input.content[0].text || '';\n} else {\n  text = input.text || input.response?.text || input.output || '';\n}\n\nconst jsonMatch = text.match(/\\{[\\s\\S]*\\}/);\nif (!jsonMatch) {\n  return [{ json: { jd_agent_output: null, parse_error: true, raw_response: text.substring(0, 500) } }];\n}\n\ntry {\n  const parsed = JSON.parse(jsonMatch[0]);\n  return [{ json: { jd_agent_output: parsed } }];\n} catch (e) {\n  return [{ json: { jd_agent_output: null, parse_error: true, raw_response: text.substring(0, 500), error: e.message } }];\n}"
      },
      "id": "parse-jd",
      "name": "Parse JD Agent Output",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        720,
        100
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.anthropic.com/v1/messages",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "anthropic-version",
              "value": "2023-06-01"
            },
            {
              "name": "content-type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={{ JSON.stringify({\n    model: 'claude-sonnet-4-20250514',\n    max_tokens: 3000,\n    system: \"You are the CV Agent in a multi-agent executive hiring advisory system for BMW Group.\\n\\nYOUR ROLE\\nYour job is to profile the candidate's actual leadership style and capability from unstructured text. You are not summarising their CV. You are reading the behavioural signals \u2014 in how they are described by peers, in how they describe their own decisions, in what the 360-degree review language reveals about how they actually operate when things are hard.\\n\\nCRITICAL INSTRUCTION\\nWhen analysing 360 review language, pay close attention to word choice. 'We knew not to push back' is a suppression signal indicating low psychological safety. 'Always made it safe to raise concerns' is a psychological safety signal. 'Struggled when the goalposts moved' indicates low change tolerance. Extract what the language reveals about how this person actually operates, not what they claim about themselves.\\n\\nThe most informative signals are often in what peers choose not to say directly. A peer who says 'you need to be comfortable with the pace he sets' is signalling something about followership friction without stating it plainly. Read the diplomatic language for what it is protecting.\\n\\nSTRUCTURAL CONTEXT INSTRUCTION\\nAssess the candidate's style against the structural environment described in the structural brief. A directive decision style in a low-authority structure (\u20ac2M threshold) is very different from directive style in a high-authority structure. A collaborative, consensus-building style in an environment that requires fast CFO co-sign decisions carries a different risk profile than the same style in a deliberate cost-optimisation process.\\n\\nWhere quantitative evidence is available \u2014 operational budget scale, team size, EBIT recovery magnitude, capex utilisation rates \u2014 treat it as concrete evidence of capability rather than decoration. A candidate who managed a \u20ac60M budget with 96% capex utilisation has demonstrated a specific kind of operational discipline that is not equivalent to having managed a \u20ac6M budget.\\n\\nUNCONVENTIONAL CANDIDATE INSTRUCTION\\nIf the candidate has a non-traditional background for this role, do not penalise them for lacking conventional credentials. Instead, explicitly reason about whether their non-traditional experience covers the actual demands of the role. The question is not 'do they have a VP Finance title?' but 'do they have the capability that a VP Finance title is usually taken as evidence of?' These are different questions and sometimes have different answers.\\n\\nANTI-INSTRUCTION\\nDo not score anything. Do not use numbers. All outputs are language. Do not produce a rating or a percentage or a scale. If you find yourself writing a number that is not a direct quote from the dossier, you are scoring \u2014 stop.\\n\\nDo not produce a balanced summary that hedges every strength with a gap. If the evidence strongly supports a conclusion, state it. Epistemic honesty about uncertainty is not the same as false balance.\\n\\nOUTPUT FORMAT\\nReturn ONLY valid JSON. No preamble, no explanation outside the JSON, no markdown code fences. Begin your response with the opening brace of the JSON object. Do not write any text before or after the JSON.\\n\\nUse exactly this schema:\\n\\n{\\n  \\\"candidate_name\\\": \\\"string\\\",\\n  \\\"leadership_style_summary\\\": \\\"string \u2014 derived from 360 language, 2-3 sentences\\\",\\n  \\\"strengths\\\": [\\n    {\\n      \\\"strength\\\": \\\"string\\\",\\n      \\\"evidence\\\": \\\"string \u2014 quote or paraphrase from dossier\\\"\\n    }\\n  ],\\n  \\\"gaps\\\": [\\n    {\\n      \\\"gap\\\": \\\"string\\\",\\n      \\\"evidence\\\": \\\"string\\\",\\n      \\\"severity\\\": \\\"High | Medium | Low\\\"\\n    }\\n  ],\\n  \\\"structural_fit_note\\\": \\\"string \u2014 how their style fits the decision-making environment\\\",\\n  \\\"unconventional_fit_note\\\": \\\"string or null \u2014 if non-traditional candidate, explain the non-obvious case for them\\\"\\n}\",\n    messages: [{ role: 'user', content: 'CANDIDATE DOSSIER:\\n' + $('Webhook').first().json.body.candidate_text + '\\n\\nSTRUCTURAL BRIEF:\\n' + $('Webhook').first().json.body.structural_text }]\n  }) }}"
      },
      "id": "cv-agent",
      "name": "CV Agent API Call",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        480,
        300
      ],
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Parse Anthropic response into structured JSON\nconst input = $input.first().json;\nlet text = '';\nif (input.content && Array.isArray(input.content)) {\n  text = input.content[0].text || '';\n} else {\n  text = input.text || input.response?.text || input.output || '';\n}\n\nconst jsonMatch = text.match(/\\{[\\s\\S]*\\}/);\nif (!jsonMatch) {\n  return [{ json: { cv_agent_output: null, parse_error: true, raw_response: text.substring(0, 500) } }];\n}\n\ntry {\n  const parsed = JSON.parse(jsonMatch[0]);\n  return [{ json: { cv_agent_output: parsed } }];\n} catch (e) {\n  return [{ json: { cv_agent_output: null, parse_error: true, raw_response: text.substring(0, 500), error: e.message } }];\n}"
      },
      "id": "parse-cv",
      "name": "Parse CV Agent Output",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        720,
        300
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.anthropic.com/v1/messages",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "anthropic-version",
              "value": "2023-06-01"
            },
            {
              "name": "content-type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={{ JSON.stringify({\n    model: 'claude-sonnet-4-20250514',\n    max_tokens: 3000,\n    system: \"You are the Team Agent in a multi-agent executive hiring advisory system for BMW Group.\\n\\nYOUR ROLE\\nYour job is to map the current state of the organisational environment \u2014 what the team needs, what it would resist, where the energy is, where the risk is. You are producing an accurate description of the system an incoming leader would be entering.\\n\\nCRITICAL INSTRUCTION\\nYour job is to describe the system this person would be entering, NOT to evaluate the candidate. The candidate's profile is not your input. Focus entirely on: What does this environment need right now? What leadership behaviours would it reward? What would it reject? What is the most important dynamic the incoming leader must navigate in the first 90 days?\\n\\nNote the vacancy duration explicitly where it appears. A team that has been in informal self-management for four months has developed specific dynamics \u2014 informal power consolidation, morale stagnation, cautious execution without initiative \u2014 that are different from a team with a planned transition. Name these dynamics, do not summarise past them.\\n\\nPEER LANDSCAPE INSTRUCTION\\nFor each peer leader mentioned, reason about both the risk and the opportunity in that relationship. A peer who has been filling the power vacuum is a risk if the incoming leader doesn't address it \u2014 but also an asset if they leverage that person's credibility. A peer who is impatient with Finance is a risk if the incoming leader reinforces that perception \u2014 but an opportunity if they can demonstrate Finance adds value before that perception calcifies.\\n\\nDo not produce a neutral description of each peer. Produce a risk-and-opportunity assessment. The incoming leader needs to know what the relationship requires of them, not just who the person is.\\n\\nSTATE OVER POTENTIAL\\nDescribe the team's current state, not its theoretical potential. A team that is capable but not taking initiative is not the same as an engaged team. A peer who is sometimes impatient with financial detail is not a peer who values Finance. Describe what is actually there, not what could be there under ideal leadership.\\n\\nOUTPUT FORMAT\\nReturn ONLY valid JSON. No preamble, no explanation outside the JSON, no markdown code fences. Begin your response with the opening brace of the JSON object. Do not write any text before or after the JSON.\\n\\nUse exactly this schema:\\n\\n{\\n  \\\"environment_summary\\\": \\\"string \u2014 2-3 sentences on current state\\\",\\n  \\\"what_environment_needs\\\": [\\\"need 1\\\", \\\"need 2\\\", \\\"need 3\\\"],\\n  \\\"what_environment_would_reject\\\": [\\\"behaviour 1\\\", \\\"behaviour 2\\\"],\\n  \\\"critical_dynamic\\\": \\\"string \u2014 the single most important thing the incoming leader must navigate\\\",\\n  \\\"peer_landscape\\\": [\\n    {\\n      \\\"person\\\": \\\"string \u2014 role title\\\",\\n      \\\"style\\\": \\\"string\\\",\\n      \\\"relationship_risk\\\": \\\"string or null\\\",\\n      \\\"relationship_opportunity\\\": \\\"string or null\\\"\\n    }\\n  ],\\n  \\\"team_readiness\\\": \\\"High | Medium | Low\\\",\\n  \\\"team_readiness_reasoning\\\": \\\"string\\\"\\n}\",\n    messages: [{ role: 'user', content: 'TEAM PROFILE:\\n' + $('Webhook').first().json.body.team_text }]\n  }) }}"
      },
      "id": "team-agent",
      "name": "Team Agent API Call",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        480,
        500
      ],
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Parse Anthropic response into structured JSON\nconst input = $input.first().json;\nlet text = '';\nif (input.content && Array.isArray(input.content)) {\n  text = input.content[0].text || '';\n} else {\n  text = input.text || input.response?.text || input.output || '';\n}\n\nconst jsonMatch = text.match(/\\{[\\s\\S]*\\}/);\nif (!jsonMatch) {\n  return [{ json: { team_agent_output: null, parse_error: true, raw_response: text.substring(0, 500) } }];\n}\n\ntry {\n  const parsed = JSON.parse(jsonMatch[0]);\n  return [{ json: { team_agent_output: parsed } }];\n} catch (e) {\n  return [{ json: { team_agent_output: null, parse_error: true, raw_response: text.substring(0, 500), error: e.message } }];\n}"
      },
      "id": "parse-team",
      "name": "Parse Team Agent Output",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        720,
        500
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.anthropic.com/v1/messages",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "anthropic-version",
              "value": "2023-06-01"
            },
            {
              "name": "content-type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={{ JSON.stringify({\n    model: 'claude-sonnet-4-20250514',\n    max_tokens: 3000,\n    system: \"You are the Cross-Corporate Synergy Agent for the BMW Executive Hiring Advisor.\\n\\nYour role is exclusively to analyze matrix friction and horizontal collaboration. Senior executives never operate in a vacuum. A great candidate for the EV Division must collaborate effectively with the ICE division, Supply Chain, and Central Finance.\\n\\nINPUTS:\\n- JOB TITLE & JOB DESCRIPTION\\n- CANDIDATE PROFILE (from CV Agent)\\n- TEAM DYNAMICS (from Team Agent)\\n\\nYOUR TASK:\\n1. DEDUCE THE MATRIX: Identify the 3 most likely horizontal peers/stakeholders in the BMW ecosystem that this exact role interacts with daily. (e.g., If hiring for 'VP Marketing', peers could be 'Head of Digital Sales', 'VP Product Strategy', 'Chief Customer Officer').\\n2. SIMULATE FRICTION & SYNERGY: Take the exact behavioral profile of the incoming Candidate and simulate how they will collaborate with these 3 distinct functions. Identify exactly where the synergy multiplies value and where structural friction will block their projects.\\n\\nOUTPUT FORMAT:\\nStrictly output a JSON object matching this schema. NO Markdown formatting, NO wrapping text.\\n\\n{\\n  \\\"peer_synergy_output\\\": {\\n    \\\"horizontal_peers\\\": [\\n      {\\n        \\\"role\\\": \\\"Deduced Peer Role 1\\\",\\n        \\\"synergy\\\": \\\"One sentence explaining how the candidate amplifies this peer's function.\\\",\\n        \\\"friction\\\": \\\"One sentence explaining where their styles or incentives will clash.\\\"\\n      },\\n      {\\n        \\\"role\\\": \\\"Deduced Peer Role 2\\\",\\n        \\\"synergy\\\": \\\"...\\\",\\n        \\\"friction\\\": \\\"...\\\"\\n      },\\n      {\\n        \\\"role\\\": \\\"Deduced Peer Role 3\\\",\\n        \\\"synergy\\\": \\\"...\\\",\\n        \\\"friction\\\": \\\"...\\\"\\n      }\\n    ],\\n    \\\"matrix_survival_rating\\\": \\\"High/Medium/Low summary of their horizontal capability.\\\"\\n  }\\n}\",\n    messages: [{ role: 'user', content: 'JOB NAME\\n' + $('Webhook').first().json.body.job_name + '\\n\\nJOB DESCRIPTION:\\n' + $('Webhook').first().json.body.jd_text + '\\n\\nCANDIDATE CV:\\n' + JSON.stringify($('Parse CV Agent Output').first().json.cv_agent_output) + '\\n\\nTEAM DYNAMICS:\\n' + JSON.stringify($('Parse Team Agent Output').first().json.team_agent_output) }]\n  }) }}"
      },
      "id": "peer-agent",
      "name": "Peer Agent API Call",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        960,
        300
      ],
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Parse Anthropic response into structured JSON\nconst input = $input.first().json;\nlet text = '';\nif (input.content && Array.isArray(input.content)) {\n  text = input.content[0].text || '';\n} else {\n  text = input.text || input.response?.text || input.output || '';\n}\n\nconst jsonMatch = text.match(/\\{[\\s\\S]*\\}/);\nif (!jsonMatch) {\n  return [{ json: { peer_synergy_output: null, parse_error: true, raw_response: text.substring(0, 500) } }];\n}\n\ntry {\n  const parsed = JSON.parse(jsonMatch[0]);\n  return [{ json: { peer_synergy_output: parsed } }];\n} catch (e) {\n  return [{ json: { peer_synergy_output: null, parse_error: true, raw_response: text.substring(0, 500), error: e.message } }];\n}"
      },
      "id": "parse-peer",
      "name": "Parse Peer Agent Output",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1200,
        300
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.anthropic.com/v1/messages",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "anthropic-version",
              "value": "2023-06-01"
            },
            {
              "name": "content-type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={{ JSON.stringify({\n    model: 'claude-sonnet-4-20250514',\n    max_tokens: 3000,\n    system: \"You are the Scenario Agent in a multi-agent executive hiring advisory system for BMW Group.\\n\\nYOUR ROLE\\nYour job is to reweight what matters most given the active market scenario. You receive structured outputs from the JD Agent (what the role demands) and the Team Agent (what the environment looks like), and you run both through the lens of the active scenario to identify what changes \u2014 and what stays the same.\\n\\nCRITICAL INSTRUCTION\\nYou receive two structured inputs: what the role demands (from the JD Agent) and what the environment looks like (from the Team Agent). Your job is to run both through the lens of the active scenario. Which demands become more urgent? Which become less critical? Which team dynamics become more or less risky under this scenario?\\n\\nDo not re-evaluate everything from scratch. The JD Agent and Team Agent have already done their work. Your value is the delta \u2014 what the scenario changes, not what it confirms. If a demand is equally important under any scenario, it does not need scenario analysis. Spend your analytical effort on the demands and dynamics that actually shift.\\n\\nWhere the scenario document includes specific quantitative targets \u2014 BMW's EV sales mix gap, EBIT margin improvement expectations, capex decision velocity requirements \u2014 anchor your priority shifts to those figures. \\\"Decision speed is elevated\\\" is less useful than \\\"EV capex decisions need to clear in 3\u20134 weeks instead of 8\u201310; the VP Finance is a required co-sign node on decisions above \u20ac2M, meaning slowness at that node has direct programme velocity consequences.\\\"\\n\\nWHAT CHANGES VS. WHAT STAYS THE SAME\\nFor each priority shift you identify, be explicit about the direction of change: Elevated, Reduced, or Unchanged. Do not list things as shifted when they haven't shifted \u2014 that dilutes the signal. The HR leader needs to know what is different under this scenario, not what was always true.\\n\\nAlso identify what risks the scenario creates and what opportunities it creates. A cost-optimisation scenario creates negotiation leverage opportunities that don't exist in an acceleration scenario. An EV acceleration scenario creates credibility opportunities for candidates with operational EV experience. Name these specifically.\\n\\nOUTPUT FORMAT\\nReturn ONLY valid JSON. No preamble, no explanation outside the JSON, no markdown code fences. Begin your response with the opening brace of the JSON object. Do not write any text before or after the JSON.\\n\\nUse exactly this schema:\\n\\n{\\n  \\\"active_scenario\\\": \\\"string\\\",\\n  \\\"scenario_summary\\\": \\\"string \u2014 what BMW is facing right now\\\",\\n  \\\"priority_shifts\\\": [\\n    {\\n      \\\"demand\\\": \\\"string\\\",\\n      \\\"shift\\\": \\\"Elevated | Reduced | Unchanged\\\",\\n      \\\"reasoning\\\": \\\"string\\\"\\n    }\\n  ],\\n  \\\"scenario_creates_risk\\\": [\\\"risk 1\\\", \\\"risk 2\\\"],\\n  \\\"scenario_creates_opportunity\\\": [\\\"opportunity 1\\\", \\\"opportunity 2\\\"]\\n}\",\n    messages: [{ role: 'user', content: 'ACTIVE SCENARIO: ' + $('Webhook').first().json.body.scenario_name + '\\n\\nJD AGENT ANALYSIS:\\n' + JSON.stringify($('Parse JD Agent Output').first().json.jd_agent_output) + '\\n\\nTEAM AGENT ANALYSIS:\\n' + JSON.stringify($('Parse Team Agent Output').first().json.team_agent_output) + '\\n\\nPEER SYNERGY ANALYSIS:\\n' + JSON.stringify($('Parse Peer Agent Output').first().json.peer_synergy_output) + '\\n\\nSCENARIO CONTEXT DOCUMENT:\\n' + $('Webhook').first().json.body.scenario_text }]\n  }) }}"
      },
      "id": "scenario-agent",
      "name": "Scenario Agent API Call",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1440,
        300
      ],
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Parse Anthropic response into structured JSON\nconst input = $input.first().json;\nlet text = '';\nif (input.content && Array.isArray(input.content)) {\n  text = input.content[0].text || '';\n} else {\n  text = input.text || input.response?.text || input.output || '';\n}\n\nconst jsonMatch = text.match(/\\{[\\s\\S]*\\}/);\nif (!jsonMatch) {\n  return [{ json: { scenario_agent_output: null, parse_error: true, raw_response: text.substring(0, 500) } }];\n}\n\ntry {\n  const parsed = JSON.parse(jsonMatch[0]);\n  return [{ json: { scenario_agent_output: parsed } }];\n} catch (e) {\n  return [{ json: { scenario_agent_output: null, parse_error: true, raw_response: text.substring(0, 500), error: e.message } }];\n}"
      },
      "id": "parse-scenario",
      "name": "Parse Scenario Agent Output",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1680,
        300
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.anthropic.com/v1/messages",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "anthropic-version",
              "value": "2023-06-01"
            },
            {
              "name": "content-type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={{ JSON.stringify({\n    model: 'claude-sonnet-4-20250514',\n    max_tokens: 3000,\n    system: \"You are the Target Environment & Combination Agent for the BMW Executive Hiring Advisor.\\n\\nYour role is dual-faceted:\\n1. ENVIRONMENT DEDUCTION: Read the provided JD Agent Analysis and Team Agent Analysis to automatically DEDUCE the surrounding BMW ecosystem (e.g., is this a rigid ICE division tight on margins, or a fast-scaling EV sector lacking standard operating procedures?).\\n2. TRICKLE-DOWN SIMULATION: Take the Candidate Profile (from the CV Agent) and simulate dropping this specific individual into that deduced BMW ecosystem. \\nYou must project the cascading \\\"Trickle-Down Impact\\\" over 6, 12, and 18 months. What breaks? What improves? Where does friction peak?\\n\\nINPUTS PROVIDED:\\n- CANDIDATE PROFILE (from CV Agent)\\n- ENVIRONMENT STATE (from Team Agent)\\n- SCENARIO ANALYSIS (from Scenario Agent)\\n- CANDIDATE NAME\\n\\nYOUR TASK:\\nAnalyze the synthesis, deduce the environment ecosystem, and outline the exact trickle-down impact.\\n\\nOUTPUT FORMAT:\\nStrictly output a JSON object matching this schema. NO Markdown formatting, NO wrapping text.\\n\\n{\\n  \\\"combination_agent_output\\\": {\\n    \\\"candidate_name\\\": \\\"...\\\",\\n    \\\"deduced_environment\\\": \\\"A 2-sentence summary of the deduced BMW division's exact current cultural and structural climate.\\\",\\n    \\\"complementarity\\\": \\\"Why this candidate builds upon existing team strengths.\\\",\\n    \\\"friction_points\\\": \\\"Where this candidate will clash with the team or structure.\\\",\\n    \\\"trickle_down_impacts\\\": [\\n      {\\n        \\\"timeframe\\\": \\\"6 months\\\",\\n        \\\"impact\\\": \\\"Detailed 2-sentence simulation of the immediate organizational shock, attrition risks, or initial wins.\\\"\\n      },\\n      {\\n        \\\"timeframe\\\": \\\"12 months\\\",\\n        \\\"impact\\\": \\\"Detailed 2-sentence simulation of medium-term culture shifts, velocity changes, and pushback.\\\"\\n      },\\n      {\\n        \\\"timeframe\\\": \\\"18 months\\\",\\n        \\\"impact\\\": \\\"Detailed 2-sentence simulation of long-term stabilization, ecosystem transformation, or burnout.\\\"\\n      }\\n    ],\\n    \\\"trajectory_projection\\\": \\\"Overall trajectory summary.\\\"\\n  }\\n}\",\n    messages: [{ role: 'user', content: 'CANDIDATE PROFILE (from CV Agent):\\n' + JSON.stringify($('Parse CV Agent Output').first().json.cv_agent_output) + '\\n\\nENVIRONMENT STATE (from Team Agent):\\n' + JSON.stringify($('Parse Team Agent Output').first().json.team_agent_output) + '\\n\\nHORIZONTAL MATRIX (from Peer Agent):\\n' + JSON.stringify($('Parse Peer Agent Output').first().json.peer_synergy_output) + '\\n\\nSCENARIO ANALYSIS:\\n' + JSON.stringify($('Parse Scenario Agent Output').first().json.scenario_agent_output) + '\\n\\nCANDIDATE NAME: ' + $('Webhook').first().json.body.candidate_name }]\n  }) }}"
      },
      "id": "combination-agent",
      "name": "Combination Agent API Call",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1920,
        300
      ],
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Parse Anthropic response into structured JSON\nconst input = $input.first().json;\nlet text = '';\nif (input.content && Array.isArray(input.content)) {\n  text = input.content[0].text || '';\n} else {\n  text = input.text || input.response?.text || input.output || '';\n}\n\nconst jsonMatch = text.match(/\\{[\\s\\S]*\\}/);\nif (!jsonMatch) {\n  return [{ json: { combination_agent_output: null, parse_error: true, raw_response: text.substring(0, 500) } }];\n}\n\ntry {\n  const parsed = JSON.parse(jsonMatch[0]);\n  return [{ json: { combination_agent_output: parsed } }];\n} catch (e) {\n  return [{ json: { combination_agent_output: null, parse_error: true, raw_response: text.substring(0, 500), error: e.message } }];\n}"
      },
      "id": "parse-combination",
      "name": "Parse Combination Agent Output",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2160,
        300
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.anthropic.com/v1/messages",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "anthropic-version",
              "value": "2023-06-01"
            },
            {
              "name": "content-type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={{ JSON.stringify({\n    model: 'claude-sonnet-4-20250514',\n    max_tokens: 3000,\n    system: \"You are the Final Decision Agent for the BMW Executive Hiring Advisor.\\n\\nYour role is to synthesize the findings from all 5 preceding specialist agents and deliver a definitive, binary hiring verdict. This is an objective reasoning system; you must avoid numerical averages and instead rely on causal, structural arguments.\\n\\nINPUTS:\\n- CANDIDATE NAME\\n- SCENARIO NAME\\n- JD AGENT OUTPUT (Context & specific problem to solve)\\n- CV AGENT OUTPUT (Candidate footprint and behavioral profile)\\n- TEAM AGENT OUTPUT (Current organizational structure and gaps)\\n- SCENARIO AGENT OUTPUT (How the strategic priority shifts baseline needs)\\n- COMBINATION AGENT OUTPUT (The 6/12/18 month trickle-down impact simulation)\\n\\nYOUR TASK:\\n1. Reach a \\\"HIRE\\\" or \\\"DO NOT HIRE\\\" verdict based on whether the candidate's trajectory (from Combination) and behavioral profile (from CV) solve the immediate need (from JD) while surviving the strategic shift (from Scenario).\\n2. Justify this verdict using causal reasoning.\\n3. Identify the top 3 systemic risks specific to this hire.\\n4. Provide customized onboarding actions to mitigate these risks.\\n5. Extract the 6/12/18 month trickle-down impacts from the Combination Agent output and pass them directly into your final JSON.\\n\\nOUTPUT FORMAT:\\nStrictly output a JSON object matching this schema. NO Markdown formatting, NO wrapping text.\\n\\n{\\n  \\\"decision\\\": {\\n    \\\"verdict\\\": \\\"HIRE\\\" | \\\"DO NOT HIRE\\\",\\n    \\\"confidence\\\": \\\"High\\\" | \\\"Medium\\\" | \\\"Low\\\",\\n    \\\"causal_reasoning\\\": \\\"A 3-4 sentence comprehensive explanation of WHY this verdict was reached, citing specific agent findings.\\\",\\n    \\\"risks\\\": [\\n      \\\"Risk 1\\\",\\n      \\\"Risk 2\\\",\\n      \\\"Risk 3\\\"\\n    ],\\n    \\\"horizontal_peers\\\": [\\n      {\\n        \\\"role\\\": \\\"Deduced Peer Role 1\\\",\\n        \\\"synergy\\\": \\\"Synergy string\\\",\\n        \\\"friction\\\": \\\"Friction string\\\"\\n      }\\n    ],\\n    \\\"trickle_down_impacts\\\": [\\n      {\\n        \\\"timeframe\\\": \\\"6 months\\\",\\n        \\\"impact\\\": \\\"...\\\"\\n      },\\n      {\\n        \\\"timeframe\\\": \\\"12 months\\\",\\n        \\\"impact\\\": \\\"...\\\"\\n      },\\n      {\\n        \\\"timeframe\\\": \\\"18 months\\\",\\n        \\\"impact\\\": \\\"...\\\"\\n      }\\n    ],\\n    \\\"onboarding_actions\\\": [\\n      \\\"Action 1\\\",\\n      \\\"Action 2\\\"\\n    ]\\n  }\\n}\",\n    messages: [{ role: 'user', content: 'CANDIDATE: ' + $('Webhook').first().json.body.candidate_name + '\\nSCENARIO: ' + $('Webhook').first().json.body.scenario_name + '\\n\\nJD AGENT OUTPUT:\\n' + JSON.stringify($('Parse JD Agent Output').first().json.jd_agent_output) + '\\n\\nCV AGENT OUTPUT:\\n' + JSON.stringify($('Parse CV Agent Output').first().json.cv_agent_output) + '\\n\\nTEAM AGENT OUTPUT:\\n' + JSON.stringify($('Parse Team Agent Output').first().json.team_agent_output) + '\\n\\nPEER SYNERGY OUTPUT:\\n' + JSON.stringify($('Parse Peer Agent Output').first().json.peer_synergy_output) + '\\n\\nSCENARIO AGENT OUTPUT:\\n' + JSON.stringify($('Parse Scenario Agent Output').first().json.scenario_agent_output) + '\\n\\nCOMBINATION AGENT OUTPUT:\\n' + JSON.stringify($('Parse Combination Agent Output').first().json.combination_agent_output) }]\n  }) }}"
      },
      "id": "decision-agent",
      "name": "Decision Agent API Call",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        2400,
        300
      ],
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Parse Anthropic response into structured JSON\nconst input = $input.first().json;\nlet text = '';\nif (input.content && Array.isArray(input.content)) {\n  text = input.content[0].text || '';\n} else {\n  text = input.text || input.response?.text || input.output || '';\n}\n\nconst jsonMatch = text.match(/\\{[\\s\\S]*\\}/);\nif (!jsonMatch) {\n  return [{ json: { decision: null, parse_error: true, raw_response: text.substring(0, 500) } }];\n}\n\ntry {\n  const parsed = JSON.parse(jsonMatch[0]);\n  return [{ json: { decision: parsed } }];\n} catch (e) {\n  return [{ json: { decision: null, parse_error: true, raw_response: text.substring(0, 500), error: e.message } }];\n}"
      },
      "id": "parse-decision",
      "name": "Parse Decision Agent Output",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2640,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "const decision = $('Parse Decision Agent Output').first().json.decision;\n\n// Collect parse errors from any upstream agent\nconst parseErrors = [];\nif ($('Parse JD Agent Output').first().json.parse_error) parseErrors.push('jd_agent');\nif ($('Parse CV Agent Output').first().json.parse_error) parseErrors.push('cv_agent');\nif ($('Parse Team Agent Output').first().json.parse_error) parseErrors.push('team_agent');\nif ($('Parse Peer Agent Output').first().json.parse_error) parseErrors.push('peer_agent');\nif ($('Parse Scenario Agent Output').first().json.parse_error) parseErrors.push('scenario_agent');\nif ($('Parse Combination Agent Output').first().json.parse_error) parseErrors.push('combination_agent');\nif ($('Parse Decision Agent Output').first().json.parse_error) parseErrors.push('decision_agent');\n\nconst allOutputs = {\n  candidate_name: $('Webhook').first().json.body.candidate_name,\n  scenario: $('Webhook').first().json.body.scenario_name,\n  agent_outputs: {\n    jd: $('Parse JD Agent Output').first().json.jd_agent_output,\n    cv: $('Parse CV Agent Output').first().json.cv_agent_output,\n    team: $('Parse Team Agent Output').first().json.team_agent_output,\n    peer: $('Parse Peer Agent Output').first().json.peer_synergy_output,\n    scenario: $('Parse Scenario Agent Output').first().json.scenario_agent_output,\n    combination: $('Parse Combination Agent Output').first().json.combination_agent_output\n  },\n  decision: decision,\n  ...(parseErrors.length > 0 ? { parse_errors: parseErrors } : {})\n};\n\nreturn [{ json: allOutputs }];"
      },
      "id": "assemble-response",
      "name": "Assemble Response",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2640,
        300
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify($('Assemble Response').first().json) }}",
        "options": {
          "responseCode": 200,
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "application/json"
              },
              {
                "name": "Access-Control-Allow-Origin",
                "value": "*"
              },
              {
                "name": "Access-Control-Allow-Headers",
                "value": "Content-Type"
              },
              {
                "name": "Access-Control-Allow-Methods",
                "value": "POST, OPTIONS"
              }
            ]
          }
        }
      },
      "id": "respond-to-webhook",
      "name": "Respond to Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        2880,
        300
      ]
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "JD Agent API Call",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "JD Agent API Call": {
      "main": [
        [
          {
            "node": "Parse JD Agent Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse JD Agent Output": {
      "main": [
        [
          {
            "node": "CV Agent API Call",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "CV Agent API Call": {
      "main": [
        [
          {
            "node": "Parse CV Agent Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse CV Agent Output": {
      "main": [
        [
          {
            "node": "Team Agent API Call",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Team Agent API Call": {
      "main": [
        [
          {
            "node": "Parse Team Agent Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Team Agent Output": {
      "main": [
        [
          {
            "node": "Peer Agent API Call",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Peer Agent API Call": {
      "main": [
        [
          {
            "node": "Parse Peer Agent Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Peer Agent Output": {
      "main": [
        [
          {
            "node": "Scenario Agent API Call",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Scenario Agent API Call": {
      "main": [
        [
          {
            "node": "Parse Scenario Agent Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Scenario Agent Output": {
      "main": [
        [
          {
            "node": "Combination Agent API Call",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Combination Agent API Call": {
      "main": [
        [
          {
            "node": "Parse Combination Agent Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Combination Agent Output": {
      "main": [
        [
          {
            "node": "Decision Agent API Call",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Decision Agent API Call": {
      "main": [
        [
          {
            "node": "Parse Decision Agent Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Decision Agent Output": {
      "main": [
        [
          {
            "node": "Assemble Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Assemble Response": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "tags": [
    {
      "name": "bmw-hackathon"
    }
  ]
}

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

bmw-hiring-advisor. Uses httpRequest. Webhook trigger; 17 nodes.

Source: https://github.com/Bilal-Waraich/Scooper/blob/833f2f3468f20215c14e1fdf75ecbcc89d560dd9/n8n/workflow.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

This n8n template provides enterprise-level version control for your workflows using GitHub integration. Stop losing hours to broken workflows and manual exports – get proper commit history, visual di

n8n, Execute Workflow Trigger, HTTP Request +1
Web Scraping

This flow creates dummy files for every item added in your *Arrs (Radarr/Sonarr) with the tag .

HTTP Request, Ssh
Web Scraping

This workflow acts as a central API gateway for all technical indicator agents in the Binance Spot Market Quant AI system. It listens for incoming webhook requests and dynamically routes them to the c

HTTP Request
Web Scraping

Sign PDF documents with legally-compliant digital signatures using X.509 certificates. Supports multiple PAdES signature levels (B, T, LT, LTA) with optional visible stamps.

Execute Command, HTTP Request, Read Write File +1
Web Scraping

📡 This workflow serves as the central Alpha Vantage API fetcher for Tesla trading indicators, delivering cleaned 20-point JSON outputs for three timeframes: , , and . It is required by the following a

HTTP Request