Avant d'investir dans un inventaire Amazon FBA, vous devez valider qu'un produit peut réellement être rentable. Cela implique de vérifier la densité de la concurrence sur Amazon, de confirmer les signaux de demande sur Google et TikTok, et de tester vos hypothèses de marge. Ce tutoriel construit un pipeline de validation de rentabilité qui utilise Scavio pour extraire des données en direct d'Amazon, Google et TikTok à 0,005 $ par recherche, remplaçant des outils coûteux comme Helium 10 (à partir de 49 $/mois).
Prérequis
- Python 3.9+ installé
- bibliothèque requests installée
- Une clé API Scavio depuis scavio.dev
- Compréhension de base de l'économie Amazon FBA
Parcours
Étape 1: Vérifier la densité de la concurrence sur Amazon
Recherchez votre produit sur Amazon pour voir combien d'annonces concurrentes existent, leurs notes et les tendances de prix. Une forte concurrence avec des marques établies signifie une entrée plus difficile.
import os, requests, re
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
URL = 'https://api.scavio.dev/api/v1/search'
H = {'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'}
def check_amazon_competition(product: str) -> dict:
resp = requests.post(URL, headers=H,
json={'query': f'site:amazon.com {product}',
'country_code': 'us', 'num_results': 10})
results = resp.json().get('organic_results', [])
# Extract pricing from snippets
prices = []
for r in results:
price_match = re.search(r'\$([\d,]+\.\d{2})', r.get('snippet', '') + r.get('title', ''))
if price_match:
prices.append(float(price_match.group(1).replace(',', '')))
# Extract ratings
ratings = []
for r in results:
rating_match = re.search(r'(\d+\.\d+) out of 5', r.get('snippet', ''))
if rating_match:
ratings.append(float(rating_match.group(1)))
return {
'product': product,
'listings_found': len(results),
'price_range': {'min': min(prices) if prices else 0, 'max': max(prices) if prices else 0,
'avg': sum(prices)/len(prices) if prices else 0},
'avg_rating': sum(ratings)/len(ratings) if ratings else 0,
'competition': 'high' if len(results) >= 8 else 'medium' if len(results) >= 4 else 'low',
}
comp = check_amazon_competition('silicone baking mat set')
print(f"Product: {comp['product']}")
print(f"Competition: {comp['competition']} ({comp['listings_found']} listings)")
print(f"Price range: ${comp['price_range']['min']:.2f} - ${comp['price_range']['max']:.2f}")
print(f"Avg rating: {comp['avg_rating']:.1f}")Étape 2: Vérifier les signaux de demande sur Google
Recherchez sur Google des requêtes d'intention d'achat pour évaluer la demande. Un volume de recherche élevé pour des requêtes spécifiques au produit indique une demande réelle du marché.
import time
def check_demand_signals(product: str) -> dict:
"""Check Google for buying intent signals."""
intent_queries = [
f'best {product} 2026',
f'{product} review',
f'{product} vs',
f'where to buy {product}',
]
total_results = 0
buying_signals = 0
for q in intent_queries:
resp = requests.post(URL, headers=H,
json={'query': q, 'country_code': 'us', 'num_results': 5})
results = resp.json().get('organic_results', [])
total_results += len(results)
# Count buying intent results (Amazon, Walmart, shopping sites)
for r in results:
link = r.get('link', '').lower()
if any(shop in link for shop in ['amazon.', 'walmart.', 'target.', '/shop', '/buy']):
buying_signals += 1
time.sleep(0.3)
return {
'product': product,
'intent_queries': len(intent_queries),
'total_results': total_results,
'buying_signals': buying_signals,
'demand_score': buying_signals / total_results if total_results else 0,
'demand_level': 'high' if buying_signals > 8 else 'medium' if buying_signals > 4 else 'low',
}
demand = check_demand_signals('silicone baking mat set')
print(f"Demand: {demand['demand_level']}")
print(f"Buying signals: {demand['buying_signals']}/{demand['total_results']}")
print(f"Cost: {demand['intent_queries']} searches = ${demand['intent_queries'] * 0.005:.3f}")Étape 3: Calculer les marges de rentabilité
Combinez les données de concurrence et de demande avec vos hypothèses de coûts pour estimer la rentabilité. Signalez les produits qui n'atteignent pas les seuils de marge minimale.
def validate_profitability(product: str, unit_cost: float, shipping_cost: float = 3.0) -> dict:
"""Full profitability validation with live data."""
# Get live market data
competition = check_amazon_competition(product)
time.sleep(0.3)
demand = check_demand_signals(product)
# Calculate margins
avg_price = competition['price_range']['avg']
if avg_price == 0:
return {'product': product, 'verdict': 'SKIP', 'reason': 'No pricing data found'}
amazon_fee = avg_price * 0.15 # 15% referral fee
fba_fee = 4.50 # Estimated FBA fee
total_cost = unit_cost + shipping_cost + amazon_fee + fba_fee
profit_per_unit = avg_price - total_cost
margin = profit_per_unit / avg_price if avg_price > 0 else 0
# Verdict
issues = []
if margin < 0.20:
issues.append(f'Low margin: {margin:.0%}')
if competition['competition'] == 'high' and competition['avg_rating'] > 4.3:
issues.append('High competition with strong ratings')
if demand['demand_level'] == 'low':
issues.append('Low demand signals')
verdict = 'GO' if not issues else 'CAUTION' if len(issues) == 1 else 'SKIP'
return {
'product': product, 'verdict': verdict,
'avg_price': avg_price, 'total_cost': total_cost,
'profit_per_unit': profit_per_unit, 'margin': margin,
'competition': competition['competition'],
'demand': demand['demand_level'],
'issues': issues,
'api_cost': 0.025, # 5 searches total
}
result = validate_profitability('silicone baking mat set', unit_cost=3.50)
print(f"\nProfitability Report: {result['product']}")
print(f"Verdict: {result['verdict']}")
print(f"Avg price: ${result['avg_price']:.2f}")
print(f"Total cost: ${result['total_cost']:.2f}")
print(f"Profit/unit: ${result['profit_per_unit']:.2f} ({result['margin']:.0%})")
print(f"Competition: {result['competition']}, Demand: {result['demand']}")
if result['issues']:
print(f"Issues: {', '.join(result['issues'])}")Étape 4: Valider par lot une liste restreinte de produits
Exécutez le contrôle de rentabilité sur plusieurs idées de produits et classez-les par marge et demande. Cela remplace des heures de recherche manuelle.
def batch_validate(products: list[dict]) -> list:
"""Validate multiple products and rank by profitability."""
results = []
for p in products:
print(f"Validating: {p['name']}...")
result = validate_profitability(p['name'], p['unit_cost'])
results.append(result)
time.sleep(0.5)
# Sort by margin descending
results.sort(key=lambda x: x.get('margin', 0), reverse=True)
return results
products = [
{'name': 'silicone baking mat set', 'unit_cost': 3.50},
{'name': 'bamboo cutting board set', 'unit_cost': 5.00},
{'name': 'stainless steel water bottle', 'unit_cost': 4.00},
]
results = batch_validate(products)
print('\nProduct Validation Summary')
print('=' * 60)
for r in results:
print(f"[{r['verdict']:7s}] {r['product'][:30]:30s} "
f"Margin: {r.get('margin',0):.0%} Profit: ${r.get('profit_per_unit',0):.2f}")
total_cost = sum(r['api_cost'] for r in results)
print(f'\nTotal validation cost: ${total_cost:.3f}')
print(f'Helium 10 equivalent: $49/month minimum')Exemple Python
import os, requests, re, time
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
H = {'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'}
def validate_product(product, unit_cost):
# Check Amazon competition
resp = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
json={'query': f'site:amazon.com {product}', 'country_code': 'us', 'num_results': 10})
results = resp.json().get('organic_results', [])
prices = [float(m.group(1).replace(',','')) for r in results
for m in [re.search(r'\$([\d,]+\.\d{2})', r.get('snippet',''))] if m]
avg_price = sum(prices)/len(prices) if prices else 0
margin = (avg_price - unit_cost - avg_price*0.15 - 7.5) / avg_price if avg_price else 0
print(f'{product}: ${avg_price:.2f} avg, {margin:.0%} margin, {len(results)} competitors')
for p, c in [('silicone baking mat', 3.50), ('bamboo cutting board', 5.00)]:
validate_product(p, c)
time.sleep(0.3)Exemple JavaScript
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;
async function validateProduct(product, unitCost) {
const resp = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: { 'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ query: `site:amazon.com ${product}`, country_code: 'us', num_results: 10 })
});
const results = (await resp.json()).organic_results || [];
const prices = results.flatMap(r => {
const m = (r.snippet || '').match(/\$([\d,]+\.\d{2})/);
return m ? [parseFloat(m[1].replace(',', ''))] : [];
});
const avg = prices.length ? prices.reduce((a,b) => a+b, 0) / prices.length : 0;
const margin = avg ? (avg - unitCost - avg*0.15 - 7.5) / avg : 0;
console.log(`${product}: $${avg.toFixed(2)} avg, ${(margin*100).toFixed(0)}% margin, ${results.length} competitors`);
}
validateProduct('silicone baking mat', 3.50);Sortie attendue
Validating: silicone baking mat set...
Validating: bamboo cutting board set...
Validating: stainless steel water bottle...
Product Validation Summary
============================================================
[GO ] bamboo cutting board set Margin: 35% Profit: $8.25
[CAUTION] silicone baking mat set Margin: 22% Profit: $3.10
[SKIP ] stainless steel water bottle Margin: 12% Profit: $2.40
Total validation cost: $0.075
Helium 10 equivalent: $49/month minimum