Diving deeper into n8n: node types, best practices …
In the previous chapter we reviewed what process automation is and why tools like n8n have become …
read moreIn previous articles, we explored the fundamentals of n8n, from initial setup to different node types and professional best practices. Now it’s time to take it a step further and work with intermediate concepts you’ll constantly encounter in real-world automations.
This time we’ll build a Pokemon team analyzer that demonstrates essential patterns like processing multiple items, transforming complex data from APIs, and combining information from different sources. While the topic is playful, the concepts you’ll learn apply directly to enterprise use cases like customer data enrichment, inventory analysis, or metrics aggregation.
Try the app: You can experiment with the complete analyzer in action by visiting pokeanalyzer.betazeta.dev before building your own workflow.
Most modern APIs don’t return simple, flat data. Instead, they deliver nested JSON structures with arrays, objects within objects, and references to other endpoints. This is precisely the scenario you’ll face when working with PokéAPI, a free and well-documented API that provides comprehensive information about the Pokemon universe.
An example response from PokéAPI for an individual Pokemon includes:
  {
    "name": "charizard",
    "stats": [
      { "base_stat": 78, "stat": { "name": "hp" } },
      { "base_stat": 84, "stat": { "name": "attack" } },
      { "base_stat": 78, "stat": { "name": "defense" } }
    ],
    "types": [
      { "type": { "name": "fire" } },
      { "type": { "name": "flying" } }
    ],
    "abilities": [
      { "ability": { "name": "blaze" } }
    ]
  }
This level of complexity requires specific techniques to extract, transform, and analyze useful information. Let’s see how to build a workflow that handles this elegantly.
Our Pokemon team analyzer will follow this modular structure accessible via webhook:
This architecture allows us to:
We’ll start with two entry points: a Webhook to receive HTTP requests from external applications, and a Manual Trigger for testing during development. Both connect to the Code (Prepare Input) node.
Webhook node configuration:
pokemon-team-analyzerhttps://pokemon-team-analyzer.netlify.app) or “*” to accept all origins (testing only).Using 'Respond to Webhook' NodeThe webhook expects to receive JSON in this format:
  {
    "names": ["charizard", "blastoise", "venusaur", "pikachu", "gengar", "dragonite"]
  }
   
Code (Prepare Input) node configuration:
This node’s code extracts the names array from the received JSON, validates there are between 2 and 6 Pokemon, normalizes the names (lowercase, no spaces), and converts them to the item format n8n expects for iteration.
📦 Complete code: You can find the full
workflow.jsonfile with the source code in the GitHub repository
The Loop Over Items node (formerly Split In Batches in n8n) is key for intermediate workflows. It allows us to process each element of an array sequentially, executing the following nodes once per item.
Configuration:
loop) executes iterative processing, the second (done) activates when all items have been processedHow the loop works:
Now we’ll use an HTTP Request node to get data for each Pokemon from the API.
HTTP Request configuration:
https://pokeapi.co/api/v2/pokemon/{{ $json.pokemon_name }}The expression {{ $json.pokemon_name }} will be automatically replaced with each Pokemon’s name during iteration. For example, in the first round it will be charizard, in the second blastoise, and so on.
The PokéAPI response is extensive (over 100 lines of JSON). We need to extract only the relevant information in a Code node.
What this node does:
?., ??) to avoid errorsAfter the Loop, we need to aggregate all processed Pokemon to analyze the team as a whole. This Code node connects to the Loop’s “done” output.
What this node does:
safeStat helper functions📦 Complete code: You can find the full
workflow.jsonfile with the source code in the GitHub repository
We’ll use two final nodes: Edit Fields (Format Output) to structure the data, and Respond to Webhook to send the HTTP response.
Edit Fields node configuration:
title: Pokémon Team Analysis (type: String)team_size: {{ $json.team_size }} (type: Number)members: {{ $json.team_members.join(', ') }} (type: String)stats: {{ $json.team_stats }} (type: String/Object)highlights: {{ $json.highlights }} (type: String/Object)type_coverage: {{ $json.type_coverage }} (type: String/Object)Respond to Webhook node configuration:
This final node closes the webhook cycle, automatically sending the HTTP response with the complete analysis in JSON format. This allows external applications (like web frontends, mobile apps, or scripts) to directly consume the analysis.
Result in action: Want to see this workflow running in real-time? Try the practical demo at pokeanalyzer.betazeta.dev and analyze your favorite team.
Once you’ve built the complete workflow, you can test it in several ways: through the Manual Trigger for internal development, or via the webhook with tools like curl, Postman, or your own web application. To make the analyzer truly accessible, we’re going to create a complete web interface that consumes the n8n webhook.
Before building the interface, verify the webhook works correctly:
  curl -X POST https://your-n8n-domain.com/webhook/pokemon-team-analyzer \
    -H "Content-Type: application/json" \
    -d '{
      "names": ["charizard", "blastoise", "venusaur", "pikachu", "gengar", "dragonite"]
    }'
    
Example webhook response:
  [
    {
      "title": "Pokémon Team Analysis",
      "team_size": 3,
      "members": "charizard, blastoise, pikachu",
      "stats": "{\"avg_hp\":64,\"avg_attack\":74,\"avg_defense\":73,\"avg_speed\":89,\"avg_total\":461}",
      "highlights": "{\"strongest\":{\"name\":\"charizard\",\"total_stats\":534},\"fastest\":{\"name\":\"charizard\",\"speed\":100}}",
      "type_coverage": "{\"unique_types\":[\"fire\",\"flying\",\"water\",\"electric\"],\"coverage_count\":4,\"total_types\":4}",
      "detailed_members": [
        {
          "name": "charizard",
          "id": 6,
          "height": 17,
          "weight": 905,
          "stats": {
            "hp": 78,
            "attack": 84,
            "defense": 78,
            "special-attack": 109,
            "special-defense": 85,
            "speed": 100
          },
          "total_stats": 534,
          "types": [
            "fire",
            "flying"
          ],
          "abilities": [
            "blaze",
            "solar-power"
          ],
          "sprite": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/6.png",
          "artwork": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/6.png",
          "dream_world": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/dream-world/6.svg"
        },
        {
          "name": "blastoise",
          "id": 9,
          "height": 16,
          "weight": 855,
          "stats": {
            "hp": 79,
            "attack": 83,
            "defense": 100,
            "special-attack": 85,
            "special-defense": 105,
            "speed": 78
          },
          "total_stats": 530,
          "types": [
            "water"
          ],
          "abilities": [
            "torrent",
            "rain-dish"
          ],
          "sprite": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/9.png",
          "artwork": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/9.png",
          "dream_world": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/dream-world/9.svg"
        },
        ...
      ]
    }
  ]
    
The web interface consumes the n8n webhook through a vanilla HTML/JavaScript application with Tailwind CSS. The implementation includes a 6-field form for Pokemon names, client validation (minimum 2, maximum 6), and dynamic rendering of results with aggregate stats, type coverage, and individual cards for each Pokemon with their official sprites.
The communication flow is straightforward:
  const res = await fetch('https://your-n8n.com/webhook/pokemon-team-analyzer', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ names: ["charizard", "blastoise", ...] })
  });
   
The webhook’s JSON response is processed to display team stats, color-coded type badges (fire=red, water=blue), animated sprites, and loading states with spinners. The design is fully responsive (mobile, tablet, desktop) and handles CORS errors and validations elegantly.
📦 Complete code: Both the n8n workflow (
workflow.json) and the complete web applicationindex.htmlare available in the GitHub repository with detailed deployment instructions.
This pattern demonstrates how to use n8n as a complete serverless backend, eliminating the need to create traditional APIs with Express, FastAPI, or similar frameworks. The static frontend can be deployed on Netlify, Vercel, or GitHub Pages, while n8n handles all business logic, validations, and data transformation.
This workflow demonstrates essential intermediate patterns you’ll constantly apply in professional automations:
?., ??) and validations to avoid runtime errorsTry the practical example: Ready to see these concepts in action? Visit pokeanalyzer.betazeta.dev and discover how the workflow you just learned analyzes Pokemon teams in real-time.
The same webhook → loop → transform → aggregate → respond principles can be applied to:
With these fundamentals, you’re equipped to build professional automations that handle complex real-world data. The same principles of iteration, transformation, and aggregation apply whether you’re working with Pokemon, customers, products, or any other type of data.
Happy coding!
That may interest you
In the previous chapter we reviewed what process automation is and why tools like n8n have become …
read moreIn a world where efficiency and scalability are key factors for any development team or tech …
read moren8n has established itself as one of the most powerful tools for creating automation workflows, …
read moreConcept to value