n8n AI Agents: Build Business Automations That Sell (2026 Guide)
What You Will Master in This Tutorial
- Set up Python 3.12+ and write clean, readable, PEP 8-compliant code.
- Work with fundamental data structures: Lists, Dictionaries, Sets, and Tuples.
- Control program execution flow with conditionals, loops, and list comprehensions.
- Encapsulate logic into reusable functions with type hints and default arguments.
- Understand Object-Oriented Programming (OOP) in Python: Classes, Methods, and Inheritance.
- Test and execute your scripts interactively using the Online Code Playground.
n8n is where AI demos become business systems. A model in a chat window answers questions. A model inside an n8n workflow watches an inbox, qualifies a lead, updates a CRM, books a meeting and sends a summary to Slack β at 2 a.m., without anyone opening a chat window. That's why n8n has quietly become the backbone of thousands of small automation agencies: it's visual enough to build fast, code-friendly enough to go deep, self-hostable so your costs stay flat, and it has first-class AI agent nodes that plug into Claude, ChatGPT and open models. This guide installs it, builds your first workflow node by node, constructs a real AI agent with tools, and finishes with the two use cases that sell best β plus what to charge for them.
Install n8n the right way: self-hosted with Docker
You can try n8n in the cloud in two minutes, but for client work, self-hosting wins: flat cost (one small VPS runs dozens of workflows), your clients' data stays on infrastructure you control, and there are no per-execution surprises. The production-friendly setup is Docker Compose with a real database:
# docker-compose.yml
services:
n8n:
image: n8nio/n8n:latest
restart: unless-stopped
ports:
- "5678:5678"
environment:
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=db
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- WEBHOOK_URL=https://automations.yourdomain.com/
volumes:
- n8n_data:/home/node/.n8n
depends_on:
- db
db:
image: postgres:16
restart: unless-stopped
environment:
- POSTGRES_USER=n8n
- POSTGRES_DB=n8n
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
volumes:
- db_data:/var/lib/postgresql/data
volumes:
n8n_data:
db_data:
# Generate keys, launch, and open http://localhost:5678
echo "POSTGRES_PASSWORD=$(openssl rand -hex 24)" >> .env
echo "N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)" >> .env
docker compose up -d
Three details separate a toy install from a client-safe one: Postgres instead of the default SQLite (it survives volume and concurrency), an encryption key stored outside the container (lose it and every saved credential is unreadable), and a real domain with HTTPS behind the webhook URL, because OAuth callbacks and most webhooks refuse plain HTTP. Put a reverse proxy (Caddy or Nginx) in front before the first client touches it.
Anatomy of a workflow
Every n8n workflow is the same four ideas:
- Trigger β what starts it: a schedule, a webhook, a new email, a form submission, a new row in a sheet.
- Nodes β steps that fetch, transform or send data. Data flows as JSON items from node to node; if you can read JSON, you can debug n8n.
- Credentials β encrypted connections to services (Gmail, Slack, your model API keys), stored once and reused.
- Executions β every run is logged with its full data. When something breaks at 3 a.m., the execution log is where you'll live.
Your first workflow: a lead alert that never sleeps
Goal: when a website form is submitted, save the lead to a Google Sheet and post a formatted alert to Slack within seconds. The workflow JSON structure, node by node:
- Webhook trigger (POST, path
/new-lead) β your form points here. It receives{name, email, phone, message, source}. - Set node β normalize: trim fields, add
received_attimestamp and astatusof "new". Clean data here saves pain everywhere downstream. - Google Sheets node β append one row per lead to the "Leads" sheet.
- Slack node β post to #sales: name, contact, message excerpt and a link to the sheet row.
- Respond to Webhook β return
{"ok": true}so the form can show a thank-you state.
Exported, the skeleton looks like this (trimmed for readability β in n8n you can copy JSON like this and paste it straight onto the canvas):
{
"name": "Lead Alert",
"nodes": [
{ "type": "n8n-nodes-base.webhook",
"name": "Form Submitted",
"parameters": { "path": "new-lead", "httpMethod": "POST" },
"position": [240, 300] },
{ "type": "n8n-nodes-base.set",
"name": "Normalize Lead",
"parameters": { "assignments": { "assignments": [
{ "name": "status", "value": "new", "type": "string" },
{ "name": "received_at", "value": "={{ $now.toISO() }}",
"type": "string" }
]}},
"position": [460, 300] },
{ "type": "n8n-nodes-base.googleSheets",
"name": "Save to Sheet",
"parameters": { "operation": "append" },
"position": [680, 300] },
{ "type": "n8n-nodes-base.slack",
"name": "Alert Sales",
"parameters": { "channel": "#sales",
"text": "New lead: {{ $json.name }} β {{ $json.message }}" },
"position": [900, 300] }
],
"connections": {
"Form Submitted": { "main": [[{ "node": "Normalize Lead" }]] },
"Normalize Lead": { "main": [[{ "node": "Save to Sheet" }]] },
"Save to Sheet": { "main": [[{ "node": "Alert Sales" }]] }
}
}
Activate the workflow, submit a test form, and watch the execution appear. You now own the pattern behind 80% of paid automations: event β clean β store β notify.
Now make it an agent: the AI Agent node with tools
n8n's AI Agent node wraps a model (Claude, GPT, or an open model) with memory and tools it can choose to call. Upgrade the lead workflow: instead of just alerting, let an agent qualify each lead.
- Add an AI Agent node after the Set node. Connect a chat model (for example, Claude via its API credential) and a simple memory so follow-ups keep context.
- Attach tools: an HTTP Request tool to enrich the lead from a data API, a Google Sheets tool so the agent can write its verdict back, and a Calculator/Code tool for anything deterministic.
- Write the system prompt like a job description β what a qualified lead is, exactly what to output, and what never to do:
You are a lead qualification agent for a roofing company.
For each lead you receive:
1. Score the lead 1-10 for fit. Fit means: homeowner,
inside our service area (Austin metro), mentions roof
damage, replacement, or a timeline under 60 days.
2. Write a one-sentence summary of what they need.
3. Save score and summary to the sheet with the
update_lead tool.
4. If the score is 8 or higher, flag it URGENT.
Rules: never invent details that are not in the lead.
If information is missing, score lower and say what
is missing. Output JSON only:
{"score": number, "summary": string, "urgent": boolean}
The discipline here is the product. A narrow job, structured JSON output, explicit anti-hallucination rules β that is what separates an agent a business trusts from a demo that impresses once and misfires in production.
Use case 1: the lead-gen machine (your best seller)
Chain the pieces: form/WhatsApp intake β agent qualification β CRM/Sheet β instant alert for hot leads β automatic follow-up message for the rest. The business problem is universal β leads contacted within 5 minutes convert dramatically better than leads contacted the next morning β and your agent makes 5-minute contact automatic, 24/7.
How it sells: don't pitch "AI". Pitch the leak: "Your site gets inquiries at 9 p.m.; your team answers at 9 a.m. β after the competitor who replied first." Price it as $750β$2,000 setup plus $250β$750/month including monitoring and tweaks, adjusted to your market. Results vary by niche and lead volume; sell the response-time guarantee you control, not conversion miracles you don't.
Use case 2: the inbox agent
Every business owner you know drowns in email. The inbox agent workflow: a Gmail/Outlook trigger reads new mail, an agent classifies it (invoice, support, sales inquiry, noise), drafts replies in the owner's voice for anything routine, routes invoices to a sheet, and posts a morning digest of what actually needs a human. The human approves drafts with one click β the agent never sends sensitive replies alone.
How it sells: time math. "This gives you back 5β8 hours a week" at $500β$1,500 setup plus $200β$500/month is an easy yes for owners billing their own time at $75+/hour. Start with classification + digest only (read-only, zero risk), then add drafting once trust exists.
Running agents in production without tears
- Log everything. Keep each agent's inputs, outputs and tool calls in a sheet or table. When a client says "the agent did something weird", the log is your answer and your debugging tool.
- Fail loudly, not silently. Add an error workflow (n8n supports a global one) that posts failures to your Slack. A dead automation discovered by the client is a churn event; discovered by you, it's a service moment.
- Cap the blast radius. Agents draft, humans approve β for money, commitments and anything public β until a workflow has months of clean history.
- Watch API costs per client. A chatty agent with a big model can quietly eat your margin. Track token spend per workflow and price tiers accordingly.
Your first 14 days with n8n
Days 1β2: install with Docker, connect your model key, rebuild the lead-alert workflow from this guide. Days 3β5: add the qualification agent and break it on purpose β empty forms, gibberish, a lead in another language β and harden the prompt. Days 6β9: build the inbox agent on your own email; live with it; fix what annoys you. Days 10β14: pick one local business type, record a 3-minute demo with their kind of data, and send it to ten of them with a pilot offer. That's the whole secret: n8n skill is common; a working demo aimed at one niche's expensive problem is not. Build the demo, and the selling mostly does itself.
Expressions and the Code node: your escape hatches
Two features keep n8n from ever boxing you in. Expressions β the {{ ... }} snippets you saw in the Slack node β let any field compute values from incoming data: format a date, pull a nested field, build a sentence. And when a no-code node can't express your logic, the Code node runs plain JavaScript (or Python) over the items:
// Code node: keep leads worth a human's attention.
// Input items carry JSON like { name, email, message }
const kept = [];
for (const item of $input.all()) {
const msg = (item.json.message || "").toLowerCase();
const hasIntent = ["quote", "price", "replace", "leak",
"repair", "install"].some(w => msg.includes(w));
item.json.intent = hasIntent ? "buying" : "researching";
item.json.priority = hasIntent ? "high" : "normal";
if (item.json.email) kept.push(item); // drop junk leads
}
return kept;
The working rule of experienced builders: use built-in nodes first (they're maintained, they're readable by the next person), reach for expressions to glue them, and reserve the Code node for logic that's genuinely easier written than clicked. That order keeps workflows maintainable β which matters the first time a client asks you to change something you built six months ago. The same discipline applies to naming: label nodes by what they do ("Score lead", not "Set3"), add sticky notes to complex sections, and future-you β debugging at midnight β will be grateful.
n8n vs. the alternatives, in one honest paragraph
Zapier and Make are easier on day one and cost more every month after; n8n asks a weekend of learning and then charges you roughly the price of a coffee per month in hosting, with no per-task meter running. For client work that math compounds: five clients on per-execution platforms quietly become a second rent payment, while one self-hosted n8n instance carries all five. The trade is responsibility β updates, backups and uptime become yours. For a hobby, choose easy. For a business you intend to sell automations through, choose the tool whose costs stay flat while your revenue grows.