This workflow corresponds to n8n.io template #11134 — we link there as the canonical source.
This workflow follows the Chat → Chat Trigger 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": "w0iWHqwJVcIyX6cA",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "01.Firecrawl Web Search Chatbot",
"tags": [],
"nodes": [
{
"id": "41ff48ba-2409-4697-a84c-c0ac49f292f0",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-640,
-112
],
"parameters": {
"color": 7,
"width": 944,
"height": 304,
"content": "## Internet Search Service with Firecrawl\nBackend search service responsible for processing search requests.\nReceives search queries from the chat interface, executes the web search via Firecrawl, structures the results, and returns the response to the calling interface flow."
},
"typeVersion": 1
},
{
"id": "1c55b030-a9f4-459b-8759-fc42720972f3",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-640,
-448
],
"parameters": {
"color": 7,
"width": 1424,
"height": 304,
"content": "## Internet Search Chat Interface\nHandles user-facing chat interactions for the Internet Search feature.\nReceives chat messages, forwards the search query to the backend Firecrawl service, formats the returned data, and sends the final response back to the user."
},
"typeVersion": 1
},
{
"id": "5d29f451-e073-48f7-b4e5-7a70c4115676",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
336,
-112
],
"parameters": {
"color": 7,
"width": 720,
"height": 304,
"content": "## Firecrawl Account Credits Monitor\nMonitors Firecrawl account credit usage.\nAllows manual triggering to check the remaining available credits, returning the usage summary and terminating the monitor flow."
},
"typeVersion": 1
},
{
"id": "9e41f6a8-0189-4815-8cb0-0c9e6a011644",
"name": "Receive search query",
"type": "n8n-nodes-base.webhook",
"position": [
-576,
16
],
"parameters": {
"path": "620a78d5-00a6-4a05-9587-837a8d23ef7c",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 2.1
},
{
"id": "d1c5d503-3643-416d-989d-553e20b3fcee",
"name": "Search the web (Firecrawl)",
"type": "@mendable/n8n-nodes-firecrawl.firecrawl",
"position": [
-352,
16
],
"parameters": {
"query": "={{ $json.body.consultaPesquisa }}",
"operation": "search",
"requestOptions": {}
},
"credentials": {
"firecrawlApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "94f362a0-ec97-4005-8680-a74dd04a0df9",
"name": "Answer search query",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
-128,
16
],
"parameters": {
"options": {}
},
"typeVersion": 1.4
},
{
"id": "55f74c19-a743-488b-83c2-3effc8426332",
"name": "Terminate service flow",
"type": "n8n-nodes-base.noOp",
"position": [
96,
16
],
"parameters": {},
"typeVersion": 1
},
{
"id": "cecca7b5-e368-48e3-9322-2c45e7eb3960",
"name": "Receive chat message",
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"position": [
-576,
-320
],
"parameters": {
"public": true,
"options": {
"title": "Interface de Chat para Busca na Internet",
"subtitle": "Alysson Neves (https://n8n.io/creators/alysson)",
"customCss": ":root {\n /* Paleta de cores principal */\n --chat--color-primary: #e74266;\n --chat--color-primary-shade-50: #db4061;\n --chat--color-primary-shade-100: #cf3c5c;\n --chat--color-secondary: #20b69e;\n --chat--color-secondary-shade-50: #1ca08a;\n --chat--color-white: #ffffff;\n --chat--color-light: #f2f4f8;\n --chat--color-light-shade-50: #e6e9f1;\n --chat--color-light-shade-100: #c2c5cc;\n --chat--color-medium: #d2d4d9;\n --chat--color-dark: #101330;\n --chat--color-disabled: #d2d4d9;\n --chat--color-typing: #404040;\n\n /* Layout base */\n --chat--spacing: 1rem;\n --chat--border-radius: 0.25rem;\n --chat--transition-duration: 0.15s;\n --chat--font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;\n\n /* Dimens\u00f5es da janela do chat */\n --chat--window--width: 400px;\n --chat--window--height: 600px;\n --chat--window--bottom: var(--chat--spacing);\n --chat--window--right: var(--chat--spacing);\n --chat--window--z-index: 9999;\n --chat--window--border: 1px solid var(--chat--color-light-shade-50);\n --chat--window--border-radius: var(--chat--border-radius);\n --chat--window--margin-bottom: var(--chat--spacing);\n\n /* Estilos do cabe\u00e7alho */\n --chat--header-height: auto;\n --chat--header--padding: var(--chat--spacing);\n\n /*\n Fundo do cabe\u00e7alho:\n - Imagem alinhada \u00e0 direita, centralizada verticalmente\n - Altura da imagem = 100% da altura do cabe\u00e7alho\n */\n --chat--header--background: url(\"https://user-images.githubusercontent.com/10284570/173569848-c624317f-42b1-45a6-ab09-f0ea3c247648.png\")\n right center / auto 100% no-repeat\n var(--chat--color-dark);\n\n --chat--header--color: var(--chat--color-light);\n --chat--header--border-top: none;\n --chat--header--border-bottom: none;\n --chat--header--border-left: none;\n --chat--header--border-right: none;\n --chat--heading--font-size: 1.2rem;/*2em;*/\n --chat--subtitle--font-size: inherit;\n --chat--subtitle--line-height: 1.8;\n\n /* Estilos das mensagens */\n --chat--message--font-size: 1rem;\n --chat--message--padding: var(--chat--spacing);\n --chat--message--border-radius: var(--chat--border-radius);\n --chat--message-line-height: 1.5;\n --chat--message--margin-bottom: calc(var(--chat--spacing) * 1);\n --chat--message--bot--background: var(--chat--color-white);\n --chat--message--bot--color: var(--chat--color-dark);\n --chat--message--bot--border: none;\n --chat--message--user--background: var(--chat--color-secondary);\n --chat--message--user--color: var(--chat--color-white);\n --chat--message--user--border: none;\n --chat--message--pre--background: rgba(0, 0, 0, 0.05);\n --chat--messages-list--padding: var(--chat--spacing);\n\n /* Bot\u00e3o de toggle do chat */\n --chat--toggle--size: 64px;\n --chat--toggle--width: var(--chat--toggle--size);\n --chat--toggle--height: var(--chat--toggle--size);\n --chat--toggle--border-radius: 50%;\n --chat--toggle--background: var(--chat--color-primary);\n --chat--toggle--hover--background: var(--chat--color-primary-shade-50);\n --chat--toggle--active--background: var(--chat--color-primary-shade-100);\n --chat--toggle--color: var(--chat--color-white);\n\n /* \u00c1rea de input */\n --chat--textarea--height: 50px;\n --chat--textarea--max-height: 30rem;\n --chat--input--font-size: inherit;\n --chat--input--border: 0;\n --chat--input--border-radius: 0;\n --chat--input--padding: 0.8rem;\n --chat--input--background: var(--chat--color-white);\n --chat--input--text-color: initial;\n --chat--input--line-height: 1.5;\n --chat--input--placeholder--font-size: var(--chat--input--font-size);\n --chat--input--border-active: 0;\n --chat--input--left--panel--width: 2rem;\n\n /* Bot\u00f5es gerais */\n --chat--button--color: var(--chat--color-light);\n --chat--button--background: var(--chat--color-primary);\n --chat--button--padding: calc(var(--chat--spacing) * 1 / 2) var(--chat--spacing);\n --chat--button--border-radius: var(--chat--border-radius);\n --chat--button--hover--color: var(--chat--color-light);\n --chat--button--hover--background: var(--chat--color-primary-shade-50);\n --chat--close--button--color-hover: var(--chat--color-primary);\n\n /* Bot\u00f5es de envio e anexos */\n --chat--input--send--button--background: var(--chat--color-white);\n --chat--input--send--button--color: var(--chat--color-secondary);\n --chat--input--send--button--background-hover: var(--chat--color-primary-shade-50);\n --chat--input--send--button--color-hover: var(--chat--color-secondary-shade-50);\n --chat--input--file--button--background: var(--chat--color-white);\n --chat--input--file--button--color: var(--chat--color-secondary);\n --chat--input--file--button--background-hover: var(--chat--input--file--button--background);\n --chat--input--file--button--color-hover: var(--chat--color-secondary-shade-50);\n --chat--files-spacing: 0.25rem;\n\n /* Corpo e rodap\u00e9 do chat */\n --chat--body--background: var(--chat--color-light);\n --chat--footer--background: var(--chat--color-light);\n --chat--footer--color: var(--chat--color-dark);\n}\n\n/* Limita a largura das mensagens no bal\u00e3o */\n.chat-message {\n max-width: 50%;\n}\n\n/* Fonte do cabe\u00e7alho (t\u00edtulo + subt\u00edtulo) em Arial */\n.chat-header,\n.chat-header * {\n font-family: Arial, Helvetica, sans-serif !important;\n}\n",
"responseMode": "responseNodes",
"inputPlaceholder": "Digite aqui..."
},
"initialMessages": "\ud83e\udd16 Ol\u00e1! Como posso ajudar voc\u00ea hoje?"
},
"typeVersion": 1.4
},
{
"id": "1a5c7d26-cf8d-4dac-98bd-390b67b8881a",
"name": "Query search server (HTTP)",
"type": "n8n-nodes-base.httpRequest",
"position": [
-128,
-320
],
"parameters": {
"url": "={{ $json.webhookUrl }}",
"method": "POST",
"options": {},
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "consultaPesquisa",
"value": "={{ $('Receive chat message').item.json.chatInput }}"
}
]
}
},
"typeVersion": 4.3
},
{
"id": "e383074e-3c9b-4140-86c2-d468c1feba07",
"name": "Reply to the user in the chat",
"type": "@n8n/n8n-nodes-langchain.chat",
"position": [
320,
-320
],
"parameters": {
"message": "={{ $json.output }}",
"options": {},
"waitUserReply": false
},
"typeVersion": 1
},
{
"id": "a0499bf1-b38b-449b-a315-96df8c6ddb5b",
"name": "Terminate interface flow",
"type": "n8n-nodes-base.noOp",
"position": [
544,
-320
],
"parameters": {},
"typeVersion": 1
},
{
"id": "cecacc25-6dc9-45e7-8d7a-60b80c0c28ba",
"name": "Format search response (Python)",
"type": "n8n-nodes-base.code",
"position": [
96,
-320
],
"parameters": {
"language": "python",
"pythonCode": "import json\n\n# Retrieve the JSON payload from the previous node\ndata = items[0].get(\"json\", {})\n\n# If the payload is a JSON string, parse it into a Python object\nif isinstance(data, str):\n data = json.loads(data)\n\n# If the payload is a list, use the first element as the main object\nif isinstance(data, list) and data:\n data = data[0]\n\n# Navigate to data.web, which is expected to be a list of web items\nweb_items = data.get(\"data\", {}).get(\"web\", [])\n\nblocks = []\n\nfor item in web_items:\n position = str(item.get(\"position\", \"\"))\n url = item.get(\"url\", \"\")\n title = item.get(\"title\", \"\")\n description = item.get(\"description\", \"\")\n\n # Build a clickable Markdown link using the URL, if present\n markdown_link = f\"[{url}]({url})\" if url else \"\"\n\n # Build the heading line:\n # - Use \"####\" to create a smaller heading\n # - Escape the closing parenthesis to avoid Markdown list interpretation\n if position and title:\n title_line = f\"#### {position}\\\\) {title}\"\n elif position:\n title_line = f\"#### {position}\\\\)\"\n elif title:\n title_line = f\"#### {title}\"\n else:\n title_line = \"\"\n\n # Each block has the format:\n # 1) Heading (title_line)\n # 2) Description\n # 3) Clickable link\n block_lines = [title_line, description, markdown_link]\n\n # Join non-empty lines with a blank line between them\n block = \"\\n\\n\".join(line for line in block_lines if line)\n blocks.append(block)\n\n# Use a horizontal separator between result blocks\noutput_text = \"\\n\\n-----\\n\\n\".join(blocks).strip()\n\nreturn [{\n \"json\": {\n \"output\": output_text\n }\n}]\n"
},
"typeVersion": 2
},
{
"id": "eb1d665a-21cf-47e0-b9ae-08e9a7beae24",
"name": "Define constants",
"type": "n8n-nodes-base.set",
"position": [
-352,
-320
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "ad1474cc-d06c-45ea-9779-2e4ac47da5f9",
"name": "webhookUrl",
"type": "string",
"value": "https://n8n.dudarobotics.cloud/webhook/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "b52569fa-a18b-4b2c-8fe9-e32267a3a684",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1168,
-448
],
"parameters": {
"width": 496,
"height": 640,
"content": "## Internet Search Chat with Firecrawl\n\n### How it works\n1. A user sends a query via the chat widget and the Chat Trigger captures the message.\n2. The chat flow posts the query to the backend webhook (HTTP Request) which forwards it to the search service.\n3. The webhook calls Firecrawl to run the web search and returns raw results.\n4. A formatter converts the raw results into concise Markdown blocks and separators.\n5. The chat node sends the formatted search summary back to the user.\n6. Optional: an admin can manually trigger a credits check to review Firecrawl usage.\n\n### Setup\n- [ ] Add Firecrawl API credentials in n8n.\n- [ ] Update the webhook URL in the \"Define constants\" node to your n8n instance URL.\n- [ ] Configure and enable the Chat Trigger (make it public and set initial messages).\n- [ ] Ensure the webhook node path matches the constant and is reachable from the chat node.\n- [ ] Test the chat by sending a sample query and verify the formatted search results.\n- [ ] (Optional) Run the manual \"Check credits\" trigger to monitor Firecrawl account usage.\n"
},
"typeVersion": 1
},
{
"id": "96fb707f-a004-406b-a188-2b31d8760075",
"name": "Manual Trigger",
"type": "n8n-nodes-base.manualTrigger",
"position": [
400,
16
],
"parameters": {},
"typeVersion": 1
},
{
"id": "21efbd3f-d8bb-4b64-a7cb-b808e6697de9",
"name": "Verify Firecrawl Account Credit Balance",
"type": "@mendable/n8n-nodes-firecrawl.firecrawl",
"position": [
624,
16
],
"parameters": {
"operation": "teamCreditUsage",
"requestOptions": {}
},
"credentials": {
"firecrawlApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "7c0d7a57-cb7b-4bd5-be98-fc22207d44b5",
"name": "Terminate Monitor Flow",
"type": "n8n-nodes-base.noOp",
"position": [
848,
16
],
"parameters": {},
"typeVersion": 1
}
],
"active": true,
"settings": {
"executionOrder": "v1"
},
"versionId": "d49505fb-d0ea-4702-b028-3ba99c13ba54",
"connections": {
"Manual Trigger": {
"main": [
[
{
"node": "Verify Firecrawl Account Credit Balance",
"type": "main",
"index": 0
}
]
]
},
"Define constants": {
"main": [
[
{
"node": "Query search server (HTTP)",
"type": "main",
"index": 0
}
]
]
},
"Answer search query": {
"main": [
[
{
"node": "Terminate service flow",
"type": "main",
"index": 0
}
]
]
},
"Receive chat message": {
"main": [
[
{
"node": "Define constants",
"type": "main",
"index": 0
}
]
]
},
"Receive search query": {
"main": [
[
{
"node": "Search the web (Firecrawl)",
"type": "main",
"index": 0
}
]
]
},
"Query search server (HTTP)": {
"main": [
[
{
"node": "Format search response (Python)",
"type": "main",
"index": 0
}
]
]
},
"Search the web (Firecrawl)": {
"main": [
[
{
"node": "Answer search query",
"type": "main",
"index": 0
}
]
]
},
"Reply to the user in the chat": {
"main": [
[
{
"node": "Terminate interface flow",
"type": "main",
"index": 0
}
]
]
},
"Format search response (Python)": {
"main": [
[
{
"node": "Reply to the user in the chat",
"type": "main",
"index": 0
}
]
]
},
"Verify Firecrawl Account Credit Balance": {
"main": [
[
{
"node": "Terminate Monitor Flow",
"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.
firecrawlApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
A user sends a query via the chat widget and the Chat Trigger captures the message. The chat flow posts the query to the backend webhook (HTTP Request) which forwards it to the search service. The webhook calls Firecrawl to run the web search and returns raw results. A formatter…
Source: https://n8n.io/workflows/11134/ — 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.
Selenium Ultimate Scraper Workflow. Uses html, lmChatOpenAi, httpRequest, limit. Webhook trigger; 63 nodes.
Selenium Ultimate Scraper Workflow. Uses html, lmChatOpenAi, httpRequest, limit. Webhook trigger; 63 nodes.
This workflow is Part 2 of the HR Client Acquisition system and builds on the lead discovery pipeline from the previous workflow:
Business owners, industry specialists, and AI developers building domain-specific search experiences. It generates custom search filters to boost technical authorities and block lead-gen aggregators,
Automate Your Job Search: Find Job Listings on LinkedIn, Indeed, Glassdoor, Upwork & Adzuna!