databeginner10 min setupby Mantle

Fan out a list to an API

Receive a list of items by webhook and call an API once per item, five in parallel, continuing past individual failures.

Batch inFor each itemPOST item

Drag to pan, pinch to zoom. This is the real graph the template installs.

Purpose

Receive a list of items by webhook and call an API once per item, five in parallel, continuing past individual failures.

How it works

What it does

  • Webhook batch-in receives {items: [...]}.
  • For each item iterates the list five at a time (parallel, max_concurrency: 5); a failed item does not stop the others (on_error: continue).
  • POST item — the loop body — sends each element as the JSON body, with exponential-backoff retry.

Nodes 3

  1. 01Batch intrigger.webhookTrigger
  2. 02For each itemcontrol.for_eachLogic
  3. 03POST itemhttp.requestHTTP
View template JSON
{
  "format": "mantle-workflow/v1",
  "id": "data-fan-out-http",
  "name": "Fan out a list to an API",
  "graph": {
    "nodes": [
      {
        "id": "webhook",
        "type": "trigger.webhook",
        "label": "Batch in",
        "config": {
          "slug": "batch-in",
          "input_schema": {
            "required": [
              "items"
            ],
            "properties": {
              "items": {
                "type": "array"
              }
            }
          }
        },
        "worker_type": "generic-worker",
        "position": {
          "x": 60,
          "y": 220
        }
      },
      {
        "id": "for_each_item",
        "type": "control.for_each",
        "label": "For each item",
        "config": {
          "items": "items",
          "item_as": "item",
          "index_as": "i",
          "parallel": true,
          "max_concurrency": 5,
          "on_error": "continue",
          "empty_collection": "skip",
          "max_items": 1000
        },
        "worker_type": "generic-worker",
        "position": {
          "x": 380,
          "y": 220
        }
      },
      {
        "id": "post_item",
        "type": "http.request",
        "label": "POST item",
        "config": {
          "method": "POST",
          "url": "https://example.com/items",
          "headers": {
            "Content-Type": "application/json"
          },
          "body_from_input": true,
          "timeout_seconds": 15
        },
        "worker_type": "generic-worker",
        "position": {
          "x": 700,
          "y": 220
        },
        "retry": {
          "max_attempts": 3,
          "backoff": "exp",
          "initial_ms": 500,
          "max_ms": 8000
        },
        "parent_id": "for_each_item"
      }
    ],
    "edges": [
      {
        "from": "webhook",
        "to": "for_each_item"
      },
      {
        "from": "for_each_item",
        "to": "post_item"
      }
    ]
  }
}

Requirements

The connections and permissions each step needs, from the node contracts in the catalog.

No connections. This template runs with built-in nodes only.

Setup

  • Change the destination url on POST item (or use an HTTP connection + path).
  • Tune max_concurrency and max_items for the downstream API's limits.

Sample input and output

Synthetic examples: node-contract samples or placeholders, never customer data.

Input

The fields the template declares or reads from the request body. Values are placeholders.

{
  "items": []
}

Output

POST item http.request

{
  "body": null,
  "headers": {},
  "status_code": 0
}

Failure handling

What the graph does when a step fails, read from its retry settings, error branches and error policies.

  • For each item: a failed item is skipped and the other items carry on; the failure stays on its own step.
  • POST item: up to 3 attempts, exponential backoff from 500 ms up to 8 s.
  • POST item: the request times out after 15 s.
  • A step that fails, after any retries, fails the run. The failed step is kept with its input and error.

See it run, then make it yours.

Templates install as drafts. Edit any step, and Workflow Health re-checks the graph on every save.