Automating review summarization with n8n turns scattered product feedback into structured weekly digests without writing a custom backend. Product teams, brand managers, and e-commerce sellers need a continuous pulse on what customers praise and complain about, but manually reading hundreds of reviews is impractical. By connecting the Scavio search API to an n8n workflow and routing the results through an LLM node, you can pull reviews for any product, generate a concise summary, and deliver it to Slack or email on a schedule. This tutorial walks through building that workflow from scratch.
Prerequisites
- n8n self-hosted or n8n cloud account
- A Scavio API key from scavio.dev
- An OpenAI or Anthropic API key for the LLM summarization step
- Basic familiarity with n8n workflow editor
Walkthrough
Step 1: Create the Schedule Trigger node
Add a Schedule Trigger node to fire the workflow weekly (or at your preferred frequency). Configure it to run every Monday at 9 AM. This is the entry point that initiates the review fetch pipeline.
// n8n Schedule Trigger configuration
{
"rule": {
"interval": [
{ "field": "cronExpression", "expression": "0 9 * * 1" }
]
}
}Step 2: Add an HTTP Request node to fetch reviews from Scavio
Add an HTTP Request node that POSTs to the Scavio search API with the product query. Set the method to POST, URL to the Scavio endpoint, and add your API key header. The response will contain review data under the reviews or organic_results key.
// n8n HTTP Request node configuration
{
"method": "POST",
"url": "https://api.scavio.dev/api/v1/search",
"headers": {
"x-api-key": "={{ $env.SCAVIO_API_KEY }}",
"Content-Type": "application/json"
},
"body": {
"platform": "amazon",
"query": "B09G9FPHY6",
"marketplace": "US",
"action": "reviews"
}
}Step 3: Add a Code node to extract and format review text
Add a Code node after the HTTP Request. This node extracts the review body text from the API response and concatenates them into a single string with review numbers, ready for LLM summarization.
// n8n Code node (JavaScript)
const reviews = $input.first().json.reviews || [];
const formatted = reviews.map((r, i) => {
return 'Review ' + (i + 1) + ' (' + (r.rating || 'N/A') + ' stars): ' + (r.text || r.body || '');
}).join('\n\n');
return [{
json: {
reviewCount: reviews.length,
formattedReviews: formatted,
productName: $input.first().json.product?.title || 'Unknown Product'
}
}];Step 4: Add an LLM node to summarize reviews
Add an OpenAI or AI Agent node configured to summarize the formatted reviews. The prompt instructs the LLM to extract top praise points, top complaints, overall sentiment, and a one-paragraph executive summary. No fabricated statistics.
// Prompt for the LLM node
You are a product review analyst. Summarize the following customer reviews for {{ $json.productName }}.
Provide:
1. Top 3 praise points (what customers love)
2. Top 3 complaint points (what customers dislike)
3. Overall sentiment (positive / mixed / negative)
4. One-paragraph executive summary
Do not fabricate statistics. Base everything on the reviews provided.
Reviews ({{ $json.reviewCount }} total):
{{ $json.formattedReviews }}Step 5: Add a delivery node (Slack or Email)
Connect a Slack or Send Email node to deliver the summary. Format the message with the product name, review count, and the LLM-generated summary. The workflow is now complete: trigger fires weekly, fetches reviews, summarizes, and delivers.
// Slack message template
*Weekly Review Summary: {{ $('Code').item.json.productName }}*
Reviews analyzed: {{ $('Code').item.json.reviewCount }}
{{ $json.text }}Python Example
import os
import requests
API_KEY = os.environ.get('SCAVIO_API_KEY', 'your_scavio_api_key')
ENDPOINT = 'https://api.scavio.dev/api/v1/search'
def fetch_reviews(asin: str) -> list[dict]:
response = requests.post(
ENDPOINT,
headers={'x-api-key': API_KEY},
json={'platform': 'amazon', 'query': asin, 'marketplace': 'US', 'action': 'reviews'}
)
response.raise_for_status()
return response.json().get('reviews', [])
def format_reviews(reviews: list[dict]) -> str:
lines = []
for i, r in enumerate(reviews, 1):
lines.append(f'Review {i} ({r.get("rating", "N/A")} stars): {r.get("text", r.get("body", ""))}')
return '\n\n'.join(lines)
def summarize_with_llm(product_name: str, formatted_reviews: str, review_count: int) -> str:
prompt = f'''Summarize the following {review_count} customer reviews for {product_name}.
Provide:
1. Top 3 praise points
2. Top 3 complaint points
3. Overall sentiment
4. One-paragraph executive summary
Reviews:
{formatted_reviews}'''
# Replace with your preferred LLM API call
import anthropic
client = anthropic.Anthropic()
message = client.messages.create(
model='claude-sonnet-4-20250514',
max_tokens=1024,
messages=[{'role': 'user', 'content': prompt}]
)
return message.content[0].text
def main():
asin = 'B09G9FPHY6'
reviews = fetch_reviews(asin)
formatted = format_reviews(reviews)
summary = summarize_with_llm('Echo Dot 5th Gen', formatted, len(reviews))
print(f'Review Summary ({len(reviews)} reviews):')
print(summary)
if __name__ == '__main__':
main()JavaScript Example
const API_KEY = process.env.SCAVIO_API_KEY || 'your_scavio_api_key';
const ENDPOINT = 'https://api.scavio.dev/api/v1/search';
async function fetchReviews(asin) {
const response = await fetch(ENDPOINT, {
method: 'POST',
headers: { 'x-api-key': API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ platform: 'amazon', query: asin, marketplace: 'US', action: 'reviews' })
});
if (!response.ok) throw new Error('HTTP ' + response.status);
const data = await response.json();
return data.reviews || [];
}
function formatReviews(reviews) {
return reviews.map((r, i) =>
'Review ' + (i + 1) + ' (' + (r.rating || 'N/A') + ' stars): ' + (r.text || r.body || '')
).join('\n\n');
}
async function summarizeWithLLM(productName, formatted, count) {
// Replace with your preferred LLM API call
const Anthropic = require('@anthropic-ai/sdk');
const client = new Anthropic();
const message = await client.messages.create({
model: 'claude-sonnet-4-20250514',
max_tokens: 1024,
messages: [{
role: 'user',
content: 'Summarize the following ' + count + ' customer reviews for ' + productName + '.\n\nProvide:\n1. Top 3 praise points\n2. Top 3 complaint points\n3. Overall sentiment\n4. One-paragraph executive summary\n\nReviews:\n' + formatted
}]
});
return message.content[0].text;
}
async function main() {
const reviews = await fetchReviews('B09G9FPHY6');
const formatted = formatReviews(reviews);
const summary = await summarizeWithLLM('Echo Dot 5th Gen', formatted, reviews.length);
console.log('Review Summary (' + reviews.length + ' reviews):');
console.log(summary);
}
main().catch(console.error);Expected Output
Review Summary (47 reviews):
Top 3 praise points:
1. Excellent sound quality for the price point
2. Seamless smart home integration with Alexa routines
3. Compact design fits any room
Top 3 complaint points:
1. Bluetooth connection drops intermittently
2. Privacy concerns with always-on microphone
3. Power adapter is bulkier than previous generation
Overall sentiment: Positive
The Echo Dot 5th Gen receives broadly positive feedback with customers praising its audio quality and smart home capabilities relative to its price. Recurring complaints center on Bluetooth stability and the physical size of the power adapter.