n8n Advanced Workflows: Build AI-Powered Automations with Custom Code Nodes (2026)
This guide is for developers who've outgrown n8n basics and want custom logic: Code nodes, sub-workflows, error handling, AI agents, and webhook-triggered scraping with Apify. You'll also see how to self-host n8n and when Make.com might fit better.
Try Make.com for no-code automations → | Apify for web data →
Who This Is For
You've built a few n8n workflows. Triggers, HTTP requests, and basic transforms work. Now you need:
- Custom logic that doesn't fit a standard node
- Reusable workflows called from others
- Robust error handling and retries
- AI-powered decisions in the middle of a flow
- Webhook-triggered scraping with Apify
Code Node: JavaScript and Python
The Code node runs JavaScript or Python inside n8n. You get full access to upstream data.
Data access:
$input.all()— All items from previous node(s)$input.first()— First item$input.item— Current item (when processing one at a time)$json— Data from the current item$env— Environment variables (e.g. API keys)
Example (JavaScript): Transform and filter
const items = $input.all();
const query = $json.query || "default";
const filtered = items.filter(i => i.json.score > 0.5);
return filtered.map(i => ({
json: {
...i.json,
normalized: i.json.value / 100,
source: "n8n-code"
}
}));
Example (Python): Same logic
items = $input.all()
query = items[0].get("json", {}).get("query", "default")
filtered = [i for i in items if i.get("json", {}).get("score", 0) > 0.5]
return [{"json": {**i["json"], "normalized": i["json"].get("value", 0) / 100, "source": "n8n-code"}} for i in filtered]
Return an array of objects with a json property. Each becomes an item for the next node.
Expressions and Data Mapping
Beyond the Code node, n8n's expression language lets you reference upstream data without writing JavaScript. Use {{ $json.fieldName }} to pull values from the previous node. For arrays, use {{ $json.items[0].url }}. Expressions work in any field that supports them—HTTP request bodies, condition checks, and node parameters. When expressions aren't enough, drop in a Code node for full control.
Sub-workflows
Call one workflow from another. Use the Execute Workflow node.
- Create a child workflow (e.g. "Process Scraped Data")
- In the parent, add Execute Workflow
- Select workflow by ID or name
- Pass data via the input — the child receives it as
$input
Use sub-workflows for:
- Reusable logic (deduplication, formatting)
- Parallel branches (call same workflow with different params)
- Isolated error handling (child fails → parent can retry or route)
Error Handling
Error Trigger node — Runs when another workflow fails. Use it to:
- Notify via Slack/email
- Log to a database
- Push to a dead-letter queue
Retry strategies — In workflow settings, set:
- Max retries (e.g. 3)
- Retry interval (e.g. 30 seconds)
- Retry on specific errors (timeout, 5xx)
Dead-letter webhook — If all retries fail, n8n can POST to a URL with the error payload. Use it to archive failures for later inspection.
AI Agent Workflow
n8n's AI Agent node is LangChain-based. It can:
- Use OpenAI or Anthropic
- Call tools (web search, database lookup, HTTP)
- Maintain conversation memory
Example: Webhook → AI Agent → response
- Webhook trigger (POST with
{"question": "..."}) - AI Agent node: system prompt = "You are a research assistant. Use web search when needed."
- Tools: add a tool that calls an API (e.g. Apify run)
- Respond with the agent's answer (HTTP Respond or another action)
For scraping-then-analysis, chain: Webhook → Apify HTTP Request → AI Agent (with scraped data as context) → response. See the Apify n8n guide for webhook patterns.
Webhook-Triggered Scraping: n8n + Apify
Typical flow:
- Trigger: Webhook receives
{"urls": ["https://..."], "query": "..."} - Start Apify run: HTTP Request to
POST https://api.apify.com/v2/acts/%7BactorId%7D/runs?fpr=use-apifywithAuthorization: Bearer {token}and JSON body - Wait: Apify runs asynchronously. Don't wait in n8n — use webhooks.
- Callback: Configure Apify Actor to POST to an n8n webhook on
SUCCEEDED - Process: n8n webhook receives
defaultDatasetId, fetches dataset items viaGET https://api.apify.com/v2/datasets/%7Bid%7D/items?fpr=use-apify - Downstream: Route to AI, CRM, or database
n8n's async webhook model avoids Zapier's 30-second timeout. Apify can run for minutes; when done, it pushes results to n8n. See Make.com Apify web scraping for a no-code alternative.
Custom Credentials
n8n supports 100+ integrations. Store API keys in Credentials (Settings → Credentials). Reference them in nodes via the credential selector. Use generic "Header Auth" or "HTTP Request" credentials for custom APIs like Apify.
Self-Hosting n8n with Docker
# docker-compose.yml
services:
n8n:
image: n8nio/n8n
restart: unless-stopped
ports:
- "5678:5678"
environment:
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=admin
- N8N_BASIC_AUTH_PASSWORD=your_secure_password
volumes:
- n8n_data:/home/node/.n8n
volumes:
n8n_data:
Run: docker compose up -d. n8n at http://localhost:5678.
For local webhooks, use ngrok: ngrok http 5678. Use the ngrok URL as the Apify webhook target.
n8n vs Make.com for Advanced Developer Workflows
| Feature | n8n | Make.com |
|---|---|---|
| Code execution | Full JavaScript/Python in Code node | Limited (functions, JSON) |
| Sub-workflows | Execute Workflow node | Scenarios in scenarios (limited) |
| Self-hosting | Yes (Docker, npm) | No |
| Error handling | Error Trigger, retries, dead-letter | Error routes, retries |
| AI Agent | LangChain-based, custom tools | Native AI Agents, visual builder |
| Pricing | Free self-hosted; cloud from ~$24/mo | From ~$10.59/mo (operations) |
| Best for | Developers, custom logic, self-hosting | Non-devs, rapid prototyping, 3000+ apps |
Choose n8n when you need Code nodes, sub-workflows, or self-hosting. Choose Make.com when you want the fastest path to production with minimal code. Both integrate with Apify; see Make + Apify and the LangChain Apify content pipeline for pipeline patterns.
Add a Code node to your next n8n workflow. Use $input.all() and return an array of items. For no-code Apify pipelines, try Make.com.
Yes. Select 'Python' in the Code node. Requires Python to be available in the n8n environment (default in Docker).
Use Execute Workflow node. The input you pass becomes $input in the child workflow. Pass JSON or item array.
Via the @apify/n8n-nodes-apify community node. Or use HTTP Request node with Apify REST API.
Yes. Run ngrok http 5678. Use the ngrok URL as the webhook URL. Configure Apify to POST to it on run completion.
n8n: async webhooks, no 30s timeout, Code node for transformations. Make: more integrations, simpler for non-devs. Both work.




