API Storefront / Admin Shopify vs API d’annuaire : deux mondes distincts
C’est la confusion la plus fréquente quand un développeur arrive sur le sujet, donc on la pose en premier.
L’API Storefront et l’API Admin sont les deux APIs officielles de Shopify. Elles vivent toutes les deux sous le domaine du marchand : https://{shop}.myshopify.com/api/... (Storefront, GraphQL ou REST) et https://{shop}.myshopify.com/admin/api/... (Admin). L’authentification se fait avec un jeton d’accès attaché à un seul marchand, généralement obtenu via OAuth quand votre application est installée sur sa boutique. Ces APIs servent à un cas précis : votre application veut lire ou écrire des ressources qui appartiennent à ce marchand (produits, variantes, commandes, clients).
C’est exactement ce qu’il faut quand vous codez une application Shopify (avis, fidélité, livraison, comptabilité). Mais c’est inutilisable pour un cas d’usage transverse :
- Vous ne pouvez pas lister les boutiques Shopify qui utilisent Klaviyo, parce que vous n’avez pas de jeton sur ces boutiques (plus de 59 000 en Europe dans notre base).
- Vous ne pouvez pas lister les nouvelles boutiques Shopify françaises, parce que Shopify n’expose pas de liste multi-marchands à des tiers.
- Vous ne pouvez pas enrichir un compte HubSpot avec « est-ce que ce domaine tourne sous Shopify ? » sans explorer vous-même.
Une API d’annuaire raisonne à l’échelle de l’écosystème, pas à l’échelle d’un magasin :
- Une seule adresse, hors du domaine des marchands :
https://api.ecommerce-leads-database.com/v1/stores/search?... - Une clé API liée à votre compte, dans l’en-tête
X-API-Key, sans OAuth par marchand. - Réponses qui parlent de plusieurs marchands à la fois.
- Champs qui n’existent pas chez Shopify :
country,hasEmail,hasPhone,hasDecisionMaker,domainCreatedOn,audience.
Les deux APIs ne sont pas concurrentes, elles sont complémentaires.
Cas d’usage d’une API d’annuaire
Quatre patterns reviennent dans la plupart des intégrations.
1. Enrichir un CRM (HubSpot, Salesforce, Pipedrive, Attio). Votre équipe commerciale a un compte avec un domaine. Vous voulez savoir si ce domaine tourne sous Shopify, quel thème et quelles applis il utilise, s’il a un email ou un dirigeant connu. Flux : déclencheur HubSpot sur création de compte → appel à GET /v1/stores/{domaine} → écriture des champs personnalisés dans la fiche compte. Un domaine inconnu (404) ne coûte rien.
2. Prospecter les boutiques récentes. Vous voulez approcher les boutiques Shopify françaises dont le domaine a été créé depuis moins de six mois. Flux : une tâche planifiée appelle GET /v1/stores/count (gratuit) avec country=FR et createdAfter, puis /v1/stores/search sur le même filtre → ajout dans une séquence Lemlist ou Smartlead.
3. Alimenter un produit B2B avec une liste à jour. Vous éditez une place de marché de freelances Shopify, un comparateur de thèmes, un outil de découverte d’applications. Votre catalogue interne doit refléter l’état réel de l’écosystème. Une fiche débloquée le reste pour toujours : la relire pour la mettre à jour est gratuit.
4. Scoring et data science. Vous entraînez un modèle qui note des comptes e-commerce. Vous avez besoin d’un échantillon avec des caractéristiques comme theme, productCount, platformRank, audience (classe d’audience Chrome) et les applis détectées.
Pour le profil développeur complet, voir le cas d’usage développeurs d’outils Shopify.
Authentification : la clé X-API-Key
Chaque appel demande votre clé API, sauf /v1/sample. Envoyez-la dans l’en-tête X-API-Key (l’en-tête Authorization: Bearer est aussi accepté). La clé se trouve dans votre page Compte sur ELDB, après l’inscription (50 crédits offerts, sans carte bancaire).
Premier appel conseillé, gratuit : votre solde de crédits.
curl -H "X-API-Key: $CLE" \
"https://api.ecommerce-leads-database.com/v1/me"
Pour voir la forme des données sans clé du tout :
curl "https://api.ecommerce-leads-database.com/v1/sample?limit=10"
Deux règles d’hygiène qu’il faut rappeler :
Ne commitez jamais la clé. Variable d’environnement (ELDB_API_KEY dans un .env ignoré par git pour le dev local), gestionnaire de secrets pour la production.
Ne la mettez jamais côté navigateur. La clé donne accès à vos crédits : elle reste sur votre serveur, et passe toujours dans un en-tête, jamais dans l’URL.
Endpoint principal /v1/stores/search
C’est l’endpoint que vous utiliserez le plus. Il cherche dans la base avec des filtres et renvoie une page de résultats (items) avec un curseur (nextCursor). Toutes les URL partent de https://api.ecommerce-leads-database.com.
Les endpoints
| Endpoint | Effet | Coût |
|---|---|---|
GET /v1/stores/search |
Recherche filtrée, pagination par curseur, 100 résultats par page au plus. | 1 crédit par boutique pas encore débloquée |
GET /v1/stores/count |
Nombre de boutiques qui correspondent aux filtres. | Gratuit |
GET /v1/stores/{domaine} |
Fiche complète d’une boutique. | 1 crédit, gratuit si déjà débloquée |
GET /v1/stores/export.csv |
Mêmes filtres que la recherche, jusqu’à 5 000 lignes par appel. | 1 crédit par boutique pas encore débloquée |
GET /v1/stores/{domaine}/catalog |
Catalogue produits (jusqu’à 5 000 produits, pour une partie des boutiques). | 1 crédit, comme la fiche |
GET /v1/stores/{domaine}/trend |
Historique du trafic organique (pour une partie des boutiques). | 1 crédit, comme la fiche |
GET /v1/sample |
Échantillon de boutiques, sans clé. | Gratuit |
GET /v1/me |
Votre solde de crédits. | Gratuit |
Paramètres de requête
Les mêmes filtres servent à /v1/stores/search, /v1/stores/count et /v1/stores/export.csv.
| Paramètre | Exemple | Effet |
|---|---|---|
platform |
shopify |
Plateforme e-commerce. |
country |
FR |
Pays de la boutique (code ISO). |
region |
FR-IDF,CH-VD |
Région, codes ISO 3166-2 (un code ou une liste séparée par des virgules). |
tld |
fr, com |
Extension du domaine. |
app |
klaviyo |
Une appli détectée sur la boutique. |
currency |
EUR |
Devise de la boutique. |
lang |
fr |
Langue de la boutique. |
operatorCountry |
FR |
Pays de l’opérateur du téléphone. |
createdAfter, createdBefore |
2026-01-01 |
Date de création du domaine (AAAA-MM-JJ). |
activeOnly |
true (par défaut) |
Boutiques actives seulement. |
maxChromeRank |
100000 |
Audience Chrome : palier maximal du classement Chrome UX Report. |
maxPlatformRank |
1000 |
Rang dans la plateforme : garde les N premières boutiques. |
plan |
shopify_plus |
Garde seulement les boutiques confirmées sur Shopify Plus. Seule valeur acceptée. |
minProducts |
50 |
Nombre minimal de produits. |
hasEmail, hasPhone, hasGmb |
true |
Avec email, avec téléphone, avec fiche Google Business. |
hasDecisionMaker, hasDecisionMakerEmail |
true |
Avec au moins un dirigeant connu, ou un dirigeant dont l’email est trouvé. |
genericEmailsOnly |
true |
Emails génériques seulement (contact@…). |
mailProvider |
google-workspace |
Fournisseur de messagerie du domaine. |
dmarcPolicy |
reject |
Politique DMARC du domaine. |
limit |
100 (max) |
Nombre de résultats par page (50 par défaut). |
cursor |
valeur de nextCursor |
Curseur de pagination. |
Le filtre plan=shopify_plus ne garde que les boutiques confirmées sur Shopify Plus : 4 494 en Europe, dont 819 en France, au 6 novembre 2026. La détection continue et le chiffre monte. Il n’existe pas de filtre « pas Plus » : une boutique sans preuve peut quand même être sur Plus. Chaque résultat porte un champ plan (shopify_plus ou null), repris dans la colonne plan du CSV. Les noms exacts et les valeurs permises de chaque paramètre sont dans la documentation de l’API. Une valeur invalide renvoie 400 et ne coûte rien.
Exemple curl simple
D’abord compter, gratuitement, les boutiques Shopify françaises en .fr qui utilisent Klaviyo :
curl -H "X-API-Key: $CLE" \
"https://api.ecommerce-leads-database.com/v1/stores/count?platform=shopify&country=FR&tld=fr&app=klaviyo"
Puis lister la première page :
curl -H "X-API-Key: $CLE" \
"https://api.ecommerce-leads-database.com/v1/stores/search?platform=shopify&country=FR&tld=fr&app=klaviyo&limit=100"
Réponse JSON typique (extrait, une boutique fictive, champs abrégés) :
{
"items": [
{
"domain": "exemple-marchand.fr",
"platform": "shopify",
"tld": "fr",
"country": "FR",
"theme": "Dawn",
"productCount": 214,
"merchantName": "Exemple Marchand",
"hasEmail": true,
"hasPhone": true,
"hasDecisionMaker": true,
"currency": "EUR",
"lang": "fr",
"region": { "code": "FR-IDF", "name": "Île-de-France" },
"domainCreatedOn": "2019-03-14"
}
],
"nextCursor": "18450:01J…"
}
Chaque résultat est un résumé. Pour la fiche complète (emails avec leur type, téléphone, réseaux sociaux, dirigeants, fiche Google Business), appelez /v1/stores/{domaine}.
Export CSV : 5 000 lignes par appel
/v1/stores/export.csv prend les mêmes filtres que la recherche et renvoie un fichier CSV, une ligne par boutique. C’est aujourd’hui la façon d’obtenir un CSV : il n’y a pas encore de bouton « télécharger » dans le compte.
curl -H "X-API-Key: $CLE" \
"https://api.ecommerce-leads-database.com/v1/stores/export.csv?platform=shopify&country=FR&limit=1000&bom=1" \
-o boutiques.csv
limit: de 1 à 5 000 lignes par fichier (1 000 par défaut).bom=1: ajoute la marque d’encodage qui permet à Excel d’ouvrir le fichier sans casser les accents.- Fichier suivant : l’en-tête de réponse
X-Next-Cursorcontient le curseur. Renvoyez-le danscursor. Au dernier fichier, l’en-tête est absent. - Colonnes : entre autres
domain,merchant_name,plan,country_code,city,emails,telephone,linkedin_url,instagram,product_count,first_seen,last_checked,decision_maker_emails.
Suivre les nouveaux marchands, sans notifications
L’API n’envoie pas de notifications : c’est vous qui l’interrogez, à votre rythme. Le schéma qui marche :
- Une tâche planifiée (une fois par jour, par exemple) appelle
/v1/stores/countavec votre filtre. C’est gratuit. - Si le nombre a bougé, elle relance
/v1/stores/searchou l’export sur le même filtre. - Les boutiques déjà débloquées ne coûtent rien : vous ne payez que les nouvelles.
Côté base de données, indexez les boutiques reçues sur le champ domain avec un INSERT ... ON CONFLICT DO NOTHING (ou une mise à jour) pour éviter les doublons d’une passe à l’autre.
Serveur MCP pour les agents IA
Si vous travaillez avec un agent IA (Claude, Cursor…), vous pouvez le brancher directement sur la base, sans écrire de code. Le serveur MCP est à l’adresse https://mcp.ecommerce-leads-database.com/mcp. Même clé, mêmes crédits que l’API, 8 outils (chercher, compter, lire une fiche, lire le catalogue, lire la tendance de trafic, voir son solde…). Le filtre plan=shopify_plus marche aussi dans ces outils.
Avec Claude Code :
claude mcp add eldb --transport http https://mcp.ecommerce-leads-database.com/mcp \
--header "X-API-Key: $CLE"
Vous demandez ensuite en français : « compte les boutiques Shopify françaises qui utilisent Klaviyo et ont un téléphone », puis « exporte-les en CSV ». C’est aussi la façon la plus simple d’obtenir un fichier pour un profil non technique. La configuration pour Cursor et Claude Desktop est dans la documentation.
Code complet : Python
import os
import time
import requests
API_KEY = os.environ["ELDB_API_KEY"]
BASE_URL = "https://api.ecommerce-leads-database.com/v1"
def search_stores(filters: dict, limit: int = 100):
"""Parcourt toutes les boutiques qui correspondent aux filtres, page par page."""
params = {**filters, "limit": limit}
while True:
r = requests.get(
f"{BASE_URL}/stores/search",
params=params,
headers={"X-API-Key": API_KEY},
timeout=30,
)
if r.status_code == 429:
time.sleep(int(r.headers.get("Retry-After", "60")))
continue
if r.status_code == 402:
# Solde trop bas : rien n'est envoyé ni facturé (voir balance et needed)
raise RuntimeError(r.json())
r.raise_for_status()
body = r.json()
yield from body["items"]
if not body["nextCursor"]:
break
params["cursor"] = body["nextCursor"]
if __name__ == "__main__":
filters = {"platform": "shopify", "country": "FR", "app": "klaviyo"}
for store in search_stores(filters):
print(store["domain"], store.get("merchantName"))
Code complet : Node
const API_KEY = process.env.ELDB_API_KEY;
const BASE_URL = 'https://api.ecommerce-leads-database.com/v1';
async function* searchStores(filters, limit = 100) {
const params = new URLSearchParams({ ...filters, limit });
while (true) {
const r = await fetch(`${BASE_URL}/stores/search?${params}`, {
headers: { 'X-API-Key': API_KEY },
});
if (r.status === 429) {
const wait = parseInt(r.headers.get('Retry-After') ?? '60', 10);
await new Promise((res) => setTimeout(res, wait * 1000));
continue;
}
// Solde trop bas : rien n'est envoyé ni facturé (voir balance et needed)
if (r.status === 402) throw new Error(JSON.stringify(await r.json()));
if (!r.ok) throw new Error(`HTTP ${r.status}`);
const body = await r.json();
for (const store of body.items) yield store;
if (!body.nextCursor) break;
params.set('cursor', body.nextCursor);
}
}
(async () => {
const filters = { platform: 'shopify', country: 'FR', app: 'klaviyo' };
for await (const store of searchStores(filters)) {
console.log(store.domain, store.merchantName);
}
})();
Crédits, pagination, erreurs
Crédits
- 1 crédit = 1 fiche boutique renvoyée, dirigeants inclus. Une page de 100 nouvelles boutiques coûte 100 crédits.
- Une fiche débloquée le reste pour toujours : la relire, sur la recherche, la fiche ou l’export, ne coûte rien.
- Gratuit :
/v1/stores/count,/v1/me,/v1/sample, et toute erreur qui ne renvoie aucune boutique. - En-têtes de réponse :
X-Credits-Charged(crédits pris par l’appel) etX-Credits-Balance(votre solde après l’appel). - Packs, paiement unique, prix HT : 1 000 crédits 29 €, 5 000 crédits 99 €, 20 000 crédits 299 €, 100 000 crédits 990 €. Crédits valables 12 mois, pas d’abonnement. Voir les tarifs.
Pagination par curseur
L’API utilise un curseur, pas un décalage. C’est volontaire : sur une base qui change, un décalage numérique saute ou duplique des lignes. Le curseur garantit la cohérence de l’itération. Pour la recherche, renvoyez nextCursor dans cursor (il vaut null à la dernière page) ; pour l’export CSV, le curseur est dans l’en-tête X-Next-Cursor.
Codes d’erreur
400: un paramètre est invalide. Rien n’est facturé.401: clé absente, inconnue ou révoquée.402: solde trop bas. La réponse donne votre solde et les crédits demandés ; rien n’est envoyé, pas même une page partielle. Baissezlimitou achetez un pack.404: domaine inconnu. Gratuit.429: trop d’appels en peu de temps. Attendez le délai de l’en-têteRetry-After. Ce n’est pas un quota : il n’y a pas de limite mensuelle d’appels, seulement des crédits.
Ce que l’API ne fait pas
Transparence d’abord :
- Pas de notifications automatiques. L’API ne pousse rien vers vous : interrogez le comptage gratuit à votre rythme (voir plus haut).
- Pas de sièges ni de quota mensuel. Un compte, une clé, des crédits.
- Shopify Plus : seulement les boutiques confirmées.
plan=shopify_plusne trouve pas une boutique Plus sans preuve ; une case vide veut dire « inconnu », pas « pas Plus ». - Pas de chiffre d’affaires estimé. Le modèle n’est pas assez précis pour être publié.
- Pas encore de bouton « télécharger le CSV » dans le compte. Le CSV s’obtient par l’API (une commande curl) ou en le demandant à votre agent IA branché en MCP.
Voir aussi
- Reconnaître un site Shopify : les 4 signatures techniques.
- Combien de boutiques Shopify y a-t-il en France ? : nos chiffres datés et la méthode.
- Extraire une liste de boutiques Shopify : outil maison, sources publiques ou achat.
- Prospecter les boutiques Shopify en B2B : pourquoi Apollo et Sales Navigator ne suffisent pas.
- RGPD prospection B2B e-commerce : base légale et opt-out.
Documentation complète sur la doc API d’ELDB · Résumé sur la page API · Tarifs · Cas d’usage développeurs d’outils · Retour au panorama des guides · Retour à l’accueil. Une question : hello@ecommerce-leads-database.com.