Passer du niveau gratuit de l'API Brave Search à Scavio prend environ 15 minutes de modifications de code et supprime la limite de 2 000 requêtes/mois qui bloque la plupart des charges de travail en production. Ce tutoriel vous guide pas à pas dans la migration : mappage des champs de réponse Brave vers les équivalents Scavio, mise à jour de vos appels HTTP, adaptation de la gestion des erreurs et validation que votre logique en aval fonctionne avec le nouveau format de réponse.
Prérequis
- Intégration existante de l'API Brave Search que vous souhaitez migrer
- Clé API Scavio (250 crédits/mois gratuits sur scavio.dev)
- Python 3.9+ ou Node.js 18+
Parcours
Étape 1: Auditez votre utilisation actuelle de Brave Search
Avant de migrer, auditez comment vous appelez actuellement l'API Brave. Notez le point de terminaison, les en-têtes, les paramètres de requête et les champs de réponse que votre code utilise réellement. La plupart des intégrations n'utilisent que le titre, l'URL et la description des résultats de recherche web, ce qui simplifie la migration.
# Typical Brave Search API call you are replacing
import requests
BRAVE_API_KEY = 'your_brave_key'
resp = requests.get(
'https://api.search.brave.com/res/v1/web/search',
headers={'X-Subscription-Token': BRAVE_API_KEY},
params={'q': 'best crm for startups 2026', 'count': 10}
)
data = resp.json()
for result in data.get('web', {}).get('results', []):
print(result['title'], result['url'], result.get('description', ''))Étape 2: Mappez les champs de réponse Brave aux équivalents Scavio
Scavio renvoie les résultats sous un tableau organic au lieu de web.results. Les noms de champs diffèrent légèrement : Brave utilise description tandis que Scavio utilise snippet. Créez un mappage pour mettre à jour toutes les références en une seule fois.
# Field mapping: Brave -> Scavio
# data.web.results -> data.organic
# result.title -> item.title (same)
# result.url -> item.url (same)
# result.description -> item.snippet
# result.extra_snippets -> (not applicable)
# params.q -> json body: query
# params.count -> json body: num
# header X-Subscription-Token -> header x-api-keyÉtape 3: Remplacez l'appel API
Remplacez la requête GET Brave par une requête POST Scavio. L'API Scavio utilise un corps JSON au lieu de paramètres de requête, et un en-tête x-api-key au lieu de X-Subscription-Token.
import requests
SCAVIO_API_KEY = 'your_scavio_api_key'
def search(query, num=10):
resp = requests.post(
'https://api.scavio.dev/api/v1/search',
headers={'x-api-key': SCAVIO_API_KEY},
json={'query': query, 'num': num}
)
resp.raise_for_status()
data = resp.json()
return [
{
'title': item.get('title', ''),
'url': item.get('url', ''),
'description': item.get('snippet', ''),
}
for item in data.get('organic', [])
]Étape 4: Mettez à jour la gestion des erreurs et les limites de débit
Brave renvoie 429 lorsque vous atteignez le plafond du niveau gratuit. Scavio renvoie des codes d'erreur HTTP standard et inclut des en-têtes de limite de débit. Mettez à jour votre logique de tentative pour lire l'en-tête x-ratelimit-remaining et réduire la cadence avant d'atteindre la limite plutôt qu'après.
import time
def search_with_retry(query, num=10, max_retries=3):
for attempt in range(max_retries):
resp = requests.post(
'https://api.scavio.dev/api/v1/search',
headers={'x-api-key': SCAVIO_API_KEY},
json={'query': query, 'num': num}
)
if resp.status_code == 200:
return resp.json()
if resp.status_code == 429:
wait = 2 ** attempt
print(f'Rate limited, waiting {wait}s...')
time.sleep(wait)
continue
resp.raise_for_status()
raise Exception('Max retries exceeded')Étape 5: Validez la parité des sorties
Exécutez les deux API côte à côte sur un échantillon de requêtes et comparez les résultats pour vérifier que votre logique en aval fonctionne correctement. Assurez-vous que les titres, URL et descriptions sont renseignés et que votre code d'analyse gère le nouveau format sans erreur.
test_queries = [
'best crm for startups 2026',
'python web scraping tutorial',
'saas pricing page examples',
]
for q in test_queries:
results = search(q, num=5)
print(f'Query: {q}')
print(f' Results: {len(results)}')
for r in results:
assert r['title'], 'Missing title'
assert r['url'], 'Missing url'
print(f' - {r["title"][:60]}')
print()Exemple Python
import requests
import time
SCAVIO_API_KEY = 'your_scavio_api_key'
def search(query, num=10, max_retries=3):
for attempt in range(max_retries):
resp = requests.post(
'https://api.scavio.dev/api/v1/search',
headers={'x-api-key': SCAVIO_API_KEY},
json={'query': query, 'num': num}
)
if resp.status_code == 200:
data = resp.json()
return [
{
'title': item.get('title', ''),
'url': item.get('url', ''),
'description': item.get('snippet', ''),
}
for item in data.get('organic', [])
]
if resp.status_code == 429:
time.sleep(2 ** attempt)
continue
resp.raise_for_status()
raise Exception('Max retries exceeded')
# Validate migration
test_queries = [
'best crm for startups 2026',
'python web scraping tutorial',
'saas pricing page examples',
]
for q in test_queries:
results = search(q, num=5)
print(f'Query: {q} -> {len(results)} results')
for r in results:
print(f' {r["title"][:60]}')Exemple JavaScript
const SCAVIO_API_KEY = 'your_scavio_api_key';
async function search(query, num = 10, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const resp = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: { 'x-api-key': SCAVIO_API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ query, num }),
});
if (resp.ok) {
const data = await resp.json();
return (data.organic || []).map(item => ({
title: item.title || '',
url: item.url || '',
description: item.snippet || '',
}));
}
if (resp.status === 429) {
await new Promise(r => setTimeout(r, 2 ** attempt * 1000));
continue;
}
throw new Error(`API error: ${resp.status}`);
}
throw new Error('Max retries exceeded');
}
async function main() {
const testQueries = [
'best crm for startups 2026',
'python web scraping tutorial',
'saas pricing page examples',
];
for (const q of testQueries) {
const results = await search(q, 5);
console.log(`Query: ${q} -> ${results.length} results`);
for (const r of results) {
console.log(` ${r.title.slice(0, 60)}`);
}
}
}
main();Sortie attendue
Query: best crm for startups 2026 -> 5 results
The 10 Best CRMs for Startups in 2026 - Detailed Comparison
...
Query: python web scraping tutorial -> 5 results
...
Query: saas pricing page examples -> 5 results
...