This workflow follows the Execute Workflow Trigger → Postgres 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 →
{
"name": "[FC Sub] Scrape URL \u2014 Native Firecrawl Node",
"settings": {
"executionOrder": "v1"
},
"nodes": [
{
"parameters": {
"content": "## [FC Sub] Scrape URL \u2014 Native Firecrawl Node\n**Alternative to `03-sub-scrape-cached.json`.** Uses the native Firecrawl node (n8n Cloud integration or the `n8n-nodes-firecrawl` community node) instead of a raw HTTP Request.\n\n### Why this exists\nThe challenge brief asks for \"at least one Firecrawl node.\" Most of this repo's sub-workflows use HTTP Request against `api.firecrawl.dev` \u2014 which is portable and works on any self-hosted n8n, but is technically not a *Firecrawl node*. This file is insurance against a strict reading of that requirement.\n\n### When to use it\n- You're on n8n Cloud (where Firecrawl is a first-class integration with 100K free credits via the partnership)\n- You've installed the `n8n-nodes-firecrawl` community node on self-hosted n8n\n\n### When NOT to use it\n- Self-hosted without the community node installed. Stick with `03-sub-scrape-cached.json` in that case.\n\n### Differences from 03\n- **No 24h scrape cache.** The Firecrawl native node handles the call directly; adding cache logic around it is an exercise. This variant is optimized for simplicity and verifiable native-node usage, not for minimum credit burn.\n- **No 24h cache-hit short-circuit**. Every call hits Firecrawl (1 credit).\n- Same response shape as 03 so swapping it in the main workflow is a one-field change.\n- Same ledger row written to `firecrawl_credit_ledger`.\n\n### Swap instructions\n1. Import this file.\n2. Open `12-case-marco-lead-hunter.json` \u2192 `scrape_url` tool node.\n3. Change `workflowId` dropdown from the HTTP variant to this workflow (\"[FC Sub] Scrape URL \u2014 Native Firecrawl Node\").\n4. Save + activate.\n\n### Credentials\n- **Firecrawl** (native credential type on n8n Cloud, or `firecrawlApi` if using the community node)\n- **Postgres** (the same `firecrawl_agent_rw` role used by every other sub-workflow)",
"height": 680,
"width": 680,
"color": 4
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-40,
-740
],
"id": "sticky-fc-native",
"name": "README"
},
{
"parameters": {
"content": "### Node type note\nThis file references the native Firecrawl node as `n8n-nodes-firecrawl.firecrawl` \u2014 the standard community-node type identifier. On n8n Cloud the integration may register under a slightly different name. If the node shows as \"unknown\" after import, simply delete it, add a new Firecrawl node from the + menu, wire it between `Prep Input` and `Shape Response`, and copy the parameters from the old one.",
"height": 220,
"width": 360,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
460,
-180
],
"id": "sticky-fc-native-note",
"name": "Node type note"
},
{
"parameters": {
"inputSource": "passthrough"
},
"type": "n8n-nodes-base.executeWorkflowTrigger",
"typeVersion": 1.1,
"position": [
0,
0
],
"id": "fc-native-trigger",
"name": "When Executed by Another Workflow"
},
{
"parameters": {
"jsCode": "const input = $input.first().json;\nconst q = (input.query && typeof input.query === 'object') ? input.query : {};\nconst pick = (k, def) => {\n if (input[k] !== undefined) return input[k];\n if (q[k] !== undefined) return q[k];\n return def;\n};\nconst parseIfString = (v, fb) => {\n if (v === undefined || v === null) return fb;\n if (Array.isArray(v)) return v;\n if (typeof v !== 'string') return v;\n try { return JSON.parse(v); } catch { return fb; }\n};\n\nlet url = (pick('url') || '').toString().trim();\nif (!url) throw new Error('scrape_url (native) requires a `url` parameter.');\nif (!/^https?:\\/\\//i.test(url)) url = 'https://' + url;\ntry { new URL(url); } catch { throw new Error(`Invalid URL: ${url}`); }\n\nconst formats = parseIfString(pick('formats'), ['markdown','links']);\nconst only_main_content = pick('only_main_content', true) !== false;\nconst include_screenshot = pick('include_screenshot', false) === true;\nconst effective_formats = include_screenshot\n ? Array.from(new Set([...formats, 'screenshot']))\n : formats;\nconst session_id = (pick('session_id') || $execution.id || 'no-session').toString();\n\nreturn [{ json: {\n url,\n formats: effective_formats,\n only_main_content,\n include_screenshot,\n session_id,\n execution_id: $execution.id\n} }];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
220,
0
],
"id": "fc-native-prep",
"name": "Prep Input"
},
{
"parameters": {
"resource": "scrape",
"operation": "scrape",
"url": "={{ $json.url }}",
"formats": "={{ $json.formats }}",
"additionalOptions": {
"onlyMainContent": "={{ $json.only_main_content }}"
}
},
"type": "n8n-nodes-firecrawl.firecrawl",
"typeVersion": 1,
"position": [
440,
0
],
"id": "fc-native-call",
"name": "Firecrawl: Scrape",
"notesInFlow": true,
"notes": "Native Firecrawl node. Attach the 'Firecrawl API' credential. On n8n Cloud you can also connect via the one-click Connect-to-Firecrawl flow."
},
{
"parameters": {
"jsCode": "const prep = $('Prep Input').first().json;\nconst resp = $input.first().json;\n// Native node returns the Firecrawl response directly; support both shapes\nconst data = resp.data || resp;\nconst MAX_MD = 50000;\nconst markdown = (data.markdown || '').toString();\nconst truncated = markdown.length > MAX_MD;\nconst links = Array.isArray(data.links) ? data.links.slice(0, 200) : [];\nconst title = (data.metadata && data.metadata.title) || data.title || '';\nconst description = (data.metadata && data.metadata.description) || '';\nconst screenshot = data.screenshot || null;\n\nreturn [{ json: {\n url: prep.url,\n session_id: prep.session_id,\n execution_id: prep.execution_id,\n title,\n description,\n markdown: truncated ? markdown.slice(0, MAX_MD) + '\\n\\n[...truncated at 50,000 chars]' : markdown,\n links,\n screenshot,\n credits_used: 1,\n cache_hit: false,\n scraped_at: new Date().toISOString(),\n metadata: data.metadata || null\n} }];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
660,
0
],
"id": "fc-native-shape",
"name": "Shape Response"
},
{
"parameters": {
"operation": "executeQuery",
"query": "INSERT INTO public.firecrawl_credit_ledger (session_id, execution_id, operation, credits_used, url, status, metadata)\nVALUES (\n $1::jsonb->>'session_id',\n $1::jsonb->>'execution_id',\n 'scrape_native',\n (($1::jsonb)->>'credits_used')::int,\n $1::jsonb->>'url',\n 'ok',\n jsonb_build_object('node', 'native', 'title', $1::jsonb->>'title')\n);",
"options": {
"queryReplacement": "={{ JSON.stringify($json) }}"
}
},
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.6,
"position": [
880,
0
],
"id": "fc-native-ledger",
"name": "Log Credit Ledger"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "n1",
"name": "url",
"value": "={{ $('Shape Response').first().json.url }}",
"type": "string"
},
{
"id": "n2",
"name": "title",
"value": "={{ $('Shape Response').first().json.title }}",
"type": "string"
},
{
"id": "n3",
"name": "markdown",
"value": "={{ $('Shape Response').first().json.markdown }}",
"type": "string"
},
{
"id": "n4",
"name": "links",
"value": "={{ $('Shape Response').first().json.links }}",
"type": "array"
},
{
"id": "n5",
"name": "scraped_at",
"value": "={{ $('Shape Response').first().json.scraped_at }}",
"type": "string"
},
{
"id": "n6",
"name": "cache_hit",
"value": "={{ false }}",
"type": "boolean"
},
{
"id": "n7",
"name": "credits_used",
"value": "={{ $('Shape Response').first().json.credits_used }}",
"type": "number"
},
{
"id": "n8",
"name": "screenshot",
"value": "={{ $('Shape Response').first().json.screenshot }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1100,
0
],
"id": "fc-native-return",
"name": "Return Scraped"
}
],
"connections": {
"When Executed by Another Workflow": {
"main": [
[
{
"node": "Prep Input",
"type": "main",
"index": 0
}
]
]
},
"Prep Input": {
"main": [
[
{
"node": "Firecrawl: Scrape",
"type": "main",
"index": 0
}
]
]
},
"Firecrawl: Scrape": {
"main": [
[
{
"node": "Shape Response",
"type": "main",
"index": 0
}
]
]
},
"Shape Response": {
"main": [
[
{
"node": "Log Credit Ledger",
"type": "main",
"index": 0
}
]
]
},
"Log Credit Ledger": {
"main": [
[
{
"node": "Return Scraped",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
[FC Sub] Scrape URL — Native Firecrawl Node. Uses executeWorkflowTrigger, n8n-nodes-firecrawl, postgres. Event-driven trigger; 8 nodes.
Source: https://github.com/MinaSaad1/n8n-firecrawl-web-crawler-agent/blob/main/workflows/03b-sub-scrape-native-firecrawl.json — 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.
W4.1 - ROUTER (State + Voice). Uses executeWorkflowTrigger, postgres, redis. Event-driven trigger; 30 nodes.
SHEETS RAG. Uses googleDriveTrigger, postgres, googleSheets, executeWorkflowTrigger. Event-driven trigger; 24 nodes.
Gmail-Calendar. Uses executeWorkflowTrigger, postgres, googleCalendar, httpRequest. Event-driven trigger; 12 nodes.
Gmail-Triage. Uses executeWorkflowTrigger, httpRequest, postgres. Event-driven trigger; 10 nodes.
Gmail-Governance. Uses executeWorkflowTrigger, gmail, postgres. Event-driven trigger; 10 nodes.