Ilustración de setup de IndexNow: página web emitiendo señal ping hacia múltiples nodos de motores de búsqueda

IndexNow tutorial 2026: setup completo con Cloudflare Pages

Publicás un artículo nuevo y Bing tarda entre uno y siete días en darse cuenta. Con IndexNow tarda entre cinco y treinta minutos, y como ChatGPT con browsing tira de Bing por detrás, el efecto se nota también ahí. Lo uso en ignax.dev y en proyectos de clientes desde 2023, y el setup completo en SvelteKit + Cloudflare Pages te lleva alrededor de una hora. Si recién arrancás con Cloudflare Pages mirá la configuración SEO completa de Cloudflare Pages antes; para el contexto AEO general está qué es AEO.

¿Qué es IndexNow exactamente?

Es un protocolo abierto que Microsoft (Bing) y Yandex publicaron en 2021. La lógica es muy directa:

  1. El sitio le avisa al motor de búsqueda cuando publica o actualiza una URL.
  2. El motor crawlea esa URL en minutos en vez de esperar al ciclo natural de descubrimiento.
  3. La URL aparece indexada y disponible para citas dramáticamente más rápido.

Soporte oficial en 2026: Bing, Yandex, Seznam (República Checa), Naver (Corea). Google no lo soporta directamente, usa su propio Indexing API y sitemap pings.

Para AEO el indirect path importa: ChatGPT con browsing usa Bing → IndexNow llena el cache de Bing → ChatGPT te puede citar más rápido. Mismo para Bing Copilot y Microsoft 365 Search. Diagrama de flujo de la API de IndexNow desde publicación hasta endpoints de Bing y otros buscadores

¿Cómo funciona el protocolo?

Cuatro pasos por cada URL nueva o actualizada:

  1. Tu sitio publica una key UUID en /{key}.txt: prueba de propiedad.
  2. Tu sitio hace POST a https://api.indexnow.org/indexnow con la lista de URLs nuevas + la key.
  3. Bing valida que la key servida coincide con la enviada en el POST.
  4. Bing crawlea las URLs en minutos.

No requiere autenticación OAuth, no requiere panel de control. Es HTTP plano.

¿Cómo genero la API key?

Una sola vez por dominio. UUID v4 de 32-64 caracteres alfanuméricos.

# En terminal con Python
python3 -c "import uuid; print(uuid.uuid4().hex)"
# Output ejemplo: 89bee770fc3a480394ff490cd251245a

# O con Node.js
node -e "console.log(crypto.randomUUID().replace(/-/g, ''))"

Guardala como variable de entorno (INDEXNOW_KEY) y no la commitees al repo public.

¿Cómo sirvo el archivo de validación?

En Cloudflare Pages + SvelteKit, dos opciones:

Opción 1: Archivo estático en static/

Creás static/{key}.txt con el contenido siendo la key misma:

89bee770fc3a480394ff490cd251245a

(El nombre del archivo y el contenido son la misma key.)

Cloudflare Pages sirve ese archivo desde el edge. Verificás visitando https://tudominio.com/{key}.txt: debe devolver la key como texto plano.

Opción 2: Ruta dinámica +server.ts (recomendado si la key viene de env vars)

// src/routes/[key]/+server.ts (con guard)
import { INDEXNOW_KEY } from '$env/static/private';
import { error } from '@sveltejs/kit';

export async function GET({ params }) {
  if (params.key !== `${INDEXNOW_KEY}.txt`) throw error(404);
  return new Response(INDEXNOW_KEY, {
    headers: { 'content-type': 'text/plain; charset=utf-8' },
  });
}

La opción dinámica es más segura porque la key vive solo en env vars de Cloudflare, no en el repo.

¿Cómo envío URLs a IndexNow?

POST a https://api.indexnow.org/indexnow con JSON body:

{
  "host": "tudominio.com",
  "key": "89bee770fc3a480394ff490cd251245a",
  "keyLocation": "https://tudominio.com/89bee770fc3a480394ff490cd251245a.txt",
  "urlList": [
    "https://tudominio.com/articles/nuevo-articulo",
    "https://tudominio.com/es/articulos/nuevo-articulo"
  ]
}

Bing valida que keyLocation sirve la key. Si OK, crawlea las URLs.

¿Cómo lo implemento como librería en SvelteKit?

Helper reutilizable:

// src/lib/indexnow.ts
const INDEXNOW_ENDPOINT = 'https://api.indexnow.org/indexnow';
const HOST = 'ignax.dev';

export async function notifyIndexNow(urls: string[], key: string) {
  if (urls.length === 0) return { ok: true, count: 0 };
  
  const res = await fetch(INDEXNOW_ENDPOINT, {
    method: 'POST',
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify({
      host: HOST,
      key,
      keyLocation: `https://${HOST}/${key}.txt`,
      urlList: urls,
    }),
  });

  // 200 = success, 202 = accepted, 400 = bad request, 403 = key mismatch, 422 = invalid urls
  return {
    ok: res.status < 300,
    status: res.status,
    count: urls.length,
  };
}

¿Cómo lo disparo en el flujo de publicación?

Tres patrones, según cómo es tu pipeline:

Patrón 1: Endpoint API que se llama post-publish

// src/routes/api/notify-indexnow/+server.ts
import { json } from '@sveltejs/kit';
import { INDEXNOW_KEY } from '$env/static/private';
import { notifyIndexNow } from '$lib/indexnow';

export async function POST({ request }) {
  const { urls } = await request.json();
  if (!Array.isArray(urls)) return json({ error: 'urls must be array' }, { status: 400 });
  
  const result = await notifyIndexNow(urls, INDEXNOW_KEY);
  return json(result);
}

Lo llamás desde tu CMS, CI, o script post-deploy.

Patrón 2: Hook en el build (Cloudflare Pages)

En package.json:

{
  "scripts": {
    "build": "vite build && node scripts/notify-indexnow.mjs"
  }
}

Script scripts/notify-indexnow.mjs:

import { readdir } from 'node:fs/promises';
import { notifyIndexNow } from '../src/lib/indexnow.js';

const KEY = process.env.INDEXNOW_KEY;
if (!KEY || !process.env.CF_PAGES_BRANCH || process.env.CF_PAGES_BRANCH !== 'main') {
  console.log('Skipping IndexNow notification (not main branch)');
  process.exit(0);
}

// Lista de URLs del sitio (idealmente filtrada a las nuevas/cambiadas)
const allUrls = await listAllUrls(); // implementa esto leyendo el registry
const result = await notifyIndexNow(allUrls, KEY);
console.log('IndexNow:', result);

Cloudflare Pages corre esto en cada deploy. Configurá INDEXNOW_KEY en Environment Variables del proyecto.

Patrón 3: Webhook desde CMS (Sanity, Contentful, etc.)

Si usás un CMS headless, configurá un webhook on publish que llame al endpoint /api/notify-indexnow con las URLs específicas que cambiaron. Más preciso que el patrón 2 porque solo notifica URLs realmente afectadas.

¿Cómo verifico que funciona?

Tres maneras:

  1. Visitar el endpoint de la key: https://tudominio.com/{key}.txt debe devolver la key. Si devuelve 404, IndexNow va a rebotar todos los pings.
  2. Bing Webmaster Tools → URL Submission → IndexNow. Muestra historial de submissions, estado y errores. La fuente de verdad.
  3. Búsqueda manual en Bing: site:tudominio.com nueva-url debe mostrar la URL indexada dentro de 1-2 horas post-ping.

Si después de 24h una URL pingeada no aparece en site: queries de Bing, hay un problema (key mismatch, URL no indexable, robots.txt blocking, etc.).

¿Qué errores comunes evitar?

Lo que más rompe IndexNow en sitios reales:

  1. Key servida no coincide con key enviada. Verificá que el archivo /{key}.txt devuelve exactamente la misma key string que mandás en el JSON.
  2. URLs con trailing slash inconsistente. Si tu sitio canonicaliza sin trailing slash pero pingéas con, IndexNow podría rebotar.
  3. Pinging desde localhost o domain de preview de Cloudflare Pages. Solo desde el dominio real funciona.
  4. Más de 10.000 URLs en un solo POST. Batchear de a 1000-5000.
  5. No diferenciar deploys main vs preview. No querés pingear cada preview deploy: solo main.

¿Cómo IndexNow se relaciona con sitemap.xml?

No reemplaza sitemap, lo complementa:

  • Sitemap.xml es el índice general que crawlers descubren y revisan periódicamente.
  • IndexNow es el ping específico cuando hay cambios urgentes.

Setup recomendado: mantener sitemap.xml actualizado dinámicamente + pingear IndexNow en cada deploy con las URLs nuevas o cambiadas.

¿Qué pasa con Google?

Google no soporta IndexNow oficialmente. Para Google:

  • Mantené sitemap.xml fresco.
  • Usá Google Indexing API: pero está limitado a Job Postings y BroadcastEvent (livestreams). Para artículos y servicios, no aplica.
  • Confirmá en GSC que el sitio se crawlea regularmente.

Para AEO, IndexNow + Bing cubre ChatGPT con browsing, Perplexity (a veces), Copilot. Google con Gemini depende del crawl natural más Google Indexing API en casos específicos. Si querés un repaso de qué chequear página por página para citas, mirá la checklist de citación AEO.

¿Cuál es el ROI real?

Para sitios que publican 1-5 contenidos nuevos por mes:

  • Sin IndexNow: Bing indexa en 1-7 días. ChatGPT te puede citar 1-3 semanas post-publicación.
  • Con IndexNow: Bing indexa en 5-30 minutos. ChatGPT te puede citar el mismo día post-publicación.

Para sitios con changes frecuentes (e-commerce, news, SaaS docs). El speedup es exponencial.

¿Por dónde empezás?

El camino corto, una hora bien usada:

  1. Generá la key (python3 -c "import uuid; print(uuid.uuid4().hex)").
  2. Subila como env var en Cloudflare Pages + servila en /{key}.txt.
  3. Implementá el ping post-deploy (Patrón 2 más arriba).

Verificá en Bing Webmaster Tools dentro de las primeras 2 horas. Para entender por qué IndexNow es clave para AEO, mirá cómo aparecer citado por ChatGPT. Si querés contratar el setup AEO completo (incluyendo IndexNow), está en el servicio de motor de contenido. Referencia oficial: IndexNow protocol docs.

Preguntas frecuentes

¿Qué motores soportan IndexNow en 2026?

Bing, Yandex, Seznam, Naver lo soportan oficialmente. Google no lo soporta directamente (usa su propia Search Console API), pero como ChatGPT con browsing usa Bing como motor underlying, IndexNow → Bing → ChatGPT funciona indirectamente. Para SEO Google clásico, IndexNow es complementario; para Bing y para citas en motores de IA. Es la forma más rápida de notificar nuevo contenido.

¿Cuánto reduce el tiempo de indexación?

Dramáticamente para Bing: de 1-7 días de crawl natural a 5-30 minutos. Para ChatGPT con browsing que depende de Bing, similar. Para Google sin acceso directo, IndexNow no ayuda (Google ignora la señal); pero si combinás IndexNow + sitemap.xml ping + Google Indexing API (para job postings y livestreams) cubrís todos los frentes.

¿Cómo se genera y maneja la API key?

Una key es un UUID de 32-64 caracteres alfanuméricos. Se genera una sola vez por dominio. Se publica en `https://tudominio.com/{key}.txt` (un archivo con la key como contenido). Ese archivo es la prueba de propiedad que Bing valida cada vez que recibe un ping. La key no caduca, se reusa siempre. Generala con un UUID v4 random, `crypto.randomUUID()` en Node.js funciona.

¿Cómo lo integro en SvelteKit + Cloudflare Pages?

Tres piezas: 1) el archivo `{key}.txt` en `static/` con la key como contenido; 2) una ruta `/api/indexnow/+server.ts` que se llama post-publish y manda el POST a api.indexnow.org; 3) un hook en el build o en el CMS que dispara la ruta cuando hay contenido nuevo. Para sitios basados en Markdown registry como ignax.dev, lo dispara el build hook de Cloudflare Pages cuando hay deploy successful.

¿Cuáles son los límites?

Bing acepta hasta 10.000 URLs por POST. Rate limit: ~10.000 URLs/día por dominio. En la práctica nunca lo llegás. Para sitios con changes frecuentes pero pocas URLs (blog que publica 5 artículos/mes). Un POST por deploy alcanza. Para e-commerce con cambios masivos de catálogo, batchear de a 1000 URLs cada 5 minutos.

¿Vale la pena para sitios chicos?

Sí, porque cuesta una hora setupear y rinde indexación 50-100x más rápida en Bing. Para AEO (citas en ChatGPT y Perplexity). Es de las mejores decisiones técnicas que podés tomar. Para SEO Google puro. El ROI es marginal pero positivo. Setup en 1 hora, beneficio durante años, ratio inmejorable. Mirá /es/articulos/cloudflare-pages-seo para el setup base del que depende este tutorial.