The Problem
n8n workflows that call multiple enrichment APIs (search, company data, social profiles) receive responses in different schemas. One API returns results in a 'data' array, another in 'results', another in 'items'. Field names differ: 'title' vs 'name' vs 'headline'. Types differ: price as string vs number. Every downstream node must handle every possible schema variation, or the workflow breaks silently when an API changes its response format. Debugging these failures in a visual workflow builder is painful because the error surfaces three nodes downstream from the actual problem.
The Scavio Solution
Build a normalizer sub-workflow in n8n that sits between every enrichment API call and your downstream logic. The normalizer validates the response, maps vendor-specific fields to your canonical schema, handles missing fields with defaults, and passes a uniform object downstream. Scavio's consistent response schema makes it the easiest source to normalize because the same JSON structure comes back regardless of platform. One normalizer template covers Google, YouTube, Amazon, Walmart, Reddit, and TikTok.
Before
Before normalizing, n8n workflows broke silently when enrichment APIs changed response formats. Debugging required tracing data through multiple nodes to find where a field name mismatch caused a downstream failure.
After
After adding normalizer sub-workflows, every downstream node receives identical schemas. API format changes are caught at the normalizer layer, and fixing them requires updating one sub-workflow instead of every node that consumes the data.
Who It Is For
n8n workflow builders who chain multiple enrichment APIs and are tired of debugging schema mismatches three nodes downstream. Anyone building complex automation workflows that consume data from multiple sources.
Key Benefits
- Canonical schema downstream regardless of source API format
- Missing field defaults prevent silent downstream failures
- One normalizer template covers all six Scavio platforms
- API format changes are caught and fixed in one place
- n8n sub-workflow reusable across multiple parent workflows
Python Example
import requests
API_KEY = "your_scavio_api_key"
def normalize_scavio_response(raw: dict, platform: str) -> list[dict]:
"""Normalize Scavio response to canonical schema for n8n downstream nodes."""
normalized = []
for item in raw.get("organic", []):
entry = {
"title": item.get("title", ""),
"url": item.get("link", ""),
"description": item.get("snippet", ""),
"position": item.get("position"),
"source_platform": platform,
}
# Platform-specific enrichment
if platform in ("amazon", "walmart"):
entry["price"] = float(item.get("price", 0)) if item.get("price") else None
entry["rating"] = float(item.get("rating", 0)) if item.get("rating") else None
entry["reviews"] = int(item.get("reviews", 0)) if item.get("reviews") else 0
elif platform == "youtube":
entry["views"] = int(item.get("views", 0)) if item.get("views") else 0
entry["channel"] = item.get("channel", "")
elif platform == "reddit":
entry["score"] = int(item.get("score", 0)) if item.get("score") else 0
entry["comments"] = int(item.get("comments", 0)) if item.get("comments") else 0
entry["subreddit"] = item.get("subreddit", "")
normalized.append(entry)
return normalized
def search_and_normalize(query: str, platform: str) -> list[dict]:
res = requests.post(
"https://api.scavio.dev/api/v1/search",
headers={"x-api-key": API_KEY},
json={"platform": platform, "query": query},
timeout=15,
)
res.raise_for_status()
return normalize_scavio_response(res.json(), platform)
# Same downstream schema regardless of platform
google_results = search_and_normalize("project management tool", "google")
amazon_results = search_and_normalize("project management book", "amazon")
reddit_results = search_and_normalize("project management tool recommendation", "reddit")
for source in [google_results, amazon_results, reddit_results]:
if source:
print(f"Platform: {source[0]['source_platform']} - {len(source)} results")
print(f" First: {source[0]['title'][:60]}")JavaScript Example
const API_KEY = "your_scavio_api_key";
function normalizeResponse(raw, platform) {
return (raw.organic ?? []).map((item) => {
const entry = {
title: item.title ?? "",
url: item.link ?? "",
description: item.snippet ?? "",
position: item.position ?? null,
sourcePlatform: platform,
};
if (["amazon", "walmart"].includes(platform)) {
entry.price = item.price ? Number(item.price) : null;
entry.rating = item.rating ? Number(item.rating) : null;
entry.reviews = item.reviews ? Number(item.reviews) : 0;
} else if (platform === "youtube") {
entry.views = item.views ? Number(item.views) : 0;
entry.channel = item.channel ?? "";
} else if (platform === "reddit") {
entry.score = item.score ? Number(item.score) : 0;
entry.comments = item.comments ? Number(item.comments) : 0;
entry.subreddit = item.subreddit ?? "";
}
return entry;
});
}
async function searchAndNormalize(query, platform) {
const res = await fetch("https://api.scavio.dev/api/v1/search", {
method: "POST",
headers: { "x-api-key": API_KEY, "content-type": "application/json" },
body: JSON.stringify({ platform, query }),
});
if (!res.ok) throw new Error(`scavio ${res.status}`);
return normalizeResponse(await res.json(), platform);
}
const google = await searchAndNormalize("project management tool", "google");
const amazon = await searchAndNormalize("project management book", "amazon");
console.log(`Google: ${google.length} results, Amazon: ${amazon.length} results`);Platforms Used
Web search with knowledge graph, PAA, and AI overviews
YouTube
Video search with transcripts and metadata
Amazon
Product search with prices, ratings, and reviews
Walmart
Product search with pricing and fulfillment data
Community, posts & threaded comments from any subreddit
TikTok
Trending video, creator, and product discovery