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.
/v1/sampleMuestra 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"
/v1/meSu 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": "…"
}/v1/stores/countContar 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.
/v1/stores/searchBuscar 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…"
}/v1/stores/:domainFicha 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.
| Campo | Contenido |
|---|---|
domain | Nombre de dominio de la tienda. |
platform | Plataforma de e-commerce detectada (shopify, woocommerce…). |
tld | Extensión del dominio. |
country | País (código ISO). |
theme | Tema detectado. |
productCount | Número de productos detectados. |
verificationStatus | Resultado del último control del sitio. |
lastSuccessAt | Fecha del último control correcto. |
firstSeenAt | Fecha en que la tienda entró en la base. |
detectedApps | Aplicaciones y herramientas detectadas en el sitio. |
traffic | Estimación del tráfico mensual y de las palabras clave orgánicas. |
audience | Audiencia 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. |
dns | DNS: { 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. |
trackingIds | trackingIds: 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. |
platformVersion | Versión de la plataforma (PrestaShop, Magento, Odoo) cuando el sitio la muestra. |
operator | Paí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. |
isActiveShop | false 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. |
legal | Página de aviso legal: pageUrl, companyIds (SIREN, IVA, número de empresa BE, UID CH, comprobados por su dígito de control), legalForm. |
shopify | Tiendas Shopify: shopId, isPlus, shipsToCountries, shopPayInstallments, collectionsCount, themeStoreId. |
catalogStats | Cifras 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. |
metadata | merchantName; 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. |
emails | Todos 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. |
decisionMakers | Directivos: [{ 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. |
company | Ficha 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. |
gmb | Ficha 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": "…"
}
}
}/v1/stores/:domain/catalogPro y ScaleCatá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": "…"
}
]
}/v1/stores/:domain/trendPro y ScaleTendencia 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.
/v1/enrichment/providersSus 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 }
]
}/v1/enrichmentsLanzar 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": [ … ] }
]
}/v1/enrichments/:jobIdSeguir 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_…"
/v1/stores/:domain/enrichmentResultados 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.
- Starter (49 € sin IVA): 5.000 peticiones y 2.500 tiendas al mes. 1 base de plataforma a elegir.
- Pro (149 € sin IVA): 25.000 peticiones y 10.000 tiendas al mes. 3 bases a elegir. Catálogo y tendencias.
- Scale (449 € sin IVA): 150.000 peticiones y 40.000 tiendas al mes. Todas las bases. Catálogo y tendencias.
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.
| Endpoint | Peticiones | Tiendas |
|---|---|---|
/v1/sample | 0 | 0 |
/v1/me | 0 | 0 |
/v1/stores/count | 1 | 0 |
/v1/stores/search | 1 | 1 por tienda devuelta |
/v1/stores/:domain | 1 | 1 |
/v1/stores/:domain/catalog | 10 | 0 |
/v1/stores/:domain/trend | 2 | 0 |
/v1/enrichment/providers | 0 | 0 |
POST /v1/enrichments | 1 | 1 por tienda con directivos |
/v1/enrichments/:jobId | 0 | 0 |
/v1/stores/:domain/enrichment | 1 | 1 |
Cabeceras de respuesta
X-RateLimit-Limit: peticiones incluidas este mes.X-RateLimit-Remaining: peticiones restantes.X-RateLimit-Reset: fecha del reinicio, en la renovación de la suscripción.X-Stores-Limit: tiendas incluidas este mes.X-Stores-Remaining: tiendas restantes.
Errores
Un error devuelve un código HTTP y un JSON con un campo error.
| HTTP | Código | Significado |
|---|---|---|
| 400 | invalid_parameter | Un parámetro no es válido, por ejemplo limit fuera del rango de 1 a 100. |
| 401 | missing_api_key | No se ha enviado ninguna clave. |
| 401 | invalid_api_key | Clave desconocida o revocada. |
| 402 | active_subscription_required | Esta cuenta no tiene ninguna suscripción activa. |
| 402 | plan_upgrade_required | Endpoint no incluido en su plan (reason: exports_not_in_plan). El catálogo y las tendencias requieren Pro o Scale. |
| 403 | plan_restriction | Plataforma fuera de sus bases (reason: platform_locked). El campo allowed indica sus bases. |
| 404 | not_found | Dominio desconocido. |
| 404 | no_catalog | No hay catálogo para esta tienda. |
| 404 | no_trend | No hay tendencia para esta tienda. |
| 409 | no_database_selected | Primero elija sus bases en su cuenta. |
| 429 | quota_exceeded | Cuota de peticiones agotada hasta resetAt. |
| 429 | store_quota_exceeded | Presupuesto de tiendas agotado hasta resetAt. |
| 429 | rate_limited | Demasiadas llamadas en poco tiempo. Espere el plazo indicado en la cabecera Retry-After. |
| 429 | platform_change_limited | El cambio de base está limitado a 1 cada 30 días. |
| 400 | too_many_stores | Más de 25 tiendas en un enriquecimiento. |
| 402 | provider_out_of_credits | Su cuenta en el proveedor no tiene créditos. |
| 404 | provider_not_available | Este proveedor no está abierto al enriquecimiento. |
| 409 | provider_key_missing | No hay clave guardada para este proveedor. |
| 422 | provider_key_invalid | El proveedor ha rechazado su clave. Sustitúyala en su cuenta. |
| 422 | provider_plan_has_no_api | Su plan en el proveedor no da acceso a la API. |
| 429 | byok_open_jobs | Ya hay 3 enriquecimientos en curso. Espere a que uno termine. |
| 429 | byok_daily_cap | Hoy ya se enviaron 500 personas a este proveedor. Vuelva a intentarlo mañana. |
| 429 | provider_rate_limited | El proveedor pide ir más despacio. El job sigue solo. |
| 502 | provider_unavailable | El proveedor no responde. El job lo reintenta solo. |
| 503 | opt_out_unavailable | Una 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:
search_stores: buscar tiendas con filtros.count_stores: contar tiendas.get_store: leer la ficha de una tienda.get_store_catalog: leer el catálogo (Pro y Scale).get_store_trend: leer la tendencia de tráfico (Pro y Scale).enrich_store: enriquecer a los directivos de una o varias tiendas con su clave de proveedor.get_enrichment: seguir un enriquecimiento, leer los resultados de una tienda o listar sus proveedores.get_quota: ver su plan y su cuota restante.
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"]