PAUL // AUTOMATION PAUL // N8N GUIDE

Messy JSON in n8n: normalize once, then keep the workflow clean

APIs and webhooks often return one item containing a nested array. That is fine for transport, but it becomes awkward when the next nodes expect one n8n item per lead, order, record or article.

The useful pattern: inspect the incoming shape, locate the real array, validate it, emit one n8n item per array element, and copy forward only the parent metadata you still need.

Why this breaks downstream nodes

A payload such as the example below is still a single n8n item. The leads array exists inside that item rather than as separate workflow items.

{
  "source": "webhook",
  "account": "ACME",
  "leads": [
    {"id":"L-001","name":"Alex"},
    {"id":"L-002","name":"Sam"}
  ]
}

If later mapping, looping or batch logic expects one item per lead, passing the object through unchanged can produce confusing expressions, repeated handling or a loop that behaves differently from what you intended.

The robust normalization pattern

1. Find the array that actually represents your records

Common paths include payload.contacts, payload.data.items, payload.results or a similarly nested field. Do not assume the visible top-level object is the row set.

2. Validate before transforming

const payload = $input.first().json;
const rows = payload.data?.items;

if (!Array.isArray(rows)) {
  throw new Error('Expected an array at data.items');
}

A clear failure near the top of the workflow is easier to diagnose than a chain of downstream nodes receiving the wrong shape.

3. Emit one n8n item per record

return rows.map((row, index) => ({
  json: {
    ...row,
    source: payload.source ?? null,
    account: payload.account ?? null,
    array_index: index
  }
}));

This gives later nodes a predictable stream: one item per record, plus the parent fields you intentionally preserved.

4. Normalize once

Keep raw API/webhook shape handling close to the start of the workflow. Downstream nodes should work with a stable internal schema instead of repeatedly checking whether fields moved or became nested.

5. Test with sample data first

Use representative test payloads before connecting production credentials. Store credentials in n8n credentials rather than in Code nodes or shared workflow JSON.

When the payload shape changes

Optional chaining such as payload.data?.items can prevent an immediate property-access crash, but it does not prove the expected array is present. Pair defensive reads with explicit validation and a deliberate fallback or error path.

Useful design rule: make schema variation somebody's job. One normalization node should absorb external shape changes so the rest of the workflow does not have to.

Try it without uploading your data

The free PAUL n8n Payload Inspector runs in your browser. Paste JSON locally, find nested array paths, preview clean n8n-style items and generate a starter Code node.

OPEN FREE PAYLOAD INSPECTORN8N NESTED JSON RESCUE KIT · £1+

What the Rescue Kit adds

The paid Rescue Kit is a tested starter workflow rather than a promise that every third-party schema will work unchanged. It includes a working nested-array flattening pattern, quick-start notes, troubleshooting guidance and a QA/proof step. It was built and executed successfully on n8n 2.40.5 in September 2026.