Industry Solutions

Leveraging Code in n8n Workflows: From Basic Automation to Custom AI Agents

Learn how to use code nodes in n8n to build powerful workflow automation with custom logic, API integrations, vector stores, and AI agents. Expert guide with examples.

A

Andrew Snyder

AI & Automation Editor

May 29, 2026 min read
Share:

Introduction

Workflow automation platforms like n8n empower users to connect hundreds of services without writing a single line of code – until they need something custom. That's where code becomes your superpower. n8n's built-in code nodes let you inject JavaScript or Python directly into your workflows, enabling arbitrary data transformations, API orchestration, and even the creation of custom AI agents.

In this comprehensive guide, we'll walk through the various ways to use code inside n8n, covering everything from simple data manipulation to advanced integrations with vector stores, chat models, and cloud services. Whether you're a seasoned developer or a power user looking to extend your automations, these techniques will help you build more resilient and intelligent software pipelines.

Understanding Code Nodes in n8n

tn8n offers several node types that accept custom code. The most common are:

  • Code Node – Execute JavaScript (Node.js) or Python (via Pyodide) to transform data, call APIs, or implement business logic.
  • Function Node (deprecated in favor of Code node) – Similar functionality but limited to JavaScript.
  • Item Lists Node – Combine or split items using code expressions (no full execution environment).
  • Sub-workflow Node – Call external workflows; you can pass workflow IDs and return data for complex orchestration.

Additionally, the newer AI/ML nodes (Chat Model, Vector Store, etc.) can be configured with code to customize retrieval chains or memory.

Key Capabilities

CapabilityDescription
Data TransformationMap, filter, reduce, and reshape incoming data using JavaScript/Python.
API IntegrationMake HTTP requests to any REST or GraphQL endpoint, handle authentication, and parse responses.
Custom TriggersWrite code that creates custom triggers (e.g., polling from a non-standard source).
AI Agent LogicUse code to implement RAG (Retrieval-Augmented Generation) with vector stores and chat completions.
Credential ManagementAccess credentials (e.g., OAuth tokens) inside your code safely.

Using JavaScript Code Nodes

The Code node (JavaScript) runs in a Node.js 20 environment with many common libraries pre-installed (e.g., axios, lodash, dayjs). It receives an array of items from the previous node and must return an array of items.

Example: Parse and Enrich Customer Data

Suppose you receive a Google Sheet row with a customer's first name and last name. You want to create a full name, add a timestamp, and look up the company domain using the Clearbit API.

// Code node input: items = [{json: {firstName: 'Jane', lastName: 'Doe'}}]
const results = [];

for (const item of items) {
  const person = item.json;
  const fullName = `${person.firstName} ${person.lastName}`;

  // Call Clearbit API (using credentials stored in n8n)
  const response = await this.helpers.httpRequest({
    method: 'GET',
    url: `https://person.clearbit.com/v2/combined/find?email=${encodeURIComponent(person.email)}`,
    headers: {
      'Authorization': `Bearer ${this.getWorkflowStaticData('global').clearbitKey}`
    }
  });

  results.push({
    json: {
      ...person,
      fullName,
      enrichedAt: new Date().toISOString(),
      company: response?.company?.name || ''
    }
  });
}

return results;

Best Practice: Always handle errors gracefully by wrapping API calls in try/catch and using continue to skip failed items.

Python Code Nodes (Beta)

n8n now supports Python via Pyodide (WebAssembly). While not as feature-complete as JavaScript, it's excellent for data scientists who prefer pandas-like operations or need to run model inference locally.

import json
import math

# Input items are available as a list of dicts
items = globals().get('items', [])
result = []

for item in items:
    data = item['json']
    if 'revenue' in data and 'cost' in data:
        profit_margin = (data['revenue'] - data['cost']) / data['revenue'] * 100
        data['profitMargin'] = round(profit_margin, 2)
    result.append({'json': data})

# Output must be a list of dicts with 'json' key
print(json.dumps(result))

⚠️ Python nodes cannot use await or make HTTP requests directly; use the HTTP Request node for that.

Working with Data Transformations

One of the most frequent uses of code in n8n is transforming data between nodes. You can:

  • Filter items based on complex conditions.
  • Merge data from multiple sources (e.g., combine Google Calendar events with Microsoft To Do tasks).
  • Aggregate arrays – sum, average, or group by custom fields.
  • Validate inputs and generate error reports.

Example: Merging Two Sources

Imagine you have two triggers: one from a Webhook (incoming order) and one from a Schedule Trigger (daily inventory). You need to merge them on a product ID.

// From Webhook trigger: items1 = [{json: {orderId: 123, product: 'A', quantity: 2}}]
// From Schedule trigger: items2 = [{json: {product: 'A', stock: 50}}]

const merged = items1.map(order => {
  const inventory = items2.find(i => i.json.product === order.json.product);
  return {
    json: {
      ...order.json,
      stockAtOrder: inventory?.json?.stock || 0,
      canFulfill: inventory?.json?.stock >= order.json.quantity
    }
  };
});
return merged;

Integrating External APIs with Code

While n8n has hundreds of pre-built nodes for services like Google, Microsoft, Slack, Shopify, etc., you may need to call an API that isn't listed. Use the HTTP Request node for simple calls, but for complex authentication (OAuth2 with refresh, custom signing) or multiple sequential calls, code gives you full control.

Custom OAuth2 Token Refresh

Many cloud services require token rotation. Inside a Code node, you can manually check token expiry and refresh:

const staticData = this.getWorkflowStaticData('global');
if (!staticData.accessToken || Date.now() > staticData.tokenExpiresAt) {
  const response = await this.helpers.httpRequest({
    method: 'POST',
    url: 'https://auth.service.com/oauth/token',
    body: {
      grant_type: 'refresh_token',
      refresh_token: staticData.refreshToken,
      client_id: 'xxx',
      client_secret: 'yyy'
    }
  });
  staticData.accessToken = response.access_token;
  staticData.tokenExpiresAt = Date.now() + response.expires_in * 1000 - 60000; // 1 min buffer
}

Important: Never hardcode secrets in code. Use n8n's credentials system (see section below).

Building Custom Triggers

Out-of-the-box triggers cover polling, webhooks, email, and many SaaS platforms. But what if your source publishes to a WebSocket or uses a proprietary protocol? You can build a custom trigger using the Code node combined with the Manual Trigger and a loop (or use the Execute Command node for long-running scripts).

Polling with a Custom Interval

Use the Schedule Trigger to run every minute, then within a Code node, fetch data from a custom API and compare IDs to detect changes.

const staticData = this.getWorkflowStaticData('global');
const lastCheckId = staticData.lastId || 0;

const { data } = await this.helpers.httpRequest({
  url: 'https://api.example.com/items?sinceId=' + lastCheckId
});

if (data.items.length > 0) {
  staticData.lastId = data.items[data.items.length - 1].id;
  return data.items.map(item => ({ json: item }));
} else {
  return []; // no new items, workflow stops
}

The workflow will only continue if new data exists – perfect for event-driven automation.

Leveraging AI/ML with Code: Vector Stores, Chat Models, and Custom AI Agents

n8n's AI capabilities are rapidly expanding. You can now build custom AI agents that combine vector stores (e.g., Pinecone, Qdrant, MongoDB Atlas Vector Store) with chat models (OpenAI, Google Gemini, Microsoft 365 Agents) and custom tools. Code nodes are essential for orchestrating these interactions.

Creating a RAG Pipeline

A typical retrieval-augmented generation pipeline:

  1. Trigger receives a user query (e.g., from Chat trigger).
  2. Code node 1: Preprocess the query (spell-check, extract entities).
  3. Vector Store node: Perform similarity search against embedded documents.
  4. Code node 2: Format retrieved chunks into a prompt template.
  5. Chat Model node: Get completion (e.g., GPT-4).
  6. Code node 3: Post-process the answer (filter, add citations).
// Code node 2: Build prompt
const query = $json.query;
const chunks = $json.retrievedChunks; // from vector store
const context = chunks.map(c => c.pageContent).join('\
\
');
return [{
  json: {
    system: 'You are a helpful assistant. Use the context to answer.',
    user: `Context: ${context}\
\
Question: ${query}`
  }
}];

Custom Tool for an AI Agent

AI Agent nodes in n8n can use custom tools written in code. For example, a Code node can act as a tool that returns the current weather:

const location = items[0].json.location; // provided by the agent
const weather = await this.helpers.httpRequest({
  url: `https://api.openweathermap.org/data/2.5/weather?q=${location}&appid=${$credentials.openWeatherMap.apiKey}`
});
return [{ json: { result: weather.main.temp } }];

Then reference this Code node as a tool inside the Agent configuration.

Managing Credentials Securely in Code

Never embed API keys directly in your code. Instead, use n8n's credentials system:

  • Create a credential of type "Custom Credential" (or use an existing one like OAuth2, API Key).
  • In your Code node, access it via $credentials.credentialName.
  • For dynamic credentials, use this.getWorkflowStaticData('global') to store session tokens.

Example accessing a Google service account:

const { privateKey, clientEmail } = $credentials.googleServiceAccount;
// Now use these to sign JWT or call Google APIs

Security tip: Always use the principle of least privilege – grant your software only the scopes it needs.

Best Practices and Real-World Examples

1. Keep Code Nodes Focused

Each Code node should do one thing well. Break complex logic into multiple nodes – this improves readability, debugging, and reuse.

2. Use Input/Output Schema

Document the expected data structure at the start of your code with comments or a schema. This helps when revisiting months later.

3. Error Handling and Retries

Wrap critical sections in try/catch. Use the Error Trigger to notify on failures. For temporary errors, implement exponential backoff.

4. Performance Tuning

Avoid heavy loops inside Code nodes – n8n already paginates through items. Use Item Lists node for splitting/joining before processing.

5. Real-World Use Case: Automated Lead Enrichment

A workflow triggered by a Webhook receives a new lead (name, email). The code:

  • Cleans email (lowercase, remove dots).
  • Calls Clearbit (via code with credential) to get company info.
  • Uses Google Geocoding API to get lat/lng.
  • Stores enriched lead in Airtable (or MongoDB Cloud).
  • Sends a Slack notification with a summary.

This entire pipeline runs in under 10 seconds and saved a sales team 20 hours/week of manual research.

Conclusion

The ability to write code inside n8n workflows unlocks infinite possibilities. From simple data transformations to sophisticated custom AI agents that query vector stores and invoke chat models, the code node is your Swiss Army knife. By following the best practices outlined here – especially around credentials and error handling – you'll build robust, maintainable automations that scale.

Start small: try transforming a JSON payload from a Google Sheets trigger. Then experiment with integrating a Microsoft Graph API. Soon you'll be orchestrating entire business processes with code that talks to any software or cloud service.

Ready to go deeper? Explore n8n's official docs on the Code node, and join the community to share your custom workflow patterns.

Frequently Asked Questions

What is the best way to get started with Leveraging Code in n8n Workflows: From B?

The best approach is to start with a clear goal in mind. Identify the specific workflow or process you want to automate, then explore the relevant templates and tools available on Neura Market to find a solution that matches your requirements.

How much does workflow automation typically cost?

Costs vary significantly depending on the platform and scale. Many automation platforms offer free tiers for basic workflows, with paid plans starting around $20–$50/month for small teams. Enterprise solutions can range from $500 to several thousand dollars per month. Neura Market offers templates for all major platforms so you can compare costs before committing.

Do I need technical skills to implement workflow automation?

Modern no-code and low-code platforms like Zapier, Make.com, and others have made automation accessible to non-technical users. Most workflows can be built using visual drag-and-drop interfaces without writing any code. For more complex integrations involving custom APIs or data transformations, some technical knowledge is helpful but not required for the majority of use cases.

The #1 Newsletter in AI

Stay ahead of the AI curve

The most important updates, news, and content — delivered in one weekly newsletter.

No spam. Unsubscribe anytime. Privacy policy

Build it yourself

This guide pairs with an automation platform. Start building on it for free.

Try n8n
credentials
trigger
google
software
microsoft
ai-agents
A

About Andrew Snyder

AI & Automation Editor

Andrew covers practical AI automation, workflow design, and the tools teams use to streamline everyday operations.

Comments (0)