# DataFirefly Indexing API — Documentación

> Resumen DataFirefly Indexing API envía automáticamente los productos, categorías y páginas CMS de tu tienda PrestaShop a los dos canales de envío directo existentes: IndexNow mediante el relé api.indexnow.org, que…

- Página: <https://www.datafirefly.com/es/documentation/datafirefly-indexing-api-prestashop/>
- Idioma: es
- Actualizado el: 2026-07-28
- Otros idiomas: [fr](https://www.datafirefly.com/documentation/datafirefly-indexing-api-prestashop/index.md), [en](https://www.datafirefly.com/en/documentation/datafirefly-indexing-api-prestashop/index.md), [de](https://www.datafirefly.com/de/documentation/datafirefly-indexing-api-prestashop/index.md), [it](https://www.datafirefly.com/it/documentation/datafirefly-indexing-api-prestashop/index.md), [pl](https://www.datafirefly.com/pl/documentation/datafirefly-indexing-api-prestashop/index.md), [nl](https://www.datafirefly.com/nl/documentation/datafirefly-indexing-api-prestashop/index.md), [pt](https://www.datafirefly.com/pt/documentation/datafirefly-indexing-api-prestashop/index.md)
- Índice: <https://www.datafirefly.com/es/documentation/llms.txt>

## Resumen

DataFirefly Indexing API envía automáticamente los productos, categorías y páginas CMS de tu tienda PrestaShop a los dos canales de envío directo existentes: **IndexNow** mediante el relé `api.indexnow.org`, que propaga a Bing, Yandex, Naver y Seznam en una sola llamada, y **Google Indexing API** (autenticación Service Account OAuth2, firma JWT RS256 nativa). El módulo se engancha a los hooks nativos de PrestaShop, encola cada cambio en una cola con deduplicación, y un CRON procesa el lote cada pocos minutos. Mantienes un registro completo de los envíos y un dashboard de la tasa de aceptación.

**Léelo antes de configurar Google:** Google restringe oficialmente su Indexing API a las páginas que contienen datos estructurados `JobPosting`, o `BroadcastEvent` integrado en un `VideoObject`. Una ficha de producto o una página de categoría no encaja en ninguno de los dos casos. La API acepta igualmente el envío y responde 200, pero ese código solo significa que la notificación se ha recibido, no que la URL vaya a ser rastreada ni indexada. Para un catálogo de e-commerce, **IndexNow es el canal que produce un efecto medible**: configúralo primero y trata Google como un canal secundario registrado.

**En resumen:** tus nuevos productos y modificaciones de fichas se envían a Bing, Yandex, Naver y Seznam en los minutos siguientes, sin suscripción a terceros ni comisión por URL. Del lado de Google, el envío acelera el descubrimiento sin garantía de indexación.

## Requisitos

- PrestaShop 8.0 a 8.99, o PrestaShop 9.x
- PHP 7.4 a 8.3
- Extensiones PHP `openssl` (para la firma JWT RS256 de Google) y `curl` (para las peticiones HTTP)
- Un CRON del sistema o un servicio externo de CRON para llamar al procesamiento de la cola cada 5 a 15 minutos
- **Opcional, para Google:** una cuenta Google Cloud con un proyecto donde activar la Indexing API y crear un Service Account, y una propiedad Search Console verificada para tu dominio

## Instalación

### Paso 1: descarga

Descarga el ZIP `dfindexingapi-1.0.0.zip` desde tu cuenta DataFirefly tras la compra.

### Paso 2: instalación desde el back-office

1. Conéctate a tu back-office PrestaShop
2. Ve a **Módulos › Gestor de módulos › Subir un módulo**
3. Haz clic en **Seleccionar archivo** y elige el ZIP descargado
4. Valida. PrestaShop descomprime e instala el módulo
5. Una vez instalado, haz clic en **Configurar**

### Paso 3: verificaciones post-instalación

En la instalación, el módulo crea automáticamente:

- Las dos tablas SQL `ps_df_indexapi_queue` (cola) y `ps_df_indexapi_log` (registro)
- Una clave IndexNow alfanumérica de 32 caracteres
- Un token CRON aleatorio de 32 caracteres
- 5 pestañas en el menú admin: padre **DataFirefly Indexing API**, luego **Dashboard**, **Cola**, **Registro**, **Configuración**

Abre la pestaña **Configuración** para pasar al siguiente paso.

## Configuración de IndexNow

IndexNow es el canal a configurar primero: sin Service Account, sin OAuth, sin cuota y sin restricción sobre el tipo de página. Solo una clave a publicar en la raíz de tu dominio.

### Entender IndexNow

IndexNow es un protocolo abierto impulsado por Microsoft Bing y Yandex en 2021, al que se unieron Naver y Seznam. Generas una clave alfanumérica, la publicas en la raíz de tu dominio como un archivo accesible públicamente, y llamas a `api.indexnow.org` con una lista de URLs. El servidor verifica la clave leyendo el archivo en tu dominio, luego propaga las URLs a los motores participantes. Fichas de producto, categorías y páginas CMS están dentro de su ámbito normal.

### Método 1: reescritura .htaccess (recomendado)

Es el método más simple: el módulo sirve él mismo el contenido del archivo clave mediante un controlador frontend, y una regla `.htaccess` en la raíz de tu tienda redirige la petición a ese controlador.

1. En la configuración del módulo, abre la pestaña **IndexNow**
2. Marca **Activar IndexNow**
3. Verifica el campo **Host**, que debe corresponder al dominio de tu tienda sin el protocolo (por ejemplo `mi-tienda.es`)
4. Guarda
5. Copia el snippet `.htaccess` mostrado en la página de configuración, generado dinámicamente con tu clave actual
6. Pega este snippet en la parte superior del archivo `.htaccess` en la raíz de PrestaShop, justo después del bloque `RewriteEngine on`
7. Haz clic en **Probar IndexNow** en la configuración: el módulo llama a la URL del archivo clave en tu dominio y verifica que devuelve el contenido esperado como `text/plain`

### Método 2: archivo físico

Si no puedes modificar el `.htaccess`, crea manualmente un archivo físico en la raíz del dominio.

1. Recupera tu clave IndexNow desde la configuración del módulo (campo **Clave IndexNow**)
2. Crea un archivo cuyo nombre sea exactamente **la clave + .txt** (por ejemplo `a1b2c3d4e5f6.txt`) en la raíz de tu dominio
3. El contenido del archivo debe ser únicamente la clave en sí, sin salto de línea
4. Verifica que `https://tu-dominio.com/a1b2c3d4e5f6.txt` devuelve la clave como `text/plain`
5. Haz clic en **Probar IndexNow**

Puedes regenerar la clave IndexNow en cualquier momento desde la configuración (botón **Regenerar clave**). Recuerda actualizar el snippet `.htaccess` o el archivo físico en consecuencia.

## Configuración de Google Indexing API

**Alcance oficial:** Google reserva esta API a las páginas `JobPosting` o `BroadcastEvent` dentro de un `VideoObject`. En un catálogo de productos sigue siendo utilizable técnicamente (la API responde 200 y el módulo registra la respuesta), pero Google decide solo sobre el rastreo y la indexación. Esta sección es opcional: el módulo funciona perfectamente solo con IndexNow.

La API Google Indexing requiere un Service Account de Google Cloud. El proceso tarda unos 5 minutos.

### Paso 1: crear un proyecto Google Cloud

1. Ve a [console.cloud.google.com](https://console.cloud.google.com) e inicia sesión
2. Arriba, haz clic en el selector de proyecto, luego **Nuevo proyecto**
3. Dale un nombre (por ejemplo _Indexing API Tienda_) y créalo
4. Selecciona el proyecto recién creado

### Paso 2: activar la Indexing API

1. En el menú izquierdo, ve a **APIs y servicios › Biblioteca**
2. Busca _Indexing API_
3. Haz clic en **Activar**

### Paso 3: crear un Service Account

1. Ve a **APIs y servicios › Credenciales**
2. Haz clic en **Crear credenciales › Cuenta de servicio**
3. Dale un nombre (por ejemplo _indexing-api-prestashop_)
4. No se necesita rol IAM: pasa al siguiente paso y finaliza la creación
5. En la lista de cuentas de servicio, haz clic en la cuenta creada
6. Pestaña **Claves › Añadir clave › Crear nueva clave**
7. Formato **JSON**. Descarga y conserva el archivo, no podrá recuperarse después

**Seguridad:** el archivo JSON contiene la clave privada del Service Account. Nunca lo compartas públicamente y no lo subas a un repositorio Git.

### Paso 4: añadir el Service Account a Search Console

1. Copia el email del Service Account (forma `nombre@proyecto.iam.gserviceaccount.com`) desde Google Cloud
2. Ve a [Google Search Console](https://search.google.com/search-console)
3. Selecciona tu propiedad (el dominio de tu tienda)
4. Ve a **Configuración › Usuarios y permisos**
5. Haz clic en **Añadir usuario**, pega el email del Service Account, selecciona el rol **Propietario**
6. Valida

El rol **Propietario** es requerido por Google Indexing API. Los roles **Restringido** o **Completo** no son suficientes, la API devolverá `403 Permission denied`.

### Paso 5: pegar el JSON en el módulo

1. Abre el archivo JSON descargado en un editor de texto
2. Copia todo su contenido
3. En la configuración del módulo, sección **Google Indexing API**, marca **Activar Google Indexing API**
4. Pega el JSON completo en el campo **Service Account JSON**
5. Guarda

### Paso 6: probar la conexión

Haz clic en el botón **Probar Google** en la página de configuración. El módulo firma un JWT RS256, lo intercambia por un token OAuth2, y muestra el resultado. Si todo es correcto, ves un mensaje verde _Autenticación OK_. Esta prueba valida la autenticación, no que Google vaya a tener en cuenta tus URLs.

## Configuración del CRON

El CRON es el elemento que hace funcionar el procesamiento de la cola. Sin un CRON llamado regularmente, los envíos se acumulan pero nunca salen.

### Acción process: procesamiento de la cola

A llamar **cada 5 a 15 minutos**. El módulo procesa un lote configurable (predeterminado 50 trabajos) siguiendo la deduplicación y los filtros de indexación, luego actualiza el registro y la cola.

La URL exacta se muestra en la configuración. Tiene este aspecto:

```
https://tu-dominio.com/index.php?fc=module&module=dfindexingapi&controller=cron&dfaction=process&token=TU_TOKEN
```

### Acción purge: limpieza del registro

A llamar **una vez al día**. El módulo elimina los trabajos y registros procesados más allá de la retención configurada (predeterminado 30 días).

```
https://tu-dominio.com/index.php?fc=module&module=dfindexingapi&controller=cron&dfaction=purge&token=TU_TOKEN
```

### Acción key: archivo clave IndexNow

Solo utilizada por la reescritura `.htaccess`. Nunca llamas a esta URL manualmente.

### Configurar tu CRON del sistema

En Linux/cPanel, añade dos líneas en crontab:

```
# Cada 10 minutos: procesamiento de la cola
*/10 * * * * curl -s "https://tu-dominio.com/index.php?fc=module&module=dfindexingapi&controller=cron&dfaction=process&token=TU_TOKEN" > /dev/null

# Una vez al día a las 3h: purga del registro
0 3 * * * curl -s "https://tu-dominio.com/index.php?fc=module&module=dfindexingapi&controller=cron&dfaction=purge&token=TU_TOKEN" > /dev/null
```

### Seguridad del token CRON

El token es un secreto de 32 caracteres generado en la instalación. Sin el token correcto en el parámetro `token=`, el controlador devuelve HTTP 403. Puedes regenerar el token en cualquier momento desde la configuración (botón **Regenerar token CRON**), recordando actualizar tus líneas crontab con el nuevo token.

## El Dashboard

La pestaña **Dashboard** es tu vista general en tiempo real. Mide la salud técnica de las llamadas a la API, no la indexación efectiva de tus páginas.

### Contadores de cola

Cinco tarjetas en la parte superior de la página:

- **Pendiente**: trabajos creados pero aún no procesados
- **En curso**: trabajos bloqueados en procesamiento por un CRON activo
- **Enviado**: trabajos procesados con éxito (acumulación histórica no purgada)
- **Error**: trabajos que han fallado tras N reintentos máximos
- **Omitido**: trabajos creados pero ignorados por un filtro (por ejemplo URL_DELETED para IndexNow)

### Diagnóstico de proveedores

Dos tarjetas muestran el estado de configuración:

- **Google Indexing API**: activo, mal configurado, o desactivado. Indica si el JSON Service Account está presente y es válido
- **IndexNow**: activo, mal configurado, o desactivado. Indica si la clave y el host están configurados

### Tasa de aceptación a 30 días

Tabla cruzada proveedor × estado sobre los últimos 30 días, con coloración semántica: verde por encima del 90%, naranja entre 60 y 90%, rojo por debajo. Si Google cae por debajo del 90%, generalmente es señal de que has superado la cuota o que las URLs ya no son accesibles. Una tasa de aceptación del 100% significa que tus notificaciones se han recibido, no que las URLs se hayan indexado.

### Gráfico de envíos diarios

Gráfico Chart.js que superpone dos curvas diarias: total enviado y total aceptado. Útil para detectar rápidamente caídas o picos anómalos.

## La Cola

La pestaña **Cola** lista todos los trabajos (pending, processing, submitted, error, skipped) con filtros nativos de PrestaShop por tienda, tipo de objeto, ID, proveedor, estado, fecha.

### Estados de los trabajos

- **pending**: creado, en espera de procesamiento por el siguiente CRON
- **processing**: bloqueado por un CRON activo (transición lógica para evitar el procesamiento doble en paralelo)
- **submitted**: envío exitoso a la API. El contador de reintentos está congelado
- **error**: todos los reintentos han fallado. Permanece visible con el mensaje de error exacto devuelto por la API
- **skipped**: creado y luego ignorado (por ejemplo URL_DELETED IndexNow, o filtro desactivado)

### Acciones individuales

Cada fila ofrece:

- **Reintentar**: pone el trabajo de nuevo en pending y reinicia el contador de reintentos
- **Eliminar**: borra el trabajo de la cola

### Acciones en masa

Botones en la parte superior de la lista:

- **Reintentar todos los trabajos en error**: pone en pending todos los trabajos en estado error
- **Purgar trabajos procesados**: elimina todos los submitted/skipped sin importar su antigüedad

## El Registro

La pestaña **Registro** lista cada envío individual realizado: proveedor, tipo, ID de objeto, URL enviada, acción (URL_UPDATED o URL_DELETED), código HTTP devuelto, indicador aceptado/rechazado, mensaje completo de respuesta y fecha. Filtrable, ordenable, exportable como CSV mediante el HelperList estándar de PrestaShop.

Si Google rechaza una URL con código HTTP 400 y mensaje _Unable to fetch URL_, generalmente significa que la URL no es accesible públicamente (modo mantenimiento activo, robots.txt que bloquea, redirección en bucle, etc.). Verifica la URL en un navegador en navegación privada.

## Filtros de indexación

En la configuración, puedes activar o desactivar independientemente tres tipos de objetos:

- **Productos**: envío en creación, modificación, eliminación, desactivación
- **Categorías**: envío en creación, modificación, eliminación. La raíz de categoría (ID 1 y 2) se ignora por seguridad
- **Páginas CMS**: envío en creación, modificación, eliminación

Desactivar un filtro detiene inmediatamente el encolado para ese tipo, pero no purga la cola existente. En un catálogo grande, restringir los filtros del lado de Google es el reflejo correcto para no agotar la cuota de 200 URLs al día.

## Multi-tienda

El módulo es nativamente multi-tienda. La configuración (claves Google, clave IndexNow, host, activaciones) es independiente por sub-tienda. Los trabajos y registros están delimitados por `id_shop`: el mismo producto en dos sub-tiendas genera dos trabajos distintos con sus propias URLs canónicas.

Para configurar independientemente cada sub-tienda, usa el selector multistore en la parte superior del admin antes de abrir la configuración.

## Hooks PrestaShop escuchados

El módulo registra los siguientes hooks en la instalación:

- `actionProductSave`: creación o modificación de un producto. Si activo, encola URL_UPDATED; si no URL_DELETED
- `actionProductDelete`: eliminación definitiva de un producto. Encola URL_DELETED
- `actionObjectCmsAddAfter`: creación de página CMS
- `actionObjectCmsUpdateAfter`: modificación de página CMS
- `actionObjectCmsDeleteAfter`: eliminación de página CMS
- `actionCategoryAdd`: creación de categoría
- `actionCategoryUpdate`: modificación de categoría
- `actionCategoryDelete`: eliminación de categoría
- `displayBackOfficeHeader`: inyección de fragmento CSS para el estilo del dashboard

Cada hook construye la URL canónica mediante el objeto `Link` oficial de PrestaShop, lo que respeta tus preferencias **SEO friendly URL** y los prefijos de idioma multilingüe.

## Solución de problemas

### La prueba Google falla con código 401

La autenticación ha fallado. Verifica que:

- El JSON Service Account pegado está completo y bien formado
- La Indexing API está bien activada en Google Cloud (biblioteca)
- El reloj del sistema del servidor es correcto: un desfase de más de 5 minutos invalida el JWT

### La prueba Google falla con código 403

La autenticación tiene éxito pero Google rechaza la petición. Causa habitual: el Service Account no ha sido añadido como **Propietario** de la propiedad Search Console. Re-verifica el paso 4 de la configuración Google.

### La prueba IndexNow falla

El servidor api.indexnow.org no ha podido leer el archivo clave en tu dominio. Causas posibles:

- El snippet `.htaccess` no ha sido pegado, o pegado en el lugar incorrecto (debe estar después de `RewriteEngine on`)
- El archivo físico no ha sido creado, o no tiene el nombre correcto (debe ser exactamente _la clave + .txt_)
- El contenido del archivo no corresponde a la clave (errata, salto de línea adicional)
- El servidor web sirve el archivo con el Content-Type incorrecto (debe ser `text/plain`)
- El firewall o el CDN bloquea las peticiones del robot IndexNow

Abre `https://tu-dominio.com/TU_CLAVE.txt` en un navegador en navegación privada: debes ver únicamente la clave como texto plano.

### Trabajos atascados en estado processing

Significa que un CRON ha bloqueado los trabajos pero nunca ha liberado el bloqueo (por ejemplo el proceso fue eliminado por un timeout PHP). Puedes desbloquearlos manualmente mediante phpMyAdmin:

```
UPDATE ps_df_indexapi_queue SET status = 'pending', attempts = 0 WHERE status = 'processing';
```

Si el problema se repite regularmente, aumenta el `max_execution_time` PHP de tu hosting, o reduce el tamaño del lote en la configuración del módulo.

### Cuota Google superada

Google responde con código 429 o mensaje _Quota exceeded_. La cuota predeterminada es de 200 URLs al día por Service Account.

**No cuentes con un aumento de cuota.** Google ofrece un formulario de solicitud, pero la aprobación está condicionada al uso efectivo del marcado `JobPosting` o `BroadcastEvent` en el sitio. Un catálogo de e-commerce no cumple ese criterio: la solicitud será rechazada. Trata las 200 URLs al día como un techo fijo.

Tres opciones realistas:

- Esperar 24h, ya que la cuota se reinicia diariamente
- Restringir los filtros de indexación del lado de Google a los tipos que realmente te importan (por ejemplo solo productos, desactivando categorías y CMS)
- Crear un segundo Service Account y alternar, teniendo cada Service Account su propia cuota de 200 URLs al día

Recordatorio: IndexNow no tiene cuota. Si el volumen es tu limitación principal, es el canal en el que apoyarte.

### Reinicio completo

Para empezar desde cero (útil en caso de migración o problema complejo):

1. Desinstalar el módulo desde Módulos › Gestor
2. Reinstalar: las tablas se recrean, la clave IndexNow y el token CRON se regeneran
3. Reconfigurar Google e IndexNow
4. Actualizar el snippet `.htaccess` con la nueva clave
5. Actualizar las líneas crontab con el nuevo token

La desinstalación elimina la cola y el registro, pero no elimina los envíos ya efectuados en el lado de Google o IndexNow: permanecen en sus historiales respectivos.

## Limitaciones conocidas

- **Google Indexing API oficialmente limitada** a páginas `JobPosting` o `BroadcastEvent` dentro de un `VideoObject`. La API acepta otros tipos y responde 200, pero ese código solo acredita la recepción de la notificación. Para un catálogo de productos, IndexNow es el canal principal y Google un complemento registrado
- **Cuota Google limitada** a 200 URLs al día por Service Account, sin aumento realista disponible para un e-commerce (ver Solución de problemas)
- **IndexNow no gestiona URL_DELETED**: el protocolo considera que un 404 o 410 en la URL es la forma adecuada de señalar una eliminación. El módulo ignora por tanto los trabajos IndexNow en URL_DELETED (Google los envía correctamente)
- **Variantes de productos no enviadas individualmente**: la URL canónica del producto principal basta, Google consolida las variantes naturalmente
- **Raíz de categoría ignorada** (ID 1 y 2) para evitar enviar URLs no pertinentes
- **El módulo no sustituye a un sitemap XML**: el sitemap sigue siendo el canal de descubrimiento oficial y debe mantenerse limpio y al día. El envío directo se añade encima, no lo reemplaza

## Soporte

Para cualquier pregunta técnica: [support@datafirefly.com](mailto:support@datafirefly.com), respuesta en 24h laborables en español, inglés o francés. Incluido durante 12 meses tras la compra.
