CrawlForge MCP
API Reference

Monitores alojados

Entregue a CrawlForge un conjunto de páginas y un calendario cron. Las obtiene y compara en su propio programador, registra cada comprobación y le indica qué cambió por correo o mediante un webhook firmado. No hay cuota por monitor: cada comprobación cobra el precio de track_changes por destino comparado.

Descripción general

Un monitor es un nombre, hasta 20 destinos (una url más un selector CSS opcional), un calendario cron de cinco campos con una zona horaria IANA y el lugar al que enviar los resultados. El programador de CrawlForge se ejecuta cada 5 minutos e inicia por sí mismo cada comprobación pendiente, así que no hace falta que nada esté en ejecución de su lado.

La primera comprobación de un destino captura una línea base y la informa como new. Cada comprobación posterior compara con la comprobación anterior y avanza la línea base, de modo que cada comprobación informa el cambio desde la anterior. Las líneas base viven hasta que se elimina el monitor; las comprobaciones se depuran después de retention_days.

Todos los endpoints aceptan el mismo encabezado X-API-Key que las herramientas (o Authorization: Bearer cf_…). Las llamadas de gestión no cobran nada y funcionan con cero credits. Las respuestas usan el envoltorio de las herramientas, { success, data }, y los errores incluyen error.code y error.message.

Endpoints

MétodoRutaQué hace
POST/api/v1/monitorsCrea un monitor. Devuelve 201 con el monitor, incluido su webhook_secret.
GET/api/v1/monitorsLista los monitores, cada uno con su comprobación más reciente como last_check. Parámetros de consulta limit y cursor; el cuerpo incluye next_cursor. Nunca devuelve webhook_secret.
GET/api/v1/monitors/{id}Un monitor, incluido webhook_secret.
PATCH/api/v1/monitors/{id}Actualiza cualquier subconjunto de los campos de creación. Poner status en paused deja next_run_at en null.
DELETE/api/v1/monitors/{id}Elimina el monitor. Devuelve { id, deleted: true }.
POST/api/v1/monitors/{id}/runEjecuta una comprobación ahora, en línea, y la devuelve con pages. 409 MONITOR_RUNNING mientras ya haya una comprobación en curso.
GET/api/v1/monitors/{id}/checksHistorial de comprobaciones sin pages. Parámetros de consulta limit y cursor.
GET/api/v1/monitors/{id}/checks/{check_id}Una comprobación con pages y las deliveries de webhook.

Crear un monitor

Solo name y targets son obligatorios. Los valores predeterminados le dan una comprobación cada hora en UTC con 30 días de historial.

terminalBash
curl -X POST https://crawlforge.dev/api/v1/monitors \
  -H "X-API-Key: cf_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "competitor pricing",
    "targets": [{ "url": "https://competitor.com/pricing", "selector": ".pricing-table" }],
    "schedule_cron": "0 * * * *",
    "webhook_url": "https://example.com/hooks/crawlforge"
  }'

Todos los campos que acepta el cuerpo. PATCH acepta cualquier subconjunto de los mismos campos.

CampoTipoPredeterminadoDescripción
namestringobligatorioDe 1 a 80 caracteres.
targetsarrayobligatorioDe 1 a 20 objetos { url, selector? }. Las URL deben ser direcciones http(s) públicas; una dirección privada o local se rechaza con 400.
schedule_cronstring0 * * * *Expresión cron de cinco campos. Las ejecuciones consecutivas deben estar separadas al menos 5 minutos.
timezonestringUTCZona horaria IANA en la que se evalúa el calendario, por ejemplo Europe/Madrid.
notify_emailsstring[]—Hasta 5 direcciones que reciben un correo cuando una comprobación encuentra algo. Consulte Notificaciones.
webhook_urlstring—URL https pública que recibe los eventos firmados. Consulte Notificaciones.
webhook_secretstringgeneradoDe 16 a 128 caracteres con los que se firma cada entrega. Se genera cuando se omite y webhook_url está definido. Se devuelve al crear y en el GET de uno, nunca en la lista.
retention_daysnumber30De 1 a 365. Las comprobaciones más antiguas se depuran; las líneas base se conservan hasta que se elimina el monitor.
statusstringactiveactive o paused. Un monitor en pausa conserva sus líneas base y no tiene next_run_at.

Cuerpo completo

Dos destinos, mañanas de días laborables en Madrid, correo más webhook con su propio secreto, 90 días de historial:

POST /api/v1/monitorsJson
{
  "name": "competitor pricing",
  "targets": [
    { "url": "https://competitor.com/pricing", "selector": ".pricing-table" },
    { "url": "https://competitor.com/changelog" }
  ],
  "schedule_cron": "0 9 * * 1-5",
  "timezone": "Europe/Madrid",
  "notify_emails": ["alerts@example.com"],
  "webhook_url": "https://example.com/hooks/crawlforge",
  "webhook_secret": "3f9a1c7e5b2d48f0a6c1e9d7b5a3f2c4",
  "retention_days": 90,
  "status": "active"
}

El objeto monitor

Crear, el GET de uno y PATCH devuelven el monitor. next_run_at es la próxima franja, last_check_at la hora de la comprobación más reciente y estimated_credits_per_month se explica en Facturación. Las respuestas de lista añaden last_check, la comprobación más reciente sin sus páginas.

201 CreatedJson
{
  "success": true,
  "data": {
    "id": "cmf9k2x1a0001s8h4b7d3q2wz",
    "name": "competitor pricing",
    "targets": [
      { "url": "https://competitor.com/pricing", "selector": ".pricing-table" }
    ],
    "schedule_cron": "0 * * * *",
    "timezone": "UTC",
    "notify_emails": [],
    "webhook_url": "https://example.com/hooks/crawlforge",
    "webhook_secret": "3f9a1c7e5b2d48f0a6c1e9d7b5a3f2c4",
    "status": "active",
    "next_run_at": "2026-09-07T15:00:00.000Z",
    "last_check_at": null,
    "retention_days": 30,
    "estimated_credits_per_month": 2160,
    "created_at": "2026-09-07T14:12:08.000Z",
    "updated_at": "2026-09-07T14:12:08.000Z"
  }
}

Listar, ejecutar ahora y leer comprobaciones

Listar

terminalBash
curl "https://crawlforge.dev/api/v1/monitors?limit=20" \
  -H "X-API-Key: cf_test_YOUR_KEY"

# Next page: pass the next_cursor from the previous response
curl "https://crawlforge.dev/api/v1/monitors?limit=20&cursor=NEXT_CURSOR" \
  -H "X-API-Key: cf_test_YOUR_KEY"

Ejecutar ahora

Ejecuta una comprobación de inmediato, fuera del calendario, y la devuelve con sus páginas. Se aplican las mismas reglas de facturación. Una segunda llamada mientras esa comprobación sigue en curso responde 409 MONITOR_RUNNING.

terminalBash
# Run one check now and get it back with its pages
curl -X POST https://crawlforge.dev/api/v1/monitors/MONITOR_ID/run \
  -H "X-API-Key: cf_test_YOUR_KEY"

Comprobaciones

terminalBash
# Check history (no pages)
curl "https://crawlforge.dev/api/v1/monitors/MONITOR_ID/checks?limit=20" \
  -H "X-API-Key: cf_test_YOUR_KEY"

# One check, with its pages and webhook deliveries
curl https://crawlforge.dev/api/v1/monitors/MONITOR_ID/checks/CHECK_ID \
  -H "X-API-Key: cf_test_YOUR_KEY"

El objeto comprobación

Una comprobación con dos destinos: la tabla de precios cambió y se cobró; la página de documentación se topó con un desafío de Cloudflare y no se cobró. deliveries es el registro de webhooks de la comprobación.

GET /api/v1/monitors/{id}/checks/{check_id}Json
{
  "success": true,
  "data": {
    "id": "cmf9k5r8t0003s8h4m1n6p4vx",
    "monitor_id": "cmf9k2x1a0001s8h4b7d3q2wz",
    "started_at": "2026-09-07T15:00:02.000Z",
    "finished_at": "2026-09-07T15:00:05.000Z",
    "status": "completed",
    "summary": { "total": 2, "new": 0, "changed": 1, "unchanged": 0, "blocked": 1, "errored": 0 },
    "credits_reserved": 6,
    "credits_charged": 3,
    "error": null,
    "pages": [
      {
        "url": "https://competitor.com/pricing",
        "selector": ".pricing-table",
        "status": "changed",
        "change_percent": 12.5,
        "structural_similarity": 0.9713,
        "added_count": 4,
        "removed_count": 2,
        "added_samples": ["Pro $79 / month", "Includes 50,000 credits"],
        "removed_samples": ["Pro $99 / month", "Includes 25,000 credits"],
        "content_hash": "9f2c0b7e4d1a8c6f3e5b2a9d7c4f1e8b0a6d3c2f5e9b1a7d4c8f2e6b3a9d1c7f",
        "error_code": null,
        "error": null,
        "blocked_vendor": null,
        "duration_ms": 1180,
        "charged": true
      },
      {
        "url": "https://competitor.com/docs",
        "selector": null,
        "status": "blocked",
        "change_percent": null,
        "structural_similarity": null,
        "added_count": null,
        "removed_count": null,
        "added_samples": [],
        "removed_samples": [],
        "content_hash": null,
        "error_code": "BLOCKED",
        "error": "Challenge page served by cloudflare",
        "blocked_vendor": "cloudflare",
        "duration_ms": 640,
        "charged": false
      }
    ],
    "deliveries": [
      {
        "id": "cmf9k5rb20005s8h4q7w2e9rt",
        "event": "monitor.page",
        "url": "https://example.com/hooks/crawlforge",
        "attempts": 1,
        "status": "delivered",
        "http_status": 200,
        "error": null,
        "delivered_at": "2026-09-07T15:00:05.100Z"
      },
      {
        "id": "cmf9k5rb20006s8h4z3x8c5vb",
        "event": "monitor.check.completed",
        "url": "https://example.com/hooks/crawlforge",
        "attempts": 1,
        "status": "delivered",
        "http_status": 200,
        "error": null,
        "delivered_at": "2026-09-07T15:00:05.400Z"
      }
    ]
  }
}

Facturación y la estimación mensual

No hay cuota por monitor, y crear, listar, actualizar o eliminar un monitor no cuesta nada. Cada comprobación retiene 3 credits por destino, el precio de track_changes, y se queda con 3 por cada destino cuyo estado sea new, changed o unchanged. Los destinos que resultaron blocked o error no se cobran. Cada comprobación escribe una fila track_changes en el registro de uso.

Si su saldo no puede cubrir la retención, la comprobación se registra como insufficient_credits y no se obtiene nada.

estimated_credits_per_month en el monitor es el número de veces que el calendario se dispara en los próximos 30 días × destinos × 3. Es el techo para un mes en el que cada destino se obtiene y compara todas las veces.

schedule_cronDestinosEjecuciones en 30 díasestimated_credits_per_month
0 * * * *17202,160
*/15 * * * *12,8808,640
0 9 * * *530450

Estados de comprobación y de página

Cada comprobación lleva un status, un summary con el conteo por estado de página, y credits_reserved / credits_charged.

status de la comprobaciónSignificado
runningLa comprobación está en curso. Mientras tanto, POST …/run responde 409 MONITOR_RUNNING.
completedSe procesaron todos los destinos. Lea summary y pages.
failedLa comprobación no pudo terminar; error indica por qué.
skipped_overlapLa comprobación anterior seguía en curso cuando llegó esta franja. No se obtuvo nada.
insufficient_creditsEl saldo no pudo cubrir la retención. No se obtuvo nada.

Cada entrada de pages lleva un status. Una página changed incluye change_percent, structural_similarity, added_count, removed_count y hasta 20 líneas de muestra de hasta 500 caracteres en added_samples y removed_samples; los conteos son los totales reales.

status de la páginaSignificadoSe cobra
newPrimera captura de este destino. Se escribió la línea base; todavía no hay nada que comparar.Sí
changedEl contenido difiere de la comprobación anterior. La línea base avanza a esta captura.Sí
unchangedMismo hash de contenido que la comprobación anterior.Sí
blockedEl destino respondió con un muro de desafío (Cloudflare, DataDome, PerimeterX, Akamai, Amazon, Vercel) o con un documento inutilizable. blocked_vendor lo nombra. Nunca se informa como un cambio.No
errorLa obtención falló, el selector no coincidió con nada o robots.txt no permite la ruta. error_code lleva el código: FETCH_FAILED, SELECTOR_NOT_FOUND, ROBOTS_DISALLOWED, etc.No
robots.txt siempre se respeta Un monitor no tiene anulación respect_robots. Un destino cuya ruta robots.txt no permite a CrawlForge se informa como error con ROBOTS_DISALLOWED en cada comprobación y nunca se cobra.

Reglas del calendario

schedule_cron es una expresión cron estándar de cinco campos (minuto, hora, día del mes, mes, día de la semana) evaluada en timezone. Dos ejecuciones consecutivas deben estar separadas al menos 5 minutos, así que * * * * * y */2 * * * * se rechazan con 400.

El programador de CrawlForge se despierta cada 5 minutos e inicia todas las comprobaciones cuya franja ya pasó, de modo que una comprobación comienza dentro de los 5 minutos siguientes a su franja. next_run_at en el monitor es la próxima franja; pausar el monitor lo deja en null.

Un monitor cuya comprobación anterior sigue en curso cuando llega su siguiente franja registra una comprobación skipped_overlap en lugar de iniciar una segunda.

ExpresiónSe ejecuta
0 * * * *Cada hora, en punto (el valor predeterminado).
*/15 * * * *Cada 15 minutos.
0 9 * * 1-5A las 09:00 de lunes a viernes, en timezone.
0 6,18 * * *A las 06:00 y a las 18:00 todos los días.
30 2 1 * *A las 02:30 del primer día de cada mes.

Notificaciones

Correo. Cuando notify_emails está definido, solo se envía un mensaje por una comprobación que tenga al menos una página new, changed, blocked o error. Una comprobación en la que todos los destinos son unchanged no envía nada.

Webhooks. Cuando webhook_url está definido, cada entrega es un POST con un cuerpo JSON { event, id, timestamp, data } y estos encabezados:

EncabezadoValor
Content-Typeapplication/json
X-Webhook-Eventmonitor.page o monitor.check.completed
X-Webhook-IDId de la entrega, estable entre reintentos, para que un receptor pueda descartar un duplicado.
X-Webhook-TimestampHora Unix en milisegundos en la que se envió la entrega.
X-Webhook-Signaturesha256= seguido del HMAC-SHA256 hexadecimal del cuerpo sin procesar exacto, con webhook_secret como clave.

Dos eventos. Primero salen los eventos de página y después el resumen de la comprobación.

eventCuándodata
monitor.pageUno por cada página cuyo estado no sea unchanged.{ monitor: { id, name }, check_id, page, dashboard_url }: page es el resultado completo de la página, muestras incluidas.
monitor.check.completedCada comprobación completada.{ monitor, check: { id, started_at, finished_at, status, summary, credits_charged }, pages, dashboard_url }: cada entrada de pages tiene url, selector, status, change_percent, added_count, removed_count, error_code, sin muestras.
POST webhook_url — X-Webhook-Event: monitor.check.completedJson
{
  "event": "monitor.check.completed",
  "id": "cmf9k5rb20006s8h4z3x8c5vb",
  "timestamp": 1788793205400,
  "data": {
    "monitor": { "id": "cmf9k2x1a0001s8h4b7d3q2wz", "name": "competitor pricing" },
    "check": {
      "id": "cmf9k5r8t0003s8h4m1n6p4vx",
      "started_at": "2026-09-07T15:00:02.000Z",
      "finished_at": "2026-09-07T15:00:05.000Z",
      "status": "completed",
      "summary": { "total": 2, "new": 0, "changed": 1, "unchanged": 0, "blocked": 1, "errored": 0 },
      "credits_charged": 3
    },
    "pages": [
      {
        "url": "https://competitor.com/pricing",
        "selector": ".pricing-table",
        "status": "changed",
        "change_percent": 12.5,
        "added_count": 4,
        "removed_count": 2,
        "error_code": null
      },
      {
        "url": "https://competitor.com/docs",
        "selector": null,
        "status": "blocked",
        "change_percent": null,
        "added_count": null,
        "removed_count": null,
        "error_code": "BLOCKED"
      }
    ],
    "dashboard_url": "https://www.crawlforge.dev/dashboard/monitors/cmf9k2x1a0001s8h4b7d3q2wz"
  }
}

Entrega. Hasta 4 intentos (el primero más tres reintentos) con 1 s, 2 s y 4 s entre ellos y un tiempo de espera de 10 s cada uno. Una respuesta 2xx cuenta como entregada. Un 4xx distinto de 408 o 429 no se reintenta. El registro de entregas viaja con la comprobación: GET …/checks/{check_id} devuelve deliveries con el número de intentos, el estado HTTP y el error de cada evento.

Verificar la firma

Calcule el HMAC sobre el cuerpo sin procesar de la solicitud, antes de cualquier análisis JSON, y compárelo en tiempo constante. El conjunto de encabezados y el esquema de firma son los mismos que usan los webhooks del servidor MCP de CrawlForge, así que un solo receptor verifica ambos.

verifyWebhook.tsTypescript
import { createHmac, timingSafeEqual } from 'node:crypto';
import express from 'express';

// Sign the RAW body exactly as received. Parsing and re-serialising the JSON
// first changes the bytes and the signature no longer matches.
function verifyCrawlForgeWebhook(rawBody: Buffer, signatureHeader: string, secret: string): boolean {
  const expected = Buffer.from('sha256=' + createHmac('sha256', secret).update(rawBody).digest('hex'));
  const received = Buffer.from(signatureHeader);
  return expected.length === received.length && timingSafeEqual(expected, received);
}

const app = express();

// express.raw keeps the body as a Buffer; express.json would have parsed it.
app.post('/hooks/crawlforge', express.raw({ type: 'application/json' }), (req, res) => {
  const secret = process.env.CRAWLFORGE_WEBHOOK_SECRET!;
  if (!verifyCrawlForgeWebhook(req.body, req.header('X-Webhook-Signature') ?? '', secret)) {
    return res.status(401).end();
  }

  const { event, data } = JSON.parse(req.body.toString('utf8'));
  if (event === 'monitor.page') {
    console.log(data.page.status, data.page.url, data.page.change_percent);
  } else if (event === 'monitor.check.completed') {
    console.log('check', data.check.id, data.check.summary);
  }
  res.status(204).end();
});

Límites

  • 50 monitores por cuenta. La creación número 51 responde 409 MONITOR_LIMIT_REACHED.
  • 20 destinos por monitor y 5 direcciones en notify_emails.
  • Al menos 5 minutos entre ejecuciones consecutivas.
  • retention_days de 1 a 365, 30 de forma predeterminada. Las líneas base se conservan hasta que se elimina el monitor.
  • Muestras de diferencias: hasta 20 líneas de hasta 500 caracteres en cada uno de added_samples y removed_samples.

Errores

EstadoSignificado
400 VALIDATION_ERRORUn campo está fuera de rango, la expresión cron no es válida o se dispara con más frecuencia que cada 5 minutos, o una URL de destino no es una dirección http(s) pública.
401API key ausente o inválida.
404No hay ningún monitor ni comprobación con ese id en su cuenta.
409 MONITOR_LIMIT_REACHEDYa tiene 50 monitores.
409 MONITOR_RUNNINGPOST …/run mientras hay una comprobación en curso.
Relacionado
track_changes
Línea base y comparación puntuales, y operation: "monitor" para crear un monitor a partir de una sola URL; create_scheduled_monitor del servidor MCP con hosted: true crea el mismo tipo de monitor.
Panel
Cree, pause e inspeccione monitores y sus comprobaciones sin escribir una solicitud.

Pie de página

CrawlForge MCP

Web scraping empresarial para agentes de IA. 31 herramientas MCP especializadas diseñadas para desarrolladores modernos que crean sistemas inteligentes.

Producto

  • Funciones
  • Playground
  • Precios
  • Casos de uso
  • Integraciones
  • Alternativas
  • Registro de cambios

Recursos

  • Primeros pasos
  • Referencia de la API
  • Plantillas
  • Guías
  • Blog
  • Glosario
  • Preguntas frecuentes
  • Mapa del sitio

Desarrolladores

  • Protocolo MCP
  • Claude Desktop
  • Cursor IDE
  • LangChain
  • LlamaIndex

Empresa

  • Acerca de
  • Contacto
  • Privacidad
  • Términos
  • Uso aceptable
  • Seguridad
  • Cookies

Mantente al día

Recibe las últimas novedades sobre nuevas herramientas y funciones.

Creado con Next.js y el protocolo MCP

© 2025-2026 CrawlForge. Todos los derechos reservados.