Las ventas aún no están abiertas. Los precios son orientativos. Solicitar un acceso piloto

Documentación de la API

Una API REST sencilla. Usted envía una petición y recibe JSON.

Autenticación

Cada llamada requiere su clave de API, salvo /v1/sample. Envíela en la cabecera X-API-Key o en la cabecera Authorization: Bearer. Encontrará su clave en la página Cuenta.

Las claves empiezan por eldb_live_. Mantenga la suya en secreto: nunca la incluya en el código de una página web.

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

# O, si lo prefiere:
curl https://api.ecommerce-leads-database.com/v1/me \
  -H "Authorization: Bearer eldb_live_…"

Endpoints

Todas las URL parten de https://api.ecommerce-leads-database.com.

GET/v1/sample

Muestra gratuita (sin clave)

Devuelve algunas tiendas: 10 por defecto, 20 como máximo. Sirve para ver el formato de los datos antes de suscribirse. No cuenta en la cuota.

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

Su plan y su cuota

Devuelve su plan, las peticiones y tiendas consumidas, sus bases y la fecha de reinicio. Gratis: no consume ninguna petición ni ninguna tienda.

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

{
  "plan": "api_pro",
  "planLabel": "Pro",
  "requests": { "limit": 25000, "used": … },
  "stores": { "limit": 10000, "used": … },
  "databases": { "slots": 3, "selected": ["shopify", "woocommerce", "prestashop"] },
  "exports": true,
  "resetAt": "…"
}
GET/v1/stores/count

Contar tiendas

Devuelve el número de tiendas que cumplen los filtros y cuántas tienen perfil de Google. Cuesta 1 petición y 0 tiendas.

Parámetros: platform, tld, country, hasGmb, hasEmail, hasPhone, app, currency, lang, operatorCountry, activeOnly, genericEmailsOnly, includeUnverified, includeAliases, maxChromeRank, mailProvider, dmarcPolicy, trackingId, hasDecisionMaker, hasDecisionMakerEmail

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

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

Cifras reales de las tiendas Shopify verificadas.

GET/v1/stores/search

Buscar tiendas

Filtra la base y devuelve una página de resultados (items) con un cursor (nextCursor).

Parámetros: platform, tld, country, minProducts, hasGmb, hasEmail, hasPhone, app, currency, lang, operatorCountry, activeOnly, genericEmailsOnly, includeUnverified, includeAliases, maxChromeRank, mailProvider, dmarcPolicy, trackingId, hasDecisionMaker, hasDecisionMakerEmail, cursor, limit

  • limit: de 1 a 100 resultados por página. 50 por defecto.
  • Orden: de mayor a menor tráfico. Las tiendas sin tráfico conocido aparecen al final.
  • Por defecto, search y count solo devuelven tiendas verificadas: una tienda online real, comprobada de nuevo en su propio sitio. Añada includeUnverified=true para incluir también los sitios corporativos y los sitios inaccesibles.
  • activeOnly es true por defecto: se excluyen las tiendas evaluadas como inactivas. Añada activeOnly=false para incluirlas.
  • Filtros: hasEmail (email recogido en los últimos 12 meses), hasPhone, app (una app detectada, p. ej. Klaviyo), currency (EUR), lang (fr), operatorCountry (FR), genericEmailsOnly (con hasEmail: solo buzones genéricos). Un valor inválido devuelve 400 invalid_parameter y la petición no se cobra.
  • maxChromeRank (tramo máximo del ranking del Chrome UX Report: 1000, 5000, 10000, 50000, 100000, 500000, 1000000, 5000000, 10000000 o 50000000). Cualquier otro valor devuelve 400 invalid_parameter. El campo audience contiene datos del Chrome UX Report (Google), con licencia CC BY-SA 4.0.
  • mailProvider (proveedor de correo deducido del MX: google-workspace, microsoft-365, ovh, infomaniak, ionos, gandi, zoho, proton, o2switch, hostinger, other, none) y dmarcPolicy (none, quarantine, reject o missing). Cualquier otro valor devuelve 400 invalid_parameter. El filtro app también encuentra las herramientas leídas en el DNS (por ejemplo Klaviyo a través de SPF). Slugs de apps que el DNS puede añadir: 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.
  • Códigos de seguimiento públicos: use trackingId para encontrar las otras tiendas que comparten un mismo código. Pase un valor suelto como GTM-ABC123, AW-123456789, G-ABCDEF1234, UA-1234567-1 o ca-pub-1234567890123456. Los códigos numéricos necesitan su tipo delante: meta:123456789012345, tiktok:…, pinterest:…, microsoftAds:…, linkedin:…, hotjar:…, criteo:…, snapchat:…, clarity:…, klaviyo:… (Klaviyo distingue mayúsculas y minúsculas). Cualquier otro valor devuelve 400 invalid_parameter. Cada resultado incluye también trackingIds (null hasta que se lee la tienda).
  • hasDecisionMaker=true|false (al menos un directivo conocido, o ninguno) y hasDecisionMakerEmail=true (al menos un directivo cuyo email se encontró en el sitio o fue aceptado por el servidor de correo). Cualquier otro valor devuelve 400 invalid_parameter. Cada resultado incluye también hasDecisionMaker.
  • Página siguiente: envíe el valor de nextCursor en el parámetro cursor. En la última página, nextCursor vale null.
  • Cada tienda devuelta cuenta en su presupuesto de tiendas. Una página de 50 resultados consume 50 tiendas.
  • Cada resultado es un resumen de tienda: dominio, plataforma, país, tema, número de productos, apps, tráfico, nombre del comerciante, nota y categoría de Google, hasEmail, hasPhone, hasDecisionMaker, currency, lang, operatorCountry, isActiveShop. Cada resultado incluye también audience (null si la tienda no está en el ranking del Chrome UX Report). Cada resultado incluye también dns (null hasta que se lea la tienda). Para la ficha completa, llame a /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/:domain

Ficha de una tienda

Devuelve la ficha completa de una tienda. Cuesta 1 petición y 1 tienda. El catálogo no se incluye: use /catalog. Cada email se devuelve con su tipo; añada genericEmailsOnly=true para recibir solo buzones genéricos. genericEmailsOnly=true oculta también los emails de los directivos.

CampoContenido
domainNombre de dominio de la tienda.
platformPlataforma de e-commerce detectada (shopify, woocommerce…).
tldExtensión del dominio.
countryPaís (código ISO).
themeTema detectado.
productCountNúmero de productos detectados.
verificationStatusResultado del último control del sitio.
lastSuccessAtFecha del último control correcto.
firstSeenAtFecha en que la tienda entró en la base.
detectedAppsAplicaciones y herramientas detectadas en el sitio.
trafficEstimación del tráfico mensual y de las palabras clave orgánicas.
audienceAudiencia en Chrome: { chromeRank, class, country, month, source }. chromeRank es el tramo del ranking del Chrome UX Report (Google) para ese país: 1000, 5000, 10000, hasta 50000000. null si la tienda no está en el ranking. Este campo se comparte con licencia CC BY-SA 4.0: cite la fuente y mantenga la misma licencia. Valores de class: top_1k, top_5k, top_10k, top_50k, top_100k, top_500k, top_1m, top_5m, top_10m, top_50m. Fuente del Chrome UX Report: https://developer.chrome.com/docs/crux. Licencia: https://creativecommons.org/licenses/by-sa/4.0/. Datos adaptados: rangos asociados a las tiendas y agrupados por país por nosotros.
dnsDNS: { mailProvider, dmarcPolicy, apps, checkedAt }. mailProvider es el proveedor de correo deducido del MX (google-workspace, microsoft-365, ovh, infomaniak, ionos, gandi, zoho, proton, o2switch, hostinger, other, none). dmarcPolicy vale none, quarantine, reject o missing (sin registro). apps lista las herramientas de envío de emails y de verificación de dominio leídas en los registros SPF y TXT. checkedAt es la fecha de la lectura. null mientras la tienda no se haya leído. No se expone ningún token de verificación.
trackingIdstrackingIds: códigos de seguimiento y de publicidad públicos agrupados por tipo, por ejemplo { "gtm": ["GTM-ABC123"], "googleAds": ["AW-123456789"], "meta": ["123456789012345"] }. Tipos: ga4, ua, gtm, googleAds, floodlight, adsense, meta, tiktok, pinterest, microsoftAds, linkedin, snapchat, criteo, clarity, hotjar, klaviyo. {} si no se encontró nada, null hasta que se lee la tienda. Solo los códigos que cualquier visitante ve en el código fuente de la página.
platformVersionVersión de la plataforma (PrestaShop, Magento, Odoo) cuando el sitio la muestra.
operatorPaís de la empresa detrás de la tienda ({ country, source }): según su número de IVA, los ajustes de Shopify, la dirección del aviso legal, el teléfono o la extensión, en ese orden. Puede diferir de la extensión.
isActiveShopfalse cuando la tienda parece inactiva (catálogo vacío, productos de demostración, moneda por defecto), con los motivos en activeShopReasons. null mientras no se evalúa.
legalPágina de aviso legal: pageUrl, companyIds (SIREN, IVA, número de empresa BE, UID CH, comprobados por su dígito de control), legalForm.
shopifyTiendas Shopify: shopId, isPlus, shipsToCountries, shopPayInstallments, collectionsCount, themeStoreId.
catalogStatsCifras del catálogo cuando la plataforma las expone: precio y peso medios, variantes, imágenes, marcas, tipos de producto, categorías, fecha del producto más reciente.
metadatamerchantName; contactEmail con contactEmailType (generic, personal o unknown) y emailDomainMatch; telephone (E.164) con phoneType (mobile, fixed_line…); address; socialLinks; sources (página y fecha de recogida de cada contacto); title, metaDescription, lang, currency, hreflangs, features, paymentMethods, shippingCarriers, salesChannels, copyrightYear, contactPageUrl, canonicalUrl. Un contacto recogido hace más de 12 meses, o un email cuyo titular se opuso, es null con el motivo en contactEmailWithheld, telephoneWithheld o addressWithheld.
emailsTodos los emails que publica la tienda: [{ email, type, sourceUrl }]. type es generic, personal o unknown; sourceUrl es la página donde se leyó el email. 10 como máximo, el mejor primero. Un email leído hace más de 12 meses, o retirado por su titular, no se devuelve. Con genericEmailsOnly=true, solo quedan los emails generic.
decisionMakersDirectivos: [{ firstName, lastName, role, source, sourceUrl, since, email, emailStatus }], el directivo principal primero. role: owner (propietario, empresario individual), president (presidente), managing_director (director general), manager (gerente), publication_director (responsable de la publicación), partner (socio), administrator (consejero), other. source: rne (registro nacional de empresas, Francia), zefix (registro mercantil, Suiza) o legal_page (aviso legal de la tienda). sourceUrl: la ficha pública de la empresa en el registro, o la página de aviso legal. since: fecha de inicio en el cargo cuando el registro la da, si no null. emailStatus: found_on_site (dirección publicada en el sitio), valid (aceptada por el servidor de correo del dominio), catch_all (el servidor acepta todas las direcciones: formato más probable, no confirmado), pattern (deducida del formato de dirección del dominio, no comprobada), not_found (ninguna dirección aceptada por el servidor), null (ninguna dirección conocida). email vale null si su titular la retiró, si tiene más de 12 meses, o con genericEmailsOnly=true. Un directivo leído hace más de 12 meses ya no se devuelve. Nunca fecha de nacimiento, nacionalidad ni dirección personal.
companyFicha del registro de empresas: { registry, registryId, officialName, activityCode, headcountBand, createdOn, category, legalFormCode, active, hq, checkedAt }. registry es fr, be o ch; registryId es el SIREN, el número de empresa belga o el UID suizo. officialName: denominación oficial. activityCode: código de actividad (NAF o NACE). headcountBand: tramo de plantilla, por ejemplo "10-19". createdOn: fecha de creación. category: categoría de empresa (Francia). legalFormCode: código de forma jurídica del registro. active: false si la empresa está cerrada. hq: código postal y municipio de la sede. checkedAt: fecha de la última lectura del registro. Un campo que el registro no da vale null. company vale null si la tienda no tiene número de empresa, si el registro no la conoce, o si la lectura tiene más de 12 meses.
gmbFicha de Google: placeId, category, additionalCategories, rating, ratingDistribution, isClaimed, totalPhotos, workTime, address, addressInfo, latitude, longitude, phone, website. null si no existe.
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,
    "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"
    },
    "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/catalogPro y Scale

Catálogo de productos

Devuelve los productos de la tienda, 5.000 como máximo. Disponible para una parte de las tiendas Shopify y WooCommerce. Si no, error 404 no_catalog, sin coste. Cuesta 10 peticiones.

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/trendPro y Scale

Tendencia de tráfico

Devuelve el historial mensual del tráfico orgánico y de las posiciones. Error 404 no_trend si no hay datos, sin coste. Cuesta 2 peticiones.

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"
}

Enriquecer con sus claves

Encuentre el email y el teléfono de los directivos de una tienda con su propia cuenta de Apollo, FullEnrich, Kaspr o Dropcontact. La llamada usa sus créditos en el proveedor. Los resultados son suyos: ningún otro cliente los ve.

Guarde sus claves de proveedor en su cuenta, en la página Mis claves de proveedores. Nunca pasan por la API: una clave de ELDB robada no permite ni leerlas ni cambiarlas.

Por petición: 25 tiendas y 3 directivos por tienda. Por cliente: 3 enriquecimientos en curso, y 500 personas por proveedor y por día (UTC). Un resultado se sirve durante 12 meses y se borra a los 13 meses.

GET/v1/enrichment/providers

Sus proveedores

Lista los proveedores con una clave guardada, con su estado y los créditos restantes cuando el proveedor los da. Gratis.

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

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

Lanzar un enriquecimiento

Envíe provider y domain (una tienda) o domains (25 como máximo). maxPeoplePerStore: de 1 a 3, 2 por defecto. phones: true para pedir también los teléfonos (más créditos). force: true para volver a enriquecer a una persona enriquecida hace menos de 30 días. Cuesta 1 petición y 1 tienda por cada tienda con directivos. Responde 200 con los resultados cuando el proveedor responde enseguida, si no 202: siga el 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

Seguir un enriquecimiento

Devuelve el estado del job (queued, submitted, done, partial, failed, canceled) y los resultados por tienda. Gratis. Espere al menos 20 segundos entre dos llamadas.

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

Resultados de una tienda

Devuelve la plataforma, el nombre del comercio, los directivos, sus proveedores y sus resultados. Cuesta 1 petición y 1 tienda. DELETE en la misma URL borra sus resultados de esta tienda.

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
    }
  ]
}

Cada resultado contiene firstName, lastName, role, provider, status (pending, found, not_found, skipped, error), skipReason, email, emailStatus (valid, risky, catch_all, invalid, unknown), emailStatusRaw (la etiqueta del proveedor), emailKind (professional, generic, personal), phone, phoneType, linkedinUrl, jobTitle, creditsUsed, errorCode, enrichedAt y reused (true: un resultado ya obtenido, sin créditos nuevos).

GET /v1/stores/:domain también devuelve enrichment: sus propios resultados de esta tienda, junto a decisionMakers. Array vacío si no tiene.

Cuotas y costes

Cada plan tiene dos contadores: las peticiones y las tiendas. Se reinician en cada renovación de su suscripción.

Le enviamos un email cuando ha usado el 80 % de un contador.

El presupuesto de tiendas cuenta cada tienda devuelta por /v1/stores/search, y 1 tienda por cada llamada a /v1/stores/:domain. /v1/stores/count y /v1/me no consumen tiendas.

Los errores 404, 403 y 409 no se facturan.

EndpointPeticionesTiendas
/v1/sample00
/v1/me00
/v1/stores/count10
/v1/stores/search11 por tienda devuelta
/v1/stores/:domain11
/v1/stores/:domain/catalog100
/v1/stores/:domain/trend20
/v1/enrichment/providers00
POST /v1/enrichments11 por tienda con directivos
/v1/enrichments/:jobId00
/v1/stores/:domain/enrichment11

Cabeceras de respuesta

Errores

Un error devuelve un código HTTP y un JSON con un campo error.

HTTPCódigoSignificado
400invalid_parameterUn parámetro no es válido, por ejemplo limit fuera del rango de 1 a 100.
401missing_api_keyNo se ha enviado ninguna clave.
401invalid_api_keyClave desconocida o revocada.
402active_subscription_requiredEsta cuenta no tiene ninguna suscripción activa.
402plan_upgrade_requiredEndpoint no incluido en su plan (reason: exports_not_in_plan). El catálogo y las tendencias requieren Pro o Scale.
403plan_restrictionPlataforma fuera de sus bases (reason: platform_locked). El campo allowed indica sus bases.
404not_foundDominio desconocido.
404no_catalogNo hay catálogo para esta tienda.
404no_trendNo hay tendencia para esta tienda.
409no_database_selectedPrimero elija sus bases en su cuenta.
429quota_exceededCuota de peticiones agotada hasta resetAt.
429store_quota_exceededPresupuesto de tiendas agotado hasta resetAt.
429rate_limitedDemasiadas llamadas en poco tiempo. Espere el plazo indicado en la cabecera Retry-After.
429platform_change_limitedEl cambio de base está limitado a 1 cada 30 días.
400too_many_storesMás de 25 tiendas en un enriquecimiento.
402provider_out_of_creditsSu cuenta en el proveedor no tiene créditos.
404provider_not_availableEste proveedor no está abierto al enriquecimiento.
409provider_key_missingNo hay clave guardada para este proveedor.
422provider_key_invalidEl proveedor ha rechazado su clave. Sustitúyala en su cuenta.
422provider_plan_has_no_apiSu plan en el proveedor no da acceso a la API.
429byok_open_jobsYa hay 3 enriquecimientos en curso. Espere a que uno termine.
429byok_daily_capHoy ya se enviaron 500 personas a este proveedor. Vuelva a intentarlo mañana.
429provider_rate_limitedEl proveedor pide ir más despacio. El job sigue solo.
502provider_unavailableEl proveedor no responde. El job lo reintenta solo.
503opt_out_unavailableUna pausa de unos minutos: la comprobación de oposiciones no responde. No se envía nada.

Ejemplo de respuesta cuando el presupuesto de tiendas está agotado:

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 25000
X-RateLimit-Remaining: 0
X-Stores-Limit: 10000
X-Stores-Remaining: 0

{
  "error": "store_quota_exceeded",
  "plan": "api_pro",
  "quotaMonthly": 25000,
  "quotaUsed": …,
  "storesMonthly": 10000,
  "storesUsed": 10000,
  "resetAt": "…"
}

Servidor MCP

Conecte su agente de IA (Claude, Cursor…) a la base. Misma clave, mismas cuotas. El servidor ofrece 8 herramientas:

Claude Code

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

Cursor y clientes compatibles (JSON)

Para un cliente que acepta un servidor HTTP remoto con cabeceras, como Cursor (archivo mcp.json):

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

Claude Desktop: use el puente mcp-remote, en 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 clave siempre va en una cabecera. Nunca la incluya en la URL.

Ejemplos de código

Listar todas las tiendas Shopify que tienen perfil de Google, página por página.

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 === 429) {
    console.log(await res.json()); // cuota o presupuesto agotado: ver resetAt
    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("Tiendas restantes:", res.headers.get("X-Stores-Remaining"));
  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 == 429:
        print(r.json())  # cuota o presupuesto agotado: ver resetAt
        break
    r.raise_for_status()
    data = r.json()
    for store in data["items"]:
        print(store["domain"])
    print("Tiendas restantes:", r.headers.get("X-Stores-Remaining"))
    if not data["nextCursor"]:
        break
    params["cursor"] = data["nextCursor"]