Enrichir les contacts CRM avec les données de l'API de recherche ajoute des actualités récentes, des signaux de stack technique et le contexte de financement que les bases de données statiques ignorent. Les équipes commerciales concluent plus rapidement lorsqu'elles savent qu'un prospect vient de lever des fonds, d'adopter un nouvel outil ou d'apparaître dans les actualités sectorielles – mais la recherche manuelle par contact ne passe pas à l'échelle. L'API de recherche Scavio vous permet d'interroger par programmation des informations spécifiques à une entreprise et d'extraire des signaux structurés à partir des résultats. Ce tutoriel construit un pipeline d'enrichissement en Python qui prend un CSV de contacts, exécute des recherches ciblées pour chaque entreprise, analyse les résultats pour les signaux clés et réécrit les données enrichies dans un CSV prêt pour l'importation CRM.
Prérequis
- Python 3.8 ou supérieur installé
- requests et csv (bibliothèque standard) disponibles
- Une clé API Scavio depuis scavio.dev
- Un fichier CSV avec les données de contact incluant les noms d'entreprises
Parcours
Étape 1: Charger les contacts depuis un CSV
Lire le CSV d'entrée contenant au minimum une colonne company_name. Le script enrichira chaque ligne avec des colonnes supplémentaires dérivées des résultats de recherche.
import csv
from pathlib import Path
def load_contacts(filepath: str) -> list[dict]:
with open(filepath, 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
return list(reader)
contacts = load_contacts('contacts.csv')
print(f'Loaded {len(contacts)} contacts')Étape 2: Exécuter des requêtes de recherche ciblées par entreprise
Pour chaque entreprise, exécutez plusieurs requêtes ciblées pour trouver des actualités récentes, des informations de financement et des signaux de stack technique. Chaque requête est adaptée pour faire remonter un signal d'enrichissement spécifique.
import requests
import os
API_KEY = os.environ.get('SCAVIO_API_KEY', 'your_scavio_api_key')
ENDPOINT = 'https://api.scavio.dev/api/v1/search'
def search_company(company: str, query_suffix: str) -> dict:
response = requests.post(
ENDPOINT,
headers={'x-api-key': API_KEY},
json={'query': f'{company} {query_suffix}', 'country_code': 'us'}
)
response.raise_for_status()
return response.json()
SIGNAL_QUERIES = {
'recent_news': 'news 2026',
'funding': 'funding round raised',
'tech_stack': 'tech stack tools uses',
'hiring': 'hiring jobs open positions'
}Étape 3: Analyser les résultats de recherche en signaux structurés
Extraire les snippets des meilleurs résultats organiques pour chaque requête de signal et les condenser en un champ d'enrichissement d'une seule ligne. Cela évite le HTML brut et fournit un texte propre pour les notes CRM.
def extract_signal(data: dict, max_snippets: int = 3) -> str:
results = data.get('organic_results', [])[:max_snippets]
snippets = []
for r in results:
snippet = r.get('snippet', '')
if snippet:
snippets.append(snippet.strip())
return ' | '.join(snippets) if snippets else 'No data found'
def enrich_contact(contact: dict) -> dict:
company = contact.get('company_name', '')
if not company:
return contact
for signal_name, query_suffix in SIGNAL_QUERIES.items():
data = search_company(company, query_suffix)
contact[signal_name] = extract_signal(data)
return contactÉtape 4: Exécuter l'enrichissement et écrire les résultats dans un CSV
Parcourir tous les contacts, enrichir chacun d'eux et écrire les résultats dans un nouveau fichier CSV avec les colonnes de signal supplémentaires. Ajoutez une limitation de débit pour rester dans le budget de crédits API.
import time
def run_enrichment(input_file: str, output_file: str):
contacts = load_contacts(input_file)
enriched = []
for i, contact in enumerate(contacts):
print(f'Enriching {i + 1}/{len(contacts)}: {contact.get("company_name", "unknown")}')
enriched.append(enrich_contact(contact))
time.sleep(1) # rate limit: 4 queries per contact
fieldnames = list(enriched[0].keys())
with open(output_file, 'w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(enriched)
print(f'Wrote {len(enriched)} enriched contacts to {output_file}')
run_enrichment('contacts.csv', 'contacts_enriched.csv')Exemple Python
import os
import csv
import time
import requests
API_KEY = os.environ.get('SCAVIO_API_KEY', 'your_scavio_api_key')
ENDPOINT = 'https://api.scavio.dev/api/v1/search'
SIGNAL_QUERIES = {
'recent_news': 'news 2026',
'funding': 'funding round raised',
'tech_stack': 'tech stack tools uses',
'hiring': 'hiring jobs open positions'
}
def search_company(company: str, query_suffix: str) -> dict:
response = requests.post(
ENDPOINT,
headers={'x-api-key': API_KEY},
json={'query': f'{company} {query_suffix}', 'country_code': 'us'}
)
response.raise_for_status()
return response.json()
def extract_signal(data: dict, max_snippets: int = 3) -> str:
results = data.get('organic_results', [])[:max_snippets]
snippets = [r.get('snippet', '').strip() for r in results if r.get('snippet')]
return ' | '.join(snippets) if snippets else 'No data found'
def load_contacts(filepath: str) -> list[dict]:
with open(filepath, 'r', encoding='utf-8') as f:
return list(csv.DictReader(f))
def enrich_contact(contact: dict) -> dict:
company = contact.get('company_name', '')
if not company:
return contact
for signal_name, query_suffix in SIGNAL_QUERIES.items():
data = search_company(company, query_suffix)
contact[signal_name] = extract_signal(data)
return contact
def run_enrichment(input_file: str, output_file: str):
contacts = load_contacts(input_file)
enriched = []
for i, contact in enumerate(contacts):
print(f'Enriching {i + 1}/{len(contacts)}: {contact.get("company_name", "unknown")}')
enriched.append(enrich_contact(contact))
time.sleep(1)
fieldnames = list(enriched[0].keys())
with open(output_file, 'w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(enriched)
print(f'Wrote {len(enriched)} enriched contacts to {output_file}')
if __name__ == '__main__':
run_enrichment('contacts.csv', 'contacts_enriched.csv')Exemple JavaScript
const API_KEY = process.env.SCAVIO_API_KEY || 'your_scavio_api_key';
const ENDPOINT = 'https://api.scavio.dev/api/v1/search';
const fs = require('fs');
const SIGNAL_QUERIES = {
recent_news: 'news 2026',
funding: 'funding round raised',
tech_stack: 'tech stack tools uses',
hiring: 'hiring jobs open positions'
};
async function searchCompany(company, querySuffix) {
const response = await fetch(ENDPOINT, {
method: 'POST',
headers: { 'x-api-key': API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ query: company + ' ' + querySuffix, country_code: 'us' })
});
if (!response.ok) throw new Error('HTTP ' + response.status);
return response.json();
}
function extractSignal(data) {
const results = (data.organic_results || []).slice(0, 3);
const snippets = results.map(r => (r.snippet || '').trim()).filter(Boolean);
return snippets.length ? snippets.join(' | ') : 'No data found';
}
function parseCSV(text) {
const lines = text.trim().split('\n');
const headers = lines[0].split(',').map(h => h.trim());
return lines.slice(1).map(line => {
const values = line.split(',');
return Object.fromEntries(headers.map((h, i) => [h, (values[i] || '').trim()]));
});
}
async function main() {
const contacts = parseCSV(fs.readFileSync('contacts.csv', 'utf-8'));
const enriched = [];
for (let i = 0; i < contacts.length; i++) {
const contact = contacts[i];
const company = contact.company_name || '';
console.log('Enriching ' + (i + 1) + '/' + contacts.length + ': ' + company);
if (company) {
for (const [signal, suffix] of Object.entries(SIGNAL_QUERIES)) {
const data = await searchCompany(company, suffix);
contact[signal] = extractSignal(data);
}
}
enriched.push(contact);
await new Promise(r => setTimeout(r, 1000));
}
const headers = Object.keys(enriched[0]);
const csv = [headers.join(','), ...enriched.map(r => headers.map(h => '"' + (r[h] || '') + '"').join(','))].join('\n');
fs.writeFileSync('contacts_enriched.csv', csv);
console.log('Wrote ' + enriched.length + ' enriched contacts');
}
main().catch(console.error);Sortie attendue
Enriching 1/3: Acme Corp
Enriching 2/3: TechStart Inc
Enriching 3/3: DataFlow Labs
Wrote 3 enriched contacts to contacts_enriched.csv
-- contacts_enriched.csv sample row --
company_name,email,recent_news,funding,tech_stack,hiring
Acme Corp,john@acme.com,"Acme Corp announces Q1 revenue growth...","Acme Corp raises $45M Series B...","Acme Corp uses React, PostgreSQL, and AWS...","Acme Corp hiring 15 engineers..."