How good is your Pokemon team? An n8n workflow that gives you the answers

Nov 1, 2025

In 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.

The challenge: working with complex API data

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.

Workflow architecture

Our Pokemon team analyzer will follow this modular structure accessible via webhook:

This architecture allows us to:

  • Receive external requests through an HTTP POST webhook
  • Process multiple Pokemon iteratively without duplicating nodes
  • Transform complex data into manageable structures
  • Aggregate information from multiple API calls
  • Respond automatically with the complete analysis in JSON format

Building the workflow step by step

Step 1: Configure the webhook and prepare input

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:

  • HTTP Method: POST
  • Path: pokemon-team-analyzer
  • Options → Allowed Origins: Your deployed application URL on Netlify (https://pokemon-team-analyzer.netlify.app) or “*” to accept all origins (testing only).
  • Respond: Using 'Respond to Webhook' Node

The 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.json file with the source code in the GitHub repository

Step 2: Iterate over the team with Loop Over Items

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:

  • Keep the default configuration, which will process each item automatically
  • This node has two outputs: the first (loop) executes iterative processing, the second (done) activates when all items have been processed

How the loop works:

  1. The loop output (bottom) processes each Pokemon individually
  2. The transformed data returns to the Loop node closing the cycle
  3. When finished, the done output (top) sends all results to aggregate analysis

Step 3: Query PokéAPI for each Pokemon

Now we’ll use an HTTP Request node to get data for each Pokemon from the API.

HTTP Request configuration:

  • Method: GET
  • URL: https://pokeapi.co/api/v2/pokemon/{{ $json.pokemon_name }}
  • Options → Response → Response Format: JSON

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.

Step 4: Transform complex data

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:

  • Validates that PokéAPI data exists
  • Flattens stats from nested arrays to simple objects
  • Extracts types, abilities, and sprites
  • Calculates total stats
  • Uses null-safe operators (?., ??) to avoid errors

Step 5: Aggregate complete team data

After 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:

  • Normalizes the Pokemon array received from the loop
  • Calculates stat averages (HP, Attack, Defense, Speed, Total)
  • Analyzes unique type coverage of the team
  • Identifies the strongest Pokemon (highest total stats)
  • Identifies the fastest Pokemon (highest speed)
  • Uses defensive programming with safeStat helper functions

📦 Complete code: You can find the full workflow.json file with the source code in the GitHub repository

Step 6: Format output and respond to webhook

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:

  • Mode: Define (using Assignments)
  • Assignments:
    • 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:

  • Respond With: All incoming items

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.

Testing the workflow and building a web interface

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.

Testing with curl (quick option)

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"
        },
        ...
      ]
    }
  ]
    

Building the web application

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 application index.html are available in the GitHub repository with detailed deployment instructions.

n8n as a serverless backend

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.

Key concepts learned

This workflow demonstrates essential intermediate patterns you’ll constantly apply in professional automations:

  1. Webhooks as API endpoints: Convert n8n workflows into REST services consumable by any application
  2. Iterative processing with loops: Use Split In Batches to handle data arrays efficiently
  3. Nested data transformation: Convert complex JSON from external APIs into simple, manageable structures
  4. Data aggregation: Combine information from multiple processed items into consolidated analysis
  5. Defensive programming: Use null-safe operators (?., ??) and validations to avoid runtime errors
  6. Strategic use of Code nodes: For complex transformations that other nodes can’t handle efficiently
  7. Structured HTTP responses: Format data for external consumption through Respond to Webhook
  8. Frontend-backend separation: n8n as serverless backend consumed by static frontends

Try 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.

Real-world applications

The same webhook → loop → transform → aggregate → respond principles can be applied to:

  • Mass sentiment analysis: Process product reviews, extract sentiments with AI, and aggregate metrics
  • Lead enrichment: Receive list of emails, query enrichment APIs, and return complete profiles
  • Price monitoring: Iterate over product URL lists, scrape prices, calculate averages and trends
  • Data validation: Process large CSVs validating each row against multiple criteria and returning reports

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!

Need help?

At BetaZetaDev, we transform ideas into real digital solutions. Over 10 years building mobile apps, web platforms, automation systems, and custom software that impact thousands of users. From concept to deployment, we craft technology that solves your business-specific challenges with clean code, scalable architectures, and proven expertise.

Let's talk about your project

Related posts

That may interest you