DOCUMENTATION DÉVELOPPEURS

Documentation de l’API Serper.live

Un seul endpoint qui lance une vraie recherche Google pour le marché choisi et renvoie les résultats organiques en JSON. Chaque requête est en direct : rien n’est mis en cache, rien n’est rejoué depuis une archive.

En direct pour Allemagne, France, Royaume-Uni, Turquie, Ukraine et États-Unis.
URL de base
https://api.serper.live
Authentification
Jeton Bearer
Format
JSON sur HTTPS
Prix
$0.01 par page (10 résultats maximum)
Sur cette page
01

Démarrage rapide

Trois étapes entre un compte vide et votre premier résultat en direct.

  1. Créez un compte et un jeton dans Jetons API. Le jeton complet n’est affiché qu’une fois : conservez-le dans votre gestionnaire de secrets.
  2. Ajoutez du crédit en USDT ou USDC sur la page Solde. Une recherche en direct coûte $0.01.
  3. Envoyez la requête ci-dessous avec votre jeton. La réponse contient les résultats Google actuels pour ce marché.
curl
curl -X POST https://api.serper.live/v1/search \
  -H "Authorization: Bearer sl_live_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query":"best coffee shops","country":"DE"}'
JavaScript
const response = await fetch('https://api.serper.live/v1/search', {
    method: 'POST',
    headers: {
        Authorization: 'Bearer sl_live_YOUR_TOKEN',
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({ query: 'best coffee shops', country: 'DE' }),
    signal: AbortSignal.timeout(100000),
});
const result = await response.json();

console.log(result.organic);
Python
import requests

response = requests.post(
    "https://api.serper.live/v1/search",
    headers={"Authorization": "Bearer sl_live_YOUR_TOKEN"},
    json={"query": "best coffee shops", "country": "DE"},
    timeout=100,
)
print(response.json()["organic"])

Une recherche en direct répond généralement en 2–3 secondes ; la première requête vers un marché après une pause est plus longue, car une nouvelle session Google s’y ouvre. Gardez un délai d’attente client d’au moins 100 secondes pour qu’une première requête lente n’échoue jamais de votre côté.

02

Authentification

Chaque requête vers /v1/search transmet votre jeton dans l’en-tête Authorization :

HTTP
Authorization: Bearer sl_live_YOUR_TOKEN
  • Les jetons commencent par sl_live_ et se créent dans Jetons API. Créez un jeton par application pour pouvoir le révoquer sans toucher aux autres.
  • Gardez les jetons sur votre serveur. Ne les livrez jamais dans un navigateur, une application mobile ou un dépôt public.
  • Un jeton révoqué cesse de fonctionner immédiatement ; l’historique de ses requêtes reste dans votre compte.
HTTP Code Signification
401 unauthorized L’en-tête Authorization est absent.
401 invalid_token Le jeton est mal formé, révoqué ou inconnu.
03

POST https://api.serper.live/v1/search

Lance une recherche Google en direct et renvoie les résultats organiques. La requête et la réponse sont en JSON ; le corps de la requête est limité à 16 Ko.

Corps de la requête

Champ Type Obligatoire Description
query string oui De 2 à 120 caractères. Les espaces multiples sont réduits à un seul ; les caractères de contrôle sont rejetés.
country string oui Code ISO à deux lettres du marché, par exemple DE. Doit figurer parmi les codes de GET /v1/countries.
language string non Langue de l’interface Google (hl), par exemple tr, en ou pt-BR. Par défaut, la langue du pays.
device string non desktop (par défaut) ou mobile. Change le profil de navigateur et donc la mise en page des résultats.
limit integer non Nombre de résultats organiques, de 1 à 100. 10 par défaut. Chaque bloc de 10 entamé coûte un prix du marché : limit 25 réserve trois prix.

Réponse

Champ Description
requestId UUID de cette requête. Il apparaît dans votre historique des requêtes ; indiquez-le lorsque vous signalez un problème.
query, country, language, device Les valeurs normalisées réellement utilisées.
fetchedAt Horodatage ISO 8601 de la récupération en direct.
latencyMs Durée de la recherche en direct, en millisecondes.
pages Blocs de 10 résultats facturés : au moins un, jamais plus que demandé.
price, currency Coût de cette requête, sous forme de nombre en USD : le prix du marché multiplié par pages.
organic[] Résultats organiques dans l’ordre du classement : position, title, url, domain et snippet. snippet vaut null lorsque Google n’affiche aucune description.
200 OK
{
    "requestId": "0199860b-2f4e-7a1c-9b3d-5e6f70819a2b",
    "query": "best coffee shops",
    "country": "DE",
    "language": "en",
    "device": "desktop",
    "fetchedAt": "2026-09-28T14:00:00.000Z",
    "latencyMs": 1873,
    "price": 0.01,
    "currency": "USD",
    "organic": [
        {
            "position": 1,
            "title": "The 12 best coffee shops in town",
            "url": "https://example.com/guides/best-coffee-shops",
            "domain": "example.com",
            "snippet": "A curated list of specialty coffee shops, updated every month."
        },
        {
            "position": 2,
            "title": "Coffee shops near me",
            "url": "https://maps.example.org/coffee",
            "domain": "maps.example.org",
            "snippet": null
        }
    ]
}
Les résultats sont collectés sur plusieurs pages de résultats jusqu’à atteindre limit, sans les entrées de navigation propres à Google et sans doublons.

Résultats organiques : les champs de organic[]

Chaque élément de organic[] est un résultat organique, dans l’ordre où Google les affiche. Les entrées de navigation propres à Google et les doublons sont écartés, et les résultats sont collectés sur plusieurs pages de résultats jusqu’à atteindre limit.

Les champs sont les mêmes sur ordinateur et sur mobile, et pour chaque marché :

Champ Type Description
position integer Le rang parmi les résultats organiques, de 1 jusqu’à limit (100 au maximum), compté en continu sur les pages de résultats de Google. Seules les entrées organiques sont comptées : c’est le nombre qu’un outil de suivi de positions enregistre.
title string Le titre du résultat tel qu’il apparaît sur la page.
url string L’adresse complète du résultat.
domain string La partie hôte de url, par exemple maps.example.org. Comparez ce champ lorsque vous cherchez un site.
snippet string ou null La description affichée sous le titre ; null lorsque Google n’en affiche aucune.
04

Pays

GET https://api.serper.live/v1/countries

Public, sans jeton. Renvoie les marchés ouverts en ce moment et la langue Google par défaut de chacun ; chaque marché prend en charge desktop et mobile.

curl
curl https://api.serper.live/v1/countries
200 OK
{
    "countries": [
        {
            "code": "DE",
            "defaultLanguage": "de"
        },
        {
            "code": "FR",
            "defaultLanguage": "fr"
        },
        {
            "code": "GB",
            "defaultLanguage": "en"
        },
        {
            "code": "TR",
            "defaultLanguage": "tr"
        },
        {
            "code": "UA",
            "defaultLanguage": "uk"
        },
        {
            "code": "US",
            "defaultLanguage": "en"
        }
    ]
}

Marchés ouverts en ce moment, avec la langue d’interface Google utilisée lorsque language est omis :

Marché Code Langue par défaut Prix par requête Statut
Allemagne DE Allemand $0.01 En direct
France FR Français $0.01 En direct
Royaume-Uni GB Anglais $0.01 En direct
Turquie TR Turc $0.012 En direct
Ukraine UA Ukrainien $0.01 En direct
États-Unis US Anglais $0.0125 En direct

Ouverts actuellement : Allemagne, France, Royaume-Uni, Turquie, Ukraine et États-Unis. Les nouveaux marchés apparaissent ici et sur la page des tarifs dès leur lancement. Une requête pour un marché fermé renvoie 422 country_unavailable avec la liste des codes disponibles.

05

Facturation

Votre compte détient un solde prépayé en USD. Avant le lancement de la recherche, chaque requête réserve le prix actuel de son marché pour chaque bloc de 10 résultats entamé : limit 10 ou moins réserve un prix, limit 25 en réserve trois.

  • Recherche réussie : le prix est facturé pour chaque bloc de 10 qui a reçu des résultats, au moins un, et le reste de la réservation revient aussitôt sur votre solde. limit 50 avec 12 résultats coûte deux prix, pas cinq.
  • Recherche échouée, c’est-à-dire toute réponse 408, 424 ou 5xx : la réservation est libérée automatiquement. Vous ne payez jamais un résultat que vous n’avez pas reçu.
  • Les prix peuvent évoluer, mais le prix réservé pour une requête en cours ne change jamais.
  • Crédit insuffisant : 402 insufficient_balance. Rechargez sur la page Solde ; le crédit est disponible quelques minutes après la confirmation du dépôt.

Chaque requête, son statut et son coût figurent dans l’historique des requêtes ; chaque mouvement du solde figure dans le journal de la page Solde.

06

Erreurs

Les erreurs sont en JSON, avec un code error lisible par une machine, un message lisible par un humain et, dès qu’une requête a été créée, son requestId :

JSON
{
    "error": "insufficient_balance",
    "message": "The balance does not cover one request",
    "requestId": "0199860b-2f4e-7a1c-9b3d-5e6f70819a2b"
}
HTTP Code Signification Réessayer ?
400 invalid_json Le corps n’est pas un JSON valide. Corriger la requête
401 unauthorized
invalid_token
Voir Authentification. Corriger le jeton
402 insufficient_balance Le solde ne couvre pas une requête. Après une recharge
408 search_timeout La recherche ne s’est pas terminée en 90 secondes. Oui
409 idempotency_in_progress
idempotency_replay_unavailable
Voir Relances sûres. Selon le code
413 payload_too_large Le corps dépasse 16 Ko. Corriger la requête
422 invalid_request
country_unavailable
Un champ n’a pas passé la validation (le message le nomme), ou le marché n’est pas ouvert. Corriger la requête
424 proxy_unavailable
captcha_failed
search_failed
La recherche en direct a échoué de notre côté. Oui, après une courte pause
503 busy
billing_unavailable
configuration_error
Le service est à pleine capacité ou temporairement indisponible. Oui, avec un délai croissant
Aucune réponse 408, 424 ou 5xx n’est jamais facturée. Relancez les 408, 424 et 503 avec un délai exponentiel (backoff), par exemple après 5, 15 et 45 secondes, plutôt qu’en boucle serrée, et avec une nouvelle Idempotency-Key : la même clé rejoue la même erreur pendant 15 minutes au plus au lieu de lancer une nouvelle recherche.
07

Relances sûres

Facultatif. Vous n’en avez besoin que si votre client peut relancer une requête interrompue.

Une recherche en direct dure jusqu’à 90 secondes. Si votre connexion tombe entre-temps, vous ne pouvez pas savoir si la recherche s’est terminée et a été facturée. L’en-tête Idempotency-Key vous permet de relancer sans payer deux fois :

  • Même clé : si la première recherche s’est terminée, vous recevez à nouveau la même réponse avec l’en-tête Idempotent-Replayed: true et sans second débit ; une recherche échouée rejoue la même erreur. Si elle est encore en cours, la relance l’attend. Ne réutilisez la clé que si vous n’avez pas reçu le résultat, après une coupure de connexion ou un délai d’attente dépassé côté client ; après une réponse 408, 424 ou 5xx, envoyez une nouvelle clé.
  • La clé seule identifie la recherche : une relance avec un corps différent reçoit la réponse de la première requête ; envoyez donc une nouvelle recherche avec une nouvelle clé.
  • Les résultats sont conservés 15 minutes au plus. Passé ce délai, une relance avec l’ancienne clé renvoie 409 idempotency_replay_unavailable ; envoyez une nouvelle requête avec une nouvelle clé.
  • Sans l’en-tête, chaque requête est nouvelle et facturée séparément.
curl
curl -X POST https://api.serper.live/v1/search \
  -H "Authorization: Bearer sl_live_YOUR_TOKEN" \
  -H "Idempotency-Key: 0199860b-2f4e-7a1c-9b3d-5e6f70819a2b" \
  -H "Content-Type: application/json" \
  -d '{"query":"best coffee shops","country":"DE","limit":10}'

La clé est une chaîne quelconque de 8 à 128 caractères parmi A-Za-z0-9._:-. Un nouvel UUID par requête logique est le choix le plus simple ; gardez-le identique pour toutes les relances de cette requête.

08

Limites et bon à savoir

  • query 2–120 caractères, limit 1–100, corps de requête jusqu’à 16 Ko.
  • Les recherches s’exécutent en parallèle dans la limite de la capacité du service ; au-delà, vous recevez 503 busy. Relancez avec un délai croissant.
  • Généralement 2–3 secondes pour 10 résultats et environ une seconde de plus par page supplémentaire ; une recherche toujours en cours après 90 secondes se termine par 408 search_timeout. Réglez le délai d’attente de votre client sur au moins 100 secondes.
  • Chaque réponse porte un en-tête X-Request-Id. Conservez-le dans vos logs à côté du requestId du corps.
  • Rien n’est mis en cache : deux requêtes identiques sont deux recherches en direct et deux débits. Mettez en cache de votre côté si vous réutilisez les résultats.
09

Trouver la position d’un domaine

L’API renvoie les résultats organiques jusqu’à limit, le top 10 par défaut ; y trouver un site revient à parcourir organic[] dans votre code. Comparez le domain de chaque entrée avec l’hôte que vous suivez : la position de la première correspondance est le classement pour ce mot-clé, ce pays et cet appareil. L’exemple ci-dessous fait exactement cela, avec la même requête en curl, JavaScript et Python.

Trois règles pour une comparaison fiable :

  • Normalisez avant de comparer : passez les deux côtés en minuscules, retirez un www. initial et comparez uniquement les hôtes, jamais les URL complètes.
  • Décidez comment comptent les sous-domaines. blog.example.com est un autre hôte que example.com ; comparez l’hôte exact pour un suivi strict, ou traitez tout hôte qui se termine par .example.com comme le même site pour un suivi au niveau de la marque.
  • Aucune correspondance signifie « hors de la plage demandée » pour ce contrôle, pas une erreur. Enregistrez-le comme tel : une requête renvoie au plus limit résultats organiques, donc augmentez limit (jusqu’à 100, un prix par tranche de 10) si vous suivez des positions au-delà du top 10.
curl
curl -s -X POST https://api.serper.live/v1/search \
  -H "Authorization: Bearer sl_live_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query":"best coffee shops","country":"DE","device":"desktop"}' \
  | jq '.organic[] | select(.domain == "example.com") | .position'
JavaScript
const response = await fetch('https://api.serper.live/v1/search', {
    method: 'POST',
    headers: {
        Authorization: 'Bearer sl_live_YOUR_TOKEN',
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({ query: 'best coffee shops', country: 'DE', device: 'desktop' }),
    signal: AbortSignal.timeout(100000),
});
const { organic } = await response.json();
const hit = organic.find(row => row.domain === 'example.com');

console.log(hit ? hit.position : 'outside the top 10');
Python
import requests

response = requests.post(
    "https://api.serper.live/v1/search",
    headers={"Authorization": "Bearer sl_live_YOUR_TOKEN"},
    json={"query": "best coffee shops", "country": "DE", "device": "desktop"},
    timeout=100,
)
organic = response.json()["organic"]
position = next((row["position"] for row in organic if row["domain"] == "example.com"), None)
print(position or "outside the top 10")

La page API de suivi de positions couvre tout le cycle d’un outil de suivi : listes de mots-clés, planification, stockage et coût d’un mois de vérifications.

10

Utilisation avec des agents IA (MCP)

Le serveur MCP de Serper.live donne aux agents IA comme Claude, OpenAI Codex, Cursor et VS Code Copilot la recherche Google en direct via cette API. Il s’exécute en local avec npx, nécessite Node.js 20 ou une version plus récente et s’authentifie avec le même jeton API dans la variable d’environnement SERPER_LIVE_TOKEN ; les recherches sont facturées exactement comme POST /v1/search.

  • google_search : résultats organiques en direct pour un mot-clé, un pays, une langue et un appareil, jusqu’à 100 par appel.
  • domain_position : la position d’un domaine pour un mot-clé ; un sous-domaine compte comme le domaine, et toutes les positions sont renvoyées si le site apparaît plusieurs fois.
  • list_countries : les marchés ouverts et la langue Google par défaut de chacun ; gratuit, sans jeton.
Claude Code
claude mcp add serper-live -e SERPER_LIVE_TOKEN=sl_live_YOUR_TOKEN -- npx -y @serper-live/mcp
Claude Desktop · Cursor
{
    "mcpServers": {
        "serper-live": {
            "command": "npx",
            "args": [
                "-y",
                "@serper-live/mcp"
            ],
            "env": {
                "SERPER_LIVE_TOKEN": "sl_live_YOUR_TOKEN"
            }
        }
    }
}
VS Code
{
    "inputs": [
        {
            "type": "promptString",
            "id": "serper-live-token",
            "description": "Serper.live API token",
            "password": true
        }
    ],
    "servers": {
        "serper-live": {
            "type": "stdio",
            "command": "npx",
            "args": [
                "-y",
                "@serper-live/mcp"
            ],
            "env": {
                "SERPER_LIVE_TOKEN": "${input:serper-live-token}"
            }
        }
    }
}
Codex
[mcp_servers.serper-live]
command = "npx"
args = ["-y", "@serper-live/mcp"]

[mcp_servers.serper-live.env]
SERPER_LIVE_TOKEN = "sl_live_YOUR_TOKEN"

Le paquet s’appelle @serper-live/mcp sur npm et io.github.serper-live/serper-live-mcp dans le MCP Registry officiel ; le README du dépôt décrit la configuration pour d’autres clients. Claude Desktop l’installe aussi en un clic depuis le bundle .mcpb et demande lui-même le jeton, sans Node.js.

Envoyez votre première requête en direct

Créez un compte, ajoutez du crédit à partir de 5 $ en USDT ou USDC et envoyez la requête du démarrage rapide : le premier résultat en direct n’est qu’à quelques secondes. Pas encore prêt pour un jeton ? Le Playground lance trois recherches en direct par adresse IP et par jour sans compte et affiche les mêmes résultats organiques.