---
name: n8n-workflow-specialist
description: Design, configure, debug, and optimize n8n workflows. Write n8n expressions, create custom function nodes, set up webhooks, manage credentials, integrate APIs, troubleshoot workflow errors, and optimize performance. Use when building n8n automations, debugging workflow issues, writing expressions, configuring nodes, or improving workflow efficiency.
---

# n8n Workflow Specialist

## Overview
This skill provides comprehensive support for n8n workflow automation, including workflow design, node configuration, expression writing, debugging, and performance optimization.

## Instructions

### When to Use This Skill
Activate this skill when the user needs help with:
- Designing new n8n workflows from scratch
- Configuring specific n8n nodes (HTTP Request, Webhook, Code, etc.)
- Writing n8n expressions for data transformation
- Debugging workflow errors and failed executions
- Optimizing workflow performance and costs
- Setting up API integrations and webhooks
- Managing credentials and authentication
- Creating custom Code nodes with JavaScript
- Understanding n8n workflow patterns

### Core Capabilities

#### 1. Workflow Design & Architecture
- **Start with the trigger**: Identify the right trigger type (Webhook, Schedule, Manual, Email, etc.)
- **Plan the flow**: Map out the sequence of operations logically
- **Data flow**: Understand how data passes between nodes
- **Error handling**: Add error workflows for robustness
- **Testing strategy**: Use sample data before production deployment

Best practices:
- Keep workflows focused on a single purpose
- Use meaningful node names for clarity
- Group related operations together
- Add notes/sticky notes to document complex logic
- Use subworkflows for reusable components

#### 2. Expression Writing
n8n uses a powerful expression language for data manipulation. Key syntax:

**Accessing Data:**
- Current item: `{{ $json.fieldName }}`
- Previous node: `{{ $node["Node Name"].json.fieldName }}`
- Input data: `{{ $input.item.json.fieldName }}`
- All items: `{{ $items() }}`

**JavaScript Methods:**
- String operations: `.toLowerCase()`, `.toUpperCase()`, `.trim()`, `.split()`, `.replace()`
- Array methods: `.map()`, `.filter()`, `.find()`, `.reduce()`
- Date operations: `new Date()`, `.toISOString()`, `DateTime.now()`

**Conditional Logic:**
- Ternary: `{{ condition ? valueIfTrue : valueIfFalse }}`
- If function: `{{ $if(condition, trueValue, falseValue) }}`

**Common Patterns:**
```javascript
// Format date
{{ DateTime.now().toFormat('yyyy-MM-dd') }}

// Extract email domain
{{ $json.email.split('@')[1] }}

// Conditional value
{{ $json.status === 'active' ? 'Active User' : 'Inactive User' }}

// Transform array
{{ $json.users.map(user => user.email) }}

// Parse JSON string
{{ JSON.parse($json.data) }}

// Format currency
{{ parseFloat($json.amount).toFixed(2) }}
```

#### 3. Node Configuration

**HTTP Request Node:**
1. Choose request method (GET, POST, PUT, DELETE)
2. Enter URL (can use expressions)
3. Set authentication (None, Basic, OAuth2, Header, etc.)
4. Add headers if needed
5. Configure body for POST/PUT requests
6. Test with sample data

**Webhook Node:**
1. Choose "Webhook" trigger
2. Set HTTP method (GET, POST, etc.)
3. Configure path (optional)
4. Copy webhook URL for external services
5. Set up response (important for synchronous webhooks)
6. Test with curl or Postman

**Code Node:**
1. Choose between "Run Once for All Items" or "Run Once for Each Item"
2. Write JavaScript code
3. Access items with `items` or `$input.item`
4. Return data: `return items;` or `return [{json: {result: 'value'}}];`
5. Use console.log() for debugging (visible in executions)

**Set Node:**
- Transform data without code
- Add, remove, or modify fields
- Use expressions for dynamic values
- Simpler than Code node for basic transformations

**IF Node:**
- Branch workflow based on conditions
- Configure multiple conditions with AND/OR logic
- Route data to different paths
- Essential for conditional workflows

**Merge Node:**
- Combine data from multiple branches
- Modes: Append, Merge By Fields, Keep Key Matches
- Useful after IF nodes or parallel operations

#### 4. Debugging Workflows

**Common Error Types:**

**401 Unauthorized:**
- Check credentials are configured correctly
- Verify API key hasn't expired
- Ensure correct authentication method selected
- Check required headers (Authorization, Content-Type)

**404 Not Found:**
- Verify URL is correct
- Check if endpoint exists in API documentation
- Ensure dynamic URL expressions evaluate correctly

**Expression Errors:**
- Verify node names match exactly (case-sensitive)
- Check JSON structure with debug panel
- Test expressions in the expression editor
- Ensure referenced fields exist in previous node output

**Timeout Errors:**
- Increase timeout in node settings
- Check if external API is slow or down
- Consider pagination for large data sets
- Optimize queries to reduce response time

**Debugging Tools:**
- Use the execution panel to inspect each node's output
- Enable "Continue on Fail" for error workflows
- Add "Stop and Error" nodes to catch issues
- Use console.log() in Code nodes
- Check execution logs in the workflow history

#### 5. Performance Optimization

**Reduce Execution Time:**
- Minimize HTTP requests (batch when possible)
- Use Set nodes instead of Code nodes for simple transformations
- Implement pagination for large datasets
- Run independent operations in parallel with Split In Batches

**Reduce Costs:**
- Limit workflow executions with appropriate triggers
- Use static values instead of expressions when possible
- Implement caching for frequently accessed data
- Deactivate unused workflows

**Improve Reliability:**
- Add retry logic with Error Trigger
- Implement exponential backoff for API calls
- Validate data before processing
- Use error workflows to handle failures gracefully

#### 6. Common Integration Patterns

**Webhook → Process → Respond:**
```
Webhook (Wait for Webhook Call)
  → Validate Data (IF node)
  → Process (HTTP Request / Code)
  → Respond to Webhook
```

**Schedule → Fetch → Transform → Store:**
```
Schedule Trigger (Cron)
  → Fetch Data (HTTP Request)
  → Transform (Set / Code)
  → Store (Database / Google Sheets)
```

**Email → Parse → Notify:**
```
Email Trigger (IMAP)
  → Extract Attachments
  → Parse Content (Code)
  → Send Notification (Slack / Discord)
```

**Event → Enrich → Multi-destination:**
```
Webhook
  → Fetch Additional Data (HTTP Request)
  → IF (Route by condition)
    → Path 1 (Slack notification)
    → Path 2 (Database update)
    → Path 3 (Email alert)
```

## Examples

### Example 1: Creating an Email-to-Slack Automation

**Use Case:** Send Slack notifications when receiving important emails

**Workflow:**
1. **Gmail Trigger** - Monitor inbox for new emails
2. **IF Node** - Filter by subject contains "URGENT"
3. **Set Node** - Extract and format data:
   ```
   Subject: {{ $json.subject }}
   From: {{ $json.from.email }}
   Preview: {{ $json.snippet }}
   Link: {{ $json.webLink }}
   ```
4. **Slack Node** - Send formatted message to #alerts channel
5. **Gmail Node** - Mark email as read and add label

**Key Expression:**
```javascript
// Format Slack message
{
  "text": "🚨 Urgent Email Received",
  "blocks": [
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": `*From:* {{ $json.from.email }}\n*Subject:* {{ $json.subject }}\n\n{{ $json.snippet }}`
      }
    }
  ]
}
```

### Example 2: Debugging a 401 Authentication Error

**Scenario:** HTTP Request node returns 401 Unauthorized

**Debugging Steps:**
1. Check credential configuration in node settings
2. Verify credential is correctly set up in Credentials panel
3. Test API key manually with curl:
   ```bash
   curl -H "Authorization: Bearer YOUR_API_KEY" https://api.example.com/endpoint
   ```
4. Check API documentation for required headers
5. Verify authentication method (Bearer, Basic, API Key, OAuth2)
6. Check if API key has required permissions
7. Ensure no typos in header names (e.g., "Authorization" not "Authorisation")

**Common Fixes:**
- Re-create credential with correct API key
- Add missing headers (User-Agent, Content-Type)
- Switch authentication method
- Update expired OAuth2 token

### Example 3: Writing Complex Data Transformation

**Use Case:** Transform API response to match database schema

**Input Data:**
```json
{
  "customer": {
    "fullName": "John Doe",
    "contactInfo": {
      "email": "john@example.com",
      "phone": "+1234567890"
    },
    "orders": [
      {"id": 1, "total": "99.50"},
      {"id": 2, "total": "149.99"}
    ]
  }
}
```

**Code Node:**
```javascript
// For all items
const results = [];

for (const item of items) {
  const customer = item.json.customer;

  results.push({
    json: {
      name: customer.fullName.trim(),
      email: customer.contactInfo.email.toLowerCase(),
      phone: customer.contactInfo.phone,
      total_orders: customer.orders.length,
      total_spent: customer.orders.reduce((sum, order) =>
        sum + parseFloat(order.total), 0
      ).toFixed(2),
      last_order_id: customer.orders[customer.orders.length - 1].id
    }
  });
}

return results;
```

**Alternative with Set Node (simpler):**
- name: `{{ $json.customer.fullName.trim() }}`
- email: `{{ $json.customer.contactInfo.email.toLowerCase() }}`
- total_orders: `{{ $json.customer.orders.length }}`
- total_spent: `{{ $json.customer.orders.reduce((sum, o) => sum + parseFloat(o.total), 0).toFixed(2) }}`

### Example 4: Implementing Error Handling

**Pattern:**
```
Main Workflow Node
  → IF Node (Check for errors)
    → Success Path
    → Error Path
      → Log to Database
      → Send Alert (Slack/Email)
      → Optional: Retry Logic
```

**Error Trigger Workflow:**
Create separate workflow:
1. **Error Trigger** - Activates when any workflow fails
2. **Set Node** - Format error details:
   ```
   Workflow: {{ $json.workflow.name }}
   Node: {{ $json.node.name }}
   Error: {{ $json.error.message }}
   Time: {{ $json.executionId }}
   ```
3. **Slack Node** - Alert team
4. **Google Sheets Node** - Log for analysis

## Tips for Success

- **Test incrementally**: Test each node as you build, don't wait until the end
- **Use meaningful names**: Rename nodes to describe what they do
- **Check data structure**: Use the debug panel to see actual data format
- **Start simple**: Begin with basic workflow, add complexity gradually
- **Document assumptions**: Add sticky notes to explain complex logic
- **Handle errors**: Always plan for failure scenarios
- **Monitor executions**: Regularly check execution logs for issues
- **Use subworkflows**: Break complex workflows into reusable components
- **Version control**: Export workflows regularly as backup
- **Consult documentation**: Refer to n8n docs for node-specific details at https://docs.n8n.io/

## Additional Resources

For more detailed guidance, see:
- [EXPRESSIONS.md](EXPRESSIONS.md) - Comprehensive expression syntax reference
- [TROUBLESHOOTING.md](TROUBLESHOOTING.md) - Common issues and solutions

## n8n Documentation
- Official docs: https://docs.n8n.io/
- Expression reference: https://docs.n8n.io/code-examples/expressions/
- Node library: https://docs.n8n.io/integrations/builtin/
- Community forum: https://community.n8n.io/
