Les ventes ne sont pas encore ouvertes. Les tarifs sont indicatifs. Demander un accès pilote

Documentation de l'API

Une API REST simple. Vous envoyez une requête, vous recevez du JSON.

Authentification

Chaque appel demande votre clé API, sauf /v1/sample. Envoyez-la dans l'en-tête X-API-Key, ou dans l'en-tête Authorization: Bearer. Votre clé est dans votre page Compte.

Les clés commencent par eldb_live_. Gardez la vôtre secrète : ne la mettez jamais dans le code d'une page web.

curl https://api.ecommerce-leads-database.com/v1/me \
  -H "X-API-Key: eldb_live_…"

# Ou, au choix :
curl https://api.ecommerce-leads-database.com/v1/me \
  -H "Authorization: Bearer eldb_live_…"

Endpoints

Toutes les URL partent de https://api.ecommerce-leads-database.com.

GET/v1/sample

Échantillon gratuit (sans clé)

Renvoie quelques boutiques : 10 par défaut, 20 au plus. Pour voir la forme des données avant d'acheter des crédits. Gratuit.

curl "https://api.ecommerce-leads-database.com/v1/sample?limit=10"
GET/v1/me

Votre solde de crédits

Renvoie votre solde, les crédits qui expirent en premier, un ancien plan encore actif (legacyPlan, sinon null) et la grille de prix (pricing). Gratuit.

curl https://api.ecommerce-leads-database.com/v1/me \
  -H "X-API-Key: eldb_live_…"

{
  "credits": {
    "balance": 18450,
    "nextExpiry": { "credits": 18450, "at": "2027-10-24T09:12:00.000Z" }
  },
  "legacyPlan": null,
  "pricing": {
    "creditPerStoreRow": 1,
    "unlockedStoresStayFree": true,
    "free": ["/v1/stores/count", "/v1/me", "/v1/enrichments/:jobId"],
    "managedEnrichment": { "perWorkEmailFound": 6, "perMobileFound": 60 },
    "packs": [
      { "id": "credits_1k", "credits": 1000, "priceEurExclVat": 29 },
      { "id": "credits_5k", "credits": 5000, "priceEurExclVat": 99 },
      { "id": "credits_20k", "credits": 20000, "priceEurExclVat": 299 },
      { "id": "credits_100k", "credits": 100000, "priceEurExclVat": 990 }
    ]
  }
}
GET/v1/stores/count

Compter les boutiques

Renvoie le nombre de boutiques qui correspondent aux filtres, et combien ont une fiche Google. Gratuit.

Paramètres : platform, tld, country, hasGmb, hasEmail, hasPhone, app, currency, lang, operatorCountry, activeOnly, genericEmailsOnly, includeUnverified, includeAliases, maxChromeRank, mailProvider, dmarcPolicy, trackingId, hasDecisionMaker, hasDecisionMakerEmail, region, createdAfter, createdBefore, maxPlatformRank, plan

curl "https://api.ecommerce-leads-database.com/v1/stores/count?platform=shopify" \
  -H "X-API-Key: eldb_live_…"

{ "count": 29331, "gmbCount": 6511 }

Chiffres réels pour les boutiques Shopify vérifiées.

GET/v1/stores/search

Chercher des boutiques

Filtre la base et renvoie une page de résultats (items) avec un curseur (nextCursor).

Paramètres : platform, tld, country, minProducts, hasGmb, hasEmail, hasPhone, app, currency, lang, operatorCountry, activeOnly, genericEmailsOnly, includeUnverified, includeAliases, maxChromeRank, mailProvider, dmarcPolicy, trackingId, hasDecisionMaker, hasDecisionMakerEmail, region, createdAfter, createdBefore, maxPlatformRank, plan, cursor, limit

  • limit : de 1 à 100 résultats par page. 50 par défaut.
  • Tri : du plus fort trafic au plus faible. Les boutiques sans trafic connu arrivent en dernier.
  • Par défaut, search et count ne renvoient que les boutiques vérifiées : une vraie boutique en ligne, revérifiée sur son site. Ajoutez includeUnverified=true pour inclure aussi les sites vitrines et les sites injoignables.
  • activeOnly vaut true par défaut : les boutiques notées inactives sont exclues. Ajoutez activeOnly=false pour les inclure.
  • Filtres : hasEmail (email collecté dans les 12 derniers mois), hasPhone, app (une app détectée, ex. Klaviyo), currency (EUR), lang (fr), operatorCountry (FR), genericEmailsOnly (avec hasEmail : adresses génériques seulement). Une valeur invalide renvoie 400 invalid_parameter et ne coûte rien.
  • maxChromeRank (palier maximal du classement Chrome UX Report : 1000, 5000, 10000, 50000, 100000, 500000, 1000000, 5000000, 10000000 ou 50000000). Toute autre valeur renvoie 400 invalid_parameter. Le champ audience contient des données du Chrome UX Report (Google), sous licence CC BY-SA 4.0.
  • mailProvider (fournisseur de messagerie déduit du MX : google-workspace, microsoft-365, ovh, infomaniak, ionos, gandi, zoho, proton, o2switch, hostinger, other, none) et dmarcPolicy (none, quarantine, reject ou missing). Toute autre valeur renvoie 400 invalid_parameter. Le filtre app trouve aussi les outils lus dans le DNS (par exemple Klaviyo via SPF). Slugs d'apps que le DNS peut ajouter : klaviyo, mailchimp, brevo, shopify email, mailjet, sendgrid, hubspot, salesforce marketing cloud, omnisend, mandrill, amazon ses, zendesk, mailgun, meta business, google site verification, pinterest, apple, atlassian, zoom, stripe, shopify.
  • Codes de suivi publics : utilisez trackingId pour retrouver les autres boutiques qui partagent un même code. Passez une valeur seule comme GTM-ABC123, AW-123456789, G-ABCDEF1234, UA-1234567-1 ou ca-pub-1234567890123456. Les codes numériques demandent leur type devant : meta:123456789012345, tiktok:…, pinterest:…, microsoftAds:…, linkedin:…, hotjar:…, criteo:…, snapchat:…, clarity:…, klaviyo:… (Klaviyo distingue majuscules et minuscules). Toute autre valeur renvoie 400 invalid_parameter. Chaque résultat contient aussi trackingIds (null tant que la boutique n'a pas été lue).
  • hasDecisionMaker=true|false (au moins un dirigeant connu, ou aucun) et hasDecisionMakerEmail=true (au moins un dirigeant dont l'email a été trouvé sur le site ou validé par le serveur de messagerie). Toute autre valeur renvoie 400 invalid_parameter. Chaque résultat contient aussi hasDecisionMaker.
  • region filtre sur la région de la boutique : un code ISO 3166-2 ou une liste séparée par des virgules, par exemple region=FR-IDF,CH-VD. Codes : régions françaises (FR-IDF, FR-ARA…), provinces belges (BE-BRU, BE-VAN…), cantons suisses (CH-VD, CH-ZH…) et LI. createdAfter et createdBefore (YYYY-MM-DD) filtrent sur la date de création du domaine : createdAfter inclut le jour, createdBefore ne l'inclut pas. maxPlatformRank garde les N premières boutiques de chaque plateforme, par exemple platform=shopify&maxPlatformRank=1000. plan=shopify_plus garde les boutiques Shopify Plus confirmées : une app du site affiche la formule, ou le paiement montre des fonctions réservées à Plus. C'est la seule valeur : une boutique sans cette preuve peut quand même être sur Plus. Les boutiques sans valeur connue sont écartées. Une valeur invalide renvoie 400 invalid_parameter et ne coûte rien.
  • Page suivante : renvoyez la valeur de nextCursor dans le paramètre cursor. À la dernière page, nextCursor vaut null.
  • Chaque boutique renvoyée coûte 1 crédit, sauf si vous l'avez déjà débloquée. Une fiche débloquée le reste pour toujours. Une page de 50 nouvelles boutiques coûte 50 crédits. Si le solde ne suffit pas, la réponse est 402 et rien n'est envoyé : baissez limit.
  • Chaque résultat est un résumé de boutique : domaine, plateforme, pays, thème, nombre de produits, apps, trafic, nom du marchand, note et catégorie Google, hasEmail, hasPhone, hasDecisionMaker, currency, lang, operatorCountry, isActiveShop, region, domainCreatedOn, domainCreatedSource, domainCreatedEstimated, platformRank, linkedinUrl, plan. Chaque résultat contient aussi audience (null si la boutique n'est pas dans le classement Chrome UX Report). Chaque résultat contient aussi dns (null tant que la boutique n'a pas été lue). Pour la fiche complète, appelez /v1/stores/:domain.
curl -G https://api.ecommerce-leads-database.com/v1/stores/search \
  -H "X-API-Key: eldb_live_…" \
  -d platform=shopify \
  -d minProducts=50 \
  -d hasGmb=true \
  -d limit=50

{
  "items": [
    { "domain": "…", "platform": "shopify", "productCount": …, "merchantName": "…", … }
  ],
  "nextCursor": "18450:01J…"
}
GET/v1/stores/export.csv

Exporter des boutiques (CSV)

Les mêmes filtres que la recherche, dans un fichier CSV à ouvrir dans un tableur. Une ligne par boutique, après une ligne d'en-tête.

Paramètres : platform, tld, country, minProducts, hasGmb, hasEmail, hasPhone, app, currency, lang, operatorCountry, activeOnly, genericEmailsOnly, includeUnverified, includeAliases, maxChromeRank, mailProvider, dmarcPolicy, trackingId, hasDecisionMaker, hasDecisionMakerEmail, region, createdAfter, createdBefore, maxPlatformRank, plan, cursor, limit, bom

  • limit : de 1 à 5 000 boutiques par fichier. 1 000 par défaut.
  • Fichier suivant : l'en-tête de réponse X-Next-Cursor contient le curseur. Renvoyez-le dans le paramètre cursor. Au dernier fichier, l'en-tête est absent.
  • Colonnes, dans cet ordre : domain, merchant_name, platform, plan, country_code, state, city, created, emails, telephone, linkedin_url, linkedin_account, facebook, instagram, pinterest, tiktok, twitter, estimated_monthly_sales, estimated_yearly_sales, platform_rank, product_count, crux_rank_class, status, first_seen, last_checked, decision_maker_emails, facebook_followers, instagram_followers, pinterest_followers, tiktok_followers. Les listes (emails, decision_maker_emails) sont séparées par deux-points. Les dates sont au format AAAA-MM-JJ. Les colonnes *_followers restent vides tant que le compte n'est pas compté : l'export demande les chiffres qui manquent, et ils figurent dans un export suivant.
  • estimated_monthly_sales et estimated_yearly_sales sont vides pour le moment. Elles restent dans l'en-tête pour que le format du fichier ne change pas quand les données arriveront. plan vaut Shopify Plus quand nous l'avons confirmé. Une case vide veut dire inconnu, pas un autre plan.
  • Pour Excel, ajoutez bom=1 : le fichier commence alors par un BOM UTF-8 et les accents s'affichent correctement.
  • Les emails suivent les règles de /v1/stores/:domain : une adresse dont le titulaire s'est opposé n'est jamais envoyée, une adresse collectée il y a plus de 12 mois est retirée, et genericEmailsOnly=true ne garde que les boîtes génériques (et aucun email de dirigeant).
  • Une cellule qui commence par =, +, - ou @ reçoit un ' devant, pour qu'un tableur ne la lise jamais comme une formule. Un numéro comme +33… s'affiche '+33….
  • Chaque boutique du fichier coûte 1 crédit, sauf si vous l'avez déjà débloquée. Si le solde ne suffit pas, la réponse est 402 et aucun fichier n'est envoyé : baissez limit.
curl -G https://api.ecommerce-leads-database.com/v1/stores/export.csv \
  -H "X-API-Key: eldb_live_…" \
  -d country=FR \
  -d hasEmail=true \
  -d limit=5000 \
  -D headers.txt -o stores.csv

# headers.txt
X-Next-Cursor: 18450:01J…
X-Credits-Charged: 5000

# stores.csv
domain,merchant_name,platform,plan,country_code,state,city,created,emails,…
probikeshop.fr,Probikeshop,shopify,,FR,…
GET/v1/stores/:domain

Fiche d'une boutique

Renvoie la fiche complète d'une boutique. Coûte 1 crédit, gratuit si vous l'avez déjà débloquée. Le catalogue n'est pas inclus : utilisez /catalog. Chaque email est renvoyé avec son type ; ajoutez genericEmailsOnly=true pour ne recevoir que les adresses génériques. genericEmailsOnly=true masque aussi les emails des dirigeants.

ChampContenu
domainNom de domaine de la boutique.
platformPlateforme e-commerce détectée (shopify, woocommerce…).
tldExtension du domaine.
countryPays (code ISO).
themeThème détecté.
productCountNombre de produits détectés.
verificationStatusRésultat du dernier contrôle du site.
lastSuccessAtDate du dernier contrôle réussi.
firstSeenAtDate d'entrée de la boutique dans la base.
detectedAppsApplications et outils détectés sur le site.
trafficEstimation du trafic mensuel et des mots-clés organiques.
audienceAudience Chrome : { chromeRank, class, country, month, source }. chromeRank est le palier du classement Chrome UX Report (Google) pour ce pays : 1000, 5000, 10000… jusqu'à 50000000. null si la boutique n'est pas classée. Ce champ est partagé sous licence CC BY-SA 4.0 : citez la source et gardez la même licence. Valeurs de class : top_1k, top_5k, top_10k, top_50k, top_100k, top_500k, top_1m, top_5m, top_10m, top_50m. Source du Chrome UX Report : https://developer.chrome.com/docs/crux. Licence : https://creativecommons.org/licenses/by-sa/4.0/. Données adaptées : rangs rapprochés des boutiques et regroupés par pays par nos soins.
dnsDNS : { mailProvider, dmarcPolicy, apps, checkedAt }. mailProvider est le fournisseur de messagerie déduit du MX (google-workspace, microsoft-365, ovh, infomaniak, ionos, gandi, zoho, proton, o2switch, hostinger, other, none). dmarcPolicy vaut none, quarantine, reject ou missing (aucun enregistrement). apps liste les outils d'envoi d'emails et de vérification de domaine lus dans les enregistrements SPF et TXT. checkedAt est la date de la lecture. null tant que la boutique n'a pas été lue. Aucun jeton de vérification n'est exposé.
trackingIdstrackingIds : codes de suivi et de publicité publics (Google Ads, Meta, TikTok…) regroupés par type, par exemple { "gtm": ["GTM-ABC123"], "googleAds": ["AW-123456789"], "meta": ["123456789012345"] }. Types : ga4, ua, gtm, googleAds, floodlight, adsense, meta, tiktok, pinterest, microsoftAds, linkedin, snapchat, criteo, clarity, hotjar, klaviyo. {} si rien n'a été trouvé, null tant que la boutique n'a pas été lue. Seuls les codes que tout visiteur peut voir dans le code source de la page.
platformVersionVersion de la plateforme (PrestaShop, Magento, Odoo) quand le site l'affiche.
operatorPays de l'entreprise derrière la boutique ({ country, source }) : d'après son numéro de TVA, les réglages Shopify, l'adresse des mentions légales, le téléphone ou l'extension, dans cet ordre. Peut différer de l'extension.
isActiveShopfalse quand la boutique semble inactive (catalogue vide, produits de démo, devise par défaut), avec les raisons dans activeShopReasons. null tant qu'elle n'est pas notée.
regionRégion de la boutique ({ code, name }) : code ISO 3166-2, par exemple FR-IDF, BE-VBR ou CH-VD, et son nom en anglais. D'après le siège inscrit au registre, sinon d'après l'adresse publiée par la boutique. null si elle est inconnue.
domainCreatedOnDate de création du domaine (YYYY-MM-DD), avec domainCreatedSource et domainCreatedEstimated. afnic : le fichier ouvert de l'AFNIC (.fr). rdap : le service RDAP public du registre. zone_first_seen : le premier jour où nous avons vu le domaine dans un fichier de zone public. domainCreatedEstimated vaut true quand la date ne vient pas du registre : le domaine peut être plus ancien. Les trois valent null si la date est inconnue.
platformRankRang de la boutique parmi les boutiques de la même plateforme dans ELDB, selon leurs visites estimées. 1 est la plus visitée. Mis à jour chaque mois. Pas comparable aux rangs d'autres outils. null si la boutique n'a pas de données de trafic.
linkedinUrlLa page entreprise LinkedIn de la boutique, trouvée sur son site. Jamais un profil personnel. null si aucune n'a été trouvée.
socialFollowersNombre d'abonnés des comptes de la boutique : { facebook, instagram, pinterest, tiktok }, chacun { followers, status, checkedAt }. status vaut ok (compté à la date checkedAt), not_found (compte introuvable ou privé) ou pending (pas encore compté). Un compte jamais compté, ou compté il y a plus de 30 jours, est demandé quand vous lisez la boutique : son chiffre arrive en général en moins d'une heure, à une lecture suivante. Seuls les réseaux où la boutique a un compte apparaissent.
planshopify_plus quand la boutique est confirmée sur Shopify Plus : une app du site affiche la formule, ou le paiement montre des fonctions réservées à Plus. null veut dire inconnu, pas un autre plan.
legalPage de mentions légales : pageUrl, companyIds (SIREN, TVA, numéro d'entreprise BE, IDE CH, vérifiés par leur clé), legalForm.
shopifyBoutiques Shopify : shopId, isPlus, shipsToCountries, shopPayInstallments, collectionsCount, themeStoreId.
catalogStatsChiffres du catalogue quand la plateforme les expose : prix et poids moyens, variantes, images, marques, types de produits, catégories, date du dernier produit.
metadatamerchantName ; contactEmail avec contactEmailType (generic, personal ou unknown) et emailDomainMatch ; telephone (E.164) avec phoneType (mobile, fixed_line…) ; address ; socialLinks ; sources (page et date de collecte de chaque contact) ; title, metaDescription, lang, currency, hreflangs, features, paymentMethods, shippingCarriers, salesChannels, copyrightYear, contactPageUrl, canonicalUrl. Un contact collecté il y a plus de 12 mois, ou un email dont le titulaire s'est opposé, vaut null avec la raison dans contactEmailWithheld, telephoneWithheld ou addressWithheld.
emailsTous les emails publiés par la boutique : [{ email, type, sourceUrl }]. type vaut generic, personal ou unknown ; sourceUrl est la page où l'email a été lu. 10 au plus, le meilleur d'abord. Un email lu il y a plus de 12 mois, ou retiré par son titulaire, n'est pas renvoyé. Avec genericEmailsOnly=true, seuls les emails generic restent.
decisionMakersDirigeants : [{ firstName, lastName, role, source, sourceUrl, since, email, emailStatus }], le dirigeant principal d'abord. role : owner (propriétaire, entrepreneur individuel), president, managing_director (directeur général), manager (gérant), publication_director (directeur de la publication), partner (associé), administrator (administrateur), other. source : rne (registre national des entreprises, France), zefix (registre du commerce, Suisse) ou legal_page (mentions légales de la boutique). sourceUrl : la fiche publique de l'entreprise dans le registre, ou la page de mentions légales. since : date d'entrée en fonction quand le registre la donne, sinon null. emailStatus : found_on_site (adresse publiée sur le site), valid (acceptée par le serveur de messagerie du domaine), catch_all (le serveur accepte toutes les adresses : format le plus probable, non confirmé), pattern (déduite du format d'adresse du domaine, non vérifiée), not_found (aucune adresse acceptée par le serveur), null (aucune adresse connue). email vaut null si l'adresse a été retirée par son titulaire, si elle date de plus de 12 mois, ou avec genericEmailsOnly=true. Un dirigeant lu il y a plus de 12 mois n'est plus renvoyé. Jamais de date de naissance, de nationalité ni d'adresse personnelle.
companyFiche du registre des entreprises : { registry, registryId, officialName, activityCode, headcountBand, createdOn, category, legalFormCode, active, hq, checkedAt }. registry vaut fr, be ou ch ; registryId est le SIREN, le numéro d'entreprise BE ou l'IDE CH. officialName : dénomination officielle. activityCode : code d'activité (NAF ou NACE). headcountBand : tranche d'effectif salarié, par exemple "10-19". createdOn : date de création. category : catégorie d'entreprise (France). legalFormCode : code de forme juridique du registre. active : false si l'entreprise est fermée. hq : code postal et commune du siège. checkedAt : date de la dernière lecture du registre. Un champ que le registre ne donne pas vaut null. company vaut null si la boutique n'a pas d'identifiant d'entreprise, si le registre ne la connaît pas, ou si la lecture date de plus de 12 mois.
gmbFiche Google : placeId, category, additionalCategories, rating, ratingDistribution, isClaimed, totalPhotos, workTime, address, addressInfo, latitude, longitude, phone, website. null s'il n'y en a pas.
curl https://api.ecommerce-leads-database.com/v1/stores/probikeshop.fr \
  -H "X-API-Key: eldb_live_…"

{
  "store": {
    "domain": "probikeshop.fr",
    "platform": "shopify",
    "tld": "fr",
    "country": "FR",
    "theme": "…",
    "productCount": 5000,
    "verificationStatus": "…",
    "lastSuccessAt": "…",
    "detectedApps": ["…"],
    "trackingIds": { "gtm": ["GTM-ABC123"], "googleAds": ["AW-123456789"] },
    "operator": { "country": "FR", "source": "vat" },
    "isActiveShop": true,
    "region": { "code": "FR-…", "name": "…" },
    "domainCreatedOn": "…",
    "domainCreatedSource": "afnic",
    "domainCreatedEstimated": false,
    "platformRank": …,
    "linkedinUrl": "https://www.linkedin.com/company/…/",
    "plan": "shopify_plus",
    "legal": { "pageUrl": "…", "companyIds": { "siren": "…", "vat": "…" }, "legalForm": "SAS" },
    "metadata": {
      "merchantName": "…",
      "contactEmail": "…",
      "contactEmailType": "generic",
      "contactEmailWithheld": null,
      "telephone": "+33…",
      "phoneType": "fixed_line",
      "address": { … },
      "sources": {
        "contactEmail": { "url": "https://…/mentions-legales", "at": "2026-10-19T08:00:00.000Z" }
      },
      "socialLinks": { "instagram": "…" },
      "currency": "EUR",
      "lang": "fr"
    },
    "socialFollowers": {
      "instagram": { "followers": 12400, "status": "ok", "checkedAt": "2026-11-04T09:00:00.000Z" }
    },
    "emails": [
      { "email": "contact@…", "type": "generic", "sourceUrl": "https://…/contact" }
    ],
    "decisionMakers": [
      {
        "firstName": "Marie", "lastName": "Durand", "role": "president",
        "source": "rne", "sourceUrl": "https://annuaire-entreprises.data.gouv.fr/entreprise/…",
        "since": "2019-03-01", "email": "marie.durand@…", "emailStatus": "valid"
      }
    ],
    "company": {
      "registry": "fr", "registryId": "…", "officialName": "…",
      "activityCode": "47.91B", "headcountBand": "10-19", "createdOn": "…",
      "category": "PME", "legalFormCode": "5710", "active": true,
      "hq": "…", "checkedAt": "…"
    },
    "gmb": {
      "placeId": "…", "category": "…", "rating": 4.5, "votes": 594,
      "address": "…", "phone": "…", "website": "…"
    }
  }
}
GET/v1/stores/:domain/catalog

Catalogue produits

Renvoie les produits de la boutique, 5 000 au plus. Disponible pour une partie des boutiques Shopify et WooCommerce. Sinon, erreur 404 no_catalog, non facturée. Coûte 1 crédit, comme la fiche.

curl https://api.ecommerce-leads-database.com/v1/stores/probikeshop.fr/catalog \
  -H "X-API-Key: eldb_live_…"

{
  "domain": "probikeshop.fr",
  "catalog": [
    {
      "id": "…", "title": "…", "handle": "…", "vendor": "…",
      "productType": "…", "tags": ["…"],
      "price": …, "compareAtPrice": …, "currency": "EUR",
      "available": true, "imageUrl": "…", "imageCount": …, "variantCount": …,
      "createdAt": "…", "updatedAt": "…"
    }
  ]
}
GET/v1/stores/:domain/trend

Tendance de trafic

Renvoie l'historique mensuel du trafic organique et des positions. Erreur 404 no_trend s'il n'y a pas de données, non facturée. Coûte 1 crédit, comme la fiche.

curl https://api.ecommerce-leads-database.com/v1/stores/probikeshop.fr/trend \
  -H "X-API-Key: eldb_live_…"

{
  "domain": "probikeshop.fr",
  "trend": [
    { "date": "2026-07-01", "organicTraffic": 197021, "organicPositions": 19377 }
  ],
  "savedAt": "2026-07-01T04:12:08.441Z"
}

Enrichir avec vos clés

Trouvez l'email et le téléphone des dirigeants d'une boutique avec votre propre compte Apollo, FullEnrich, Kaspr ou Dropcontact. L'appel utilise vos crédits chez le fournisseur. ELDB ne prend aucun crédit pour l'enrichissement. Les résultats sont à vous : aucun autre client ne les voit.

Enregistrez vos clés de fournisseur dans votre compte, page Mes clés de fournisseurs. Elles ne passent jamais par l'API : une clé ELDB volée ne permet ni de les lire ni de les changer.

Par demande : 25 boutiques et 3 dirigeants par boutique. Par client : 3 enrichissements en cours, et 500 personnes par fournisseur et par jour (UTC). Un résultat est servi 12 mois, puis effacé à 13 mois.

GET/v1/enrichment/providers

Vos fournisseurs

Liste les fournisseurs dont la clé est enregistrée, avec leur statut et les crédits restants quand le fournisseur les donne. managedProviders liste les fournisseurs disponibles sur notre compte. Gratuit.

curl https://api.ecommerce-leads-database.com/v1/enrichment/providers \
  -H "X-API-Key: eldb_live_…"

{
  "providers": [
    { "provider": "dropcontact", "status": "valid", "creditsRemaining": 250 }
  ],
  "managedProviders": ["fullenrich"]
}
POST/v1/enrichments

Lancer un enrichissement

Envoyez provider et domain (une boutique) ou domains (25 au plus). maxPeoplePerStore : de 1 à 3, 2 par défaut. phones : true pour demander aussi les téléphones (plus de crédits). force : true pour relancer une personne enrichie il y a moins de 30 jours. La réponse donne les noms et fonctions des dirigeants : chaque boutique qui en a coûte 1 crédit, gratuit si vous l'avez déjà débloquée. Avec votre clé, l'enrichissement lui-même est gratuit. Réponse 200 avec les résultats quand le fournisseur répond tout de suite, sinon 202 : suivez le job.

curl -X POST https://api.ecommerce-leads-database.com/v1/enrichments \
  -H "X-API-Key: eldb_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "provider": "dropcontact", "domains": ["probikeshop.fr"], "maxPeoplePerStore": 2 }'

HTTP/1.1 202 Accepted
{
  "job": {
    "id": "…", "provider": "dropcontact", "status": "queued", "phones": false,
    "storeCount": 1, "personCount": 2, "creditsUsed": null, "errorCode": null,
    "createdAt": "…", "updatedAt": "…"
  },
  "results": [
    { "domain": "probikeshop.fr", "status": "ok", "people": [ … ] }
  ]
}
GET/v1/enrichments/:jobId

Suivre un enrichissement

Renvoie le statut du job (queued, submitted, done, partial, failed, canceled) et les résultats par boutique. Gratuit. Un job géré renvoie aussi managed, eldbCreditsReserved et eldbCreditsCharged. Attendez au moins 20 secondes entre deux appels.

curl https://api.ecommerce-leads-database.com/v1/enrichments/<jobId> \
  -H "X-API-Key: eldb_live_…"
GET/v1/stores/:domain/enrichment

Résultats d'une boutique

Renvoie la plateforme, le nom du marchand, les dirigeants, vos fournisseurs et vos résultats. Coûte 1 crédit, gratuit si vous l'avez déjà débloquée. DELETE sur la même URL efface vos résultats pour cette boutique.

curl https://api.ecommerce-leads-database.com/v1/stores/probikeshop.fr/enrichment \
  -H "X-API-Key: eldb_live_…"

{
  "domain": "probikeshop.fr",
  "platform": "…",
  "merchantName": "…",
  "providers": ["dropcontact"],
  "decisionMakers": [{ "firstName": "…", "lastName": "…", "role": "president" }],
  "results": [
    {
      "firstName": "…", "lastName": "…", "role": "president", "provider": "dropcontact",
      "status": "found", "skipReason": null,
      "email": "…", "emailStatus": "valid", "emailStatusRaw": "nominative@pro", "emailKind": "professional",
      "phone": null, "phoneType": null, "linkedinUrl": "…", "jobTitle": "…",
      "creditsUsed": 1, "errorCode": null, "enrichedAt": "…", "reused": false
    }
  ]
}

managed: true

Sans clé, envoyez managed: true avec provider fullenrich. Nous utilisons alors notre compte FullEnrich. Vous payez en crédits ELDB, seulement sur résultat : 6 par email pro trouvé, 60 par mobile trouvé (avec phones: true), 0 si rien n'est trouvé. Au lancement, nous réservons le maximum : 6 crédits par personne envoyée, 66 avec les téléphones. À la fin, ce qui n'a pas servi revient sur votre solde. Si le solde ne suffit pas, la réponse est 402 insufficient_credits et rien n'est envoyé.

curl -X POST https://api.ecommerce-leads-database.com/v1/enrichments \
  -H "X-API-Key: eldb_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "provider": "fullenrich", "managed": true, "domains": ["probikeshop.fr"], "maxPeoplePerStore": 2 }'

Chaque résultat contient firstName, lastName, role, provider, status (pending, found, not_found, skipped, error), skipReason, email, emailStatus (valid, risky, catch_all, invalid, unknown), emailStatusRaw (le libellé du fournisseur), emailKind (professional, generic, personal), phone, phoneType, linkedinUrl, jobTitle, creditsUsed, errorCode, enrichedAt et reused (true : résultat déjà obtenu, sans nouveaux crédits).

GET /v1/stores/:domain renvoie aussi enrichment : vos propres résultats pour cette boutique, à côté de decisionMakers. Tableau vide si vous n'en avez pas.

Crédits et coûts

Vous payez en crédits. 1 crédit = 1 boutique renvoyée, dirigeants inclus. Il n'y a ni abonnement, ni quota de requêtes.

Packs, paiement unique, prix HT : 1 000 crédits pour 29 €, 5 000 pour 99 €, 20 000 pour 299 €, 100 000 pour 990 €. Les crédits sont valables 12 mois. Le plus ancien pack sert en premier. Chaque compte reçoit 50 crédits offerts à l'inscription.

Une fiche débloquée le reste pour toujours. La relire ne coûte rien, sur tous les endpoints boutique.

Gratuit : /v1/stores/count, /v1/me, /v1/sample, /v1/enrichment/providers et /v1/enrichments/:jobId. Une erreur qui ne renvoie aucune boutique (400, 404) ne coûte rien.

Solde trop bas : l'API répond 402 insufficient_credits, avec balance (votre solde) et needed (les crédits demandés). Elle n'envoie rien, pas même une page partielle. Pour une recherche, baissez limit sous votre solde, ou achetez un pack.

Enrichissement avec vos clés : gratuit. Enrichissement géré (managed: true, notre compte FullEnrich) : 6 crédits par email pro trouvé, 60 par mobile trouvé, 0 si rien n'est trouvé.

429 veut seulement dire rate_limited : trop d'appels en peu de temps. Attendez le délai de l'en-tête Retry-After.

EndpointCrédits
/v1/sample0
/v1/me0
/v1/stores/count0
/v1/stores/search1 par boutique renvoyée
/v1/stores/export.csv1 par boutique renvoyée
/v1/stores/:domain1
/v1/stores/:domain/catalog1
/v1/stores/:domain/trend1
/v1/enrichment/providers0
POST /v1/enrichments1 par boutique avec dirigeants, plus l'enrichissement géré
/v1/enrichments/:jobId0
/v1/stores/:domain/enrichment1

En-têtes de réponse

Erreurs

Une erreur renvoie un code HTTP et un JSON avec un champ error.

HTTPCodeSignification
400invalid_parameterUn paramètre est invalide, par exemple limit hors de 1 à 100.
401missing_api_keyAucune clé envoyée.
401invalid_api_keyClé inconnue ou révoquée.
402insufficient_creditsSolde trop bas. balance donne votre solde, needed les crédits demandés. Rien n'est envoyé.
404not_foundDomaine inconnu.
404no_catalogPas de catalogue pour cette boutique.
404no_trendPas de tendance pour cette boutique.
429rate_limitedTrop d'appels en peu de temps. Attendez le délai de l'en-tête Retry-After.
400too_many_storesPlus de 25 boutiques dans un enrichissement.
402provider_out_of_creditsVotre compte chez le fournisseur n'a plus de crédits.
404provider_not_availableCe fournisseur n'est pas ouvert à l'enrichissement.
409provider_key_missingAucune clé enregistrée pour ce fournisseur.
422provider_key_invalidLe fournisseur a refusé votre clé. Remplacez-la dans votre compte.
422provider_plan_has_no_apiVotre offre chez le fournisseur ne donne pas accès à l'API.
429byok_open_jobs3 enrichissements tournent déjà. Attendez qu'un se termine.
429byok_daily_cap500 personnes envoyées aujourd'hui à ce fournisseur. Réessayez demain.
429provider_rate_limitedLe fournisseur demande de ralentir. Le job reprend tout seul.
502provider_unavailableLe fournisseur ne répond pas. Le job réessaie tout seul.
503opt_out_unavailablePause de quelques minutes : la vérification des oppositions ne répond pas. Rien n'est envoyé.

Exemple de réponse quand le solde ne suffit pas :

HTTP/1.1 402 Payment Required
X-Credits-Balance: 12

{
  "error": "insufficient_credits",
  "balance": 12,
  "needed": 50,
  "message": "This request needs 50 credits and your balance is 12. Pass a smaller `limit` (at most your balance of new stores) or buy credits. Buy a credit pack in your account.",
  "buyUrl": "https://ecommerce-leads-database.com/account#credits"
}

Serveur MCP

Branchez votre agent IA (Claude, Cursor…) sur la base. Même clé, mêmes crédits. Le serveur propose 8 outils :

Claude Code

claude mcp add eldb --transport http https://mcp.ecommerce-leads-database.com/mcp \
  --header "X-API-Key: eldb_live_…"

Cursor et clients compatibles (JSON)

Pour un client qui accepte un serveur HTTP distant avec en-têtes, comme Cursor (fichier mcp.json) :

{
  "mcpServers": {
    "eldb": {
      "url": "https://mcp.ecommerce-leads-database.com/mcp",
      "headers": {
        "Authorization": "Bearer eldb_live_…"
      }
    }
  }
}

Claude Desktop : passez par le pont mcp-remote, dans claude_desktop_config.json :

{
  "mcpServers": {
    "eldb": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote", "https://mcp.ecommerce-leads-database.com/mcp",
        "--header", "Authorization: Bearer eldb_live_…"
      ]
    }
  }
}

La clé passe toujours dans un en-tête. Ne la mettez jamais dans l'URL.

Exemples de code

Lister toutes les boutiques Shopify qui ont une fiche Google, page par page.

JavaScript (fetch)

const API = "https://api.ecommerce-leads-database.com";
const headers = { "X-API-Key": process.env.ELDB_API_KEY };

let cursor = null;
do {
  const url = new URL("/v1/stores/search", API);
  url.searchParams.set("platform", "shopify");
  url.searchParams.set("hasGmb", "true");
  url.searchParams.set("limit", "50");
  if (cursor) url.searchParams.set("cursor", cursor);

  const res = await fetch(url, { headers });
  if (res.status === 402) {
    console.log(await res.json()); // solde trop bas : voir balance et needed
    break;
  }
  if (!res.ok) throw new Error(`HTTP ${res.status}`);

  const { items, nextCursor } = await res.json();
  for (const store of items) console.log(store.domain);
  console.log("Solde de crédits :", res.headers.get("X-Credits-Balance"));
  cursor = nextCursor;
} while (cursor);

Python (requests)

import os
import requests

API = "https://api.ecommerce-leads-database.com"
headers = {"X-API-Key": os.environ["ELDB_API_KEY"]}
params = {"platform": "shopify", "hasGmb": "true", "limit": 50}

while True:
    r = requests.get(f"{API}/v1/stores/search", headers=headers, params=params)
    if r.status_code == 402:
        print(r.json())  # solde trop bas : voir balance et needed
        break
    r.raise_for_status()
    data = r.json()
    for store in data["items"]:
        print(store["domain"])
    print("Solde de crédits :", r.headers.get("X-Credits-Balance"))
    if not data["nextCursor"]:
        break
    params["cursor"] = data["nextCursor"]