Overview
Takes a CSV of company names, searches for each company via Google search API, extracts website URL, company description, and recent news snippets, then outputs an enriched CSV ready for personalized outreach.
Trigger
Manual trigger or webhook (e.g., on new CSV upload to S3 or form submission)
Schedule
Manual or webhook-triggered
Workflow Steps
Read input CSV
Parse input CSV columns: company_name (required), industry (optional). Validate and deduplicate entries.
Search for company info
For each company, POST to Scavio search API with query '[company_name] official website'. Extract top result URL and snippet.
Search for recent news
Second search per company: '[company_name] news 2026'. Extract top 2 news snippets for context in personalization.
Extract company description
From the first search result snippet, extract a 1-2 sentence company description. Remove boilerplate ('Visit us', 'Learn more').
Assemble enriched row
Combine original fields with: website_url, company_description, recent_news_1, recent_news_2, search_date.
Output enriched CSV
Write enriched rows to output CSV. Log companies where search returned no usable data for manual review.
Python Implementation
import csv
import requests
import re
from datetime import date
import time
SCRAVIO_KEY = "YOUR_API_KEY"
INPUT_CSV = "leads.csv"
OUTPUT_CSV = "leads_enriched.csv"
def search(query: str) -> list:
resp = requests.post(
"https://api.scavio.dev/api/v1/search",
headers={"x-api-key": SCRAVIO_KEY},
json={"query": query, "platform": "google", "num": 5}
)
resp.raise_for_status()
return resp.json().get("results", [])
def clean_snippet(snippet: str) -> str:
junk = ["Visit", "Learn more", "Click here", "Sign up", "Subscribe"]
for j in junk:
snippet = snippet.replace(j, "").strip()
return snippet[:200]
def enrich_company(company_name: str) -> dict:
# Company website + description
site_results = search(f"{company_name} official website")
website_url = site_results[0]["url"] if site_results else ""
description = clean_snippet(site_results[0].get("snippet", "")) if site_results else ""
time.sleep(0.2)
# Recent news
news_results = search(f"{company_name} news 2026")
news_1 = clean_snippet(news_results[0].get("snippet", "")) if len(news_results) > 0 else ""
news_2 = clean_snippet(news_results[1].get("snippet", "")) if len(news_results) > 1 else ""
time.sleep(0.2)
return {
"website_url": website_url,
"company_description": description,
"recent_news_1": news_1,
"recent_news_2": news_2,
"search_date": date.today().isoformat()
}
def run():
with open(INPUT_CSV) as f:
reader = csv.DictReader(f)
rows = list(reader)
enriched = []
for row in rows:
company = row["company_name"].strip()
if not company:
continue
extra = enrich_company(company)
enriched.append({**row, **extra})
print(f"Enriched: {company}")
if not enriched:
return
fieldnames = list(enriched[0].keys())
with open(OUTPUT_CSV, "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(enriched)
print(f"Done. {len(enriched)} companies enriched -> {OUTPUT_CSV}")
if __name__ == "__main__":
run()
JavaScript Implementation
const fs = require('fs');
const { parse } = require('csv-parse/sync');
const { stringify } = require('csv-stringify/sync');
const fetch = require('node-fetch');
const SCRAVIO_KEY = 'YOUR_API_KEY';
const INPUT_CSV = 'leads.csv';
const OUTPUT_CSV = 'leads_enriched.csv';
async function search(query) {
const res = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: { 'x-api-key': SCRAVIO_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ query, platform: 'google', num: 5 })
});
return (await res.json()).results || [];
}
function cleanSnippet(s) {
return (s || '').replace(/Visit|Learn more|Click here|Sign up/g, '').trim().slice(0, 200);
}
async function enrichCompany(name) {
const siteResults = await search(`${name} official website`);
const website_url = siteResults[0]?.url || '';
const company_description = cleanSnippet(siteResults[0]?.snippet);
await new Promise(r => setTimeout(r, 200));
const news = await search(`${name} news 2026`);
const recent_news_1 = cleanSnippet(news[0]?.snippet);
const recent_news_2 = cleanSnippet(news[1]?.snippet);
await new Promise(r => setTimeout(r, 200));
return { website_url, company_description, recent_news_1, recent_news_2, search_date: new Date().toISOString().slice(0, 10) };
}
async function run() {
const rows = parse(fs.readFileSync(INPUT_CSV), { columns: true, skip_empty_lines: true });
const enriched = [];
for (const row of rows) {
const name = (row.company_name || '').trim();
if (!name) continue;
const extra = await enrichCompany(name);
enriched.push({ ...row, ...extra });
console.log(`Enriched: ${name}`);
}
fs.writeFileSync(OUTPUT_CSV, stringify(enriched, { header: true }));
console.log(`Done. ${enriched.length} companies -> ${OUTPUT_CSV}`);
}
run().catch(console.error);
Platforms Used
Web search with knowledge graph, PAA, and AI overviews