# Monitoreo (/es/features/monitoring)

<!-- agent-signals: reading_time_min: 20 · est_tokens: 10468 · updated: 2026-07-30 -->
Related: [Búsqueda](/es/features/search.md), [Highlights de búsqueda](/es/features/search-highlights.md), [Índice de investigación](/es/features/research.md), [scraping](/es/features/scrape.md), [Scraping más rápido](/es/features/fast-scraping.md), [Raspado en lote](/es/features/batch-scrape.md)

El monitoreo de Firecrawl ejecuta comprobaciones recurrentes y te notifica a ti o a tu agente cuando algo cambia o aparece. Usa `/monitor` para [vigilar páginas conocidas](/es/features/monitoring-page), [rastrear un sitio web de forma programada](/es/features/monitoring-website) o [ejecutar una búsqueda web siempre activa](/es/features/monitoring-web-scale) para encontrar nuevos resultados que coincidan con un objetivo.

Todos los tipos de monitores comparten el mismo flujo de trabajo: seleccionar uno o más objetivos, establecer una programación, añadir un objetivo opcional en lenguaje natural y recibir notificaciones por webhook, correo electrónico o Slack cuando algo sea relevante. Esta página cubre la configuración compartida. Para la configuración y los ejemplos específicos de cada objetivo, ve a la página de monitoreo de [Página](/es/features/monitoring-page), [Sitio web](/es/features/monitoring-website) o [Toda la web a escala](/es/features/monitoring-web-scale).

<CardGroup cols="3">
  <Card title="Monitoreo de páginas" icon="<svg xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 24 24&#x22; fill=&#x22;none&#x22;><path d=&#x22;M8 7L16 7&#x22; stroke=&#x22;currentColor&#x22; stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/><path d=&#x22;M8 11L12 11&#x22; stroke=&#x22;currentColor&#x22; stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/><path d=&#x22;M13 21.5V21C13 18.1716 13 16.7574 13.8787 15.8787C14.7574 15 16.1716 15 19 15H19.5M20 13.3431V10C20 6.22876 20 4.34315 18.8284 3.17157C17.6569 2 15.7712 2 12 2C8.22877 2 6.34315 2 5.17157 3.17157C4 4.34314 4 6.22876 4 10L4 14.5442C4 17.7892 4 19.4117 4.88607 20.5107C5.06508 20.7327 5.26731 20.9349 5.48933 21.1139C6.58831 22 8.21082 22 11.4558 22C12.1614 22 12.5141 22 12.8372 21.886C12.9044 21.8623 12.9702 21.835 13.0345 21.8043C13.3436 21.6564 13.593 21.407 14.0919 20.9081L18.8284 16.1716C19.4065 15.5935 19.6955 15.3045 19.8478 14.9369C20 14.5694 20 14.1606 20 13.3431Z&#x22; stroke=&#x22;currentColor&#x22; stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/></svg>" href="/es/features/monitoring-page">
    Vigila una o más URL conocidas, compara cada scraping con la última instantánea y genera alertas ante cambios significativos en la página.
  </Card>

  <Card title="Monitoreo de sitios web" icon="<svg xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 24 24&#x22; fill=&#x22;none&#x22;><path d=&#x22;M8 7L16 7&#x22; stroke=&#x22;currentColor&#x22; stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/><path d=&#x22;M8 11L12 11&#x22; stroke=&#x22;currentColor&#x22; stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/><path d=&#x22;M13 21.5V21C13 18.1716 13 16.7574 13.8787 15.8787C14.7574 15 16.1716 15 19 15H19.5M20 13.3431V10C20 6.22876 20 4.34315 18.8284 3.17157C17.6569 2 15.7712 2 12 2C8.22877 2 6.34315 2 5.17157 3.17157C4 4.34314 4 6.22876 4 10L4 14.5442C4 17.7892 4 19.4117 4.88607 20.5107C5.06508 20.7327 5.26731 20.9349 5.48933 21.1139C6.58831 22 8.21082 22 11.4558 22C12.1614 22 12.5141 22 12.8372 21.886C12.9044 21.8623 12.9702 21.835 13.0345 21.8043C13.3436 21.6564 13.593 21.407 14.0919 20.9081L18.8284 16.1716C19.4065 15.5935 19.6955 15.3045 19.8478 14.9369C20 14.5694 20 14.1606 20 13.3431Z&#x22; stroke=&#x22;currentColor&#x22; stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/></svg>" href="/es/features/monitoring-website">
    Rastrea un sitio de forma programada, detecta páginas añadidas, modificadas o eliminadas y notifica a tu webhook o bandeja de entrada.
  </Card>

  <Card title="Monitoreo de toda la web a escala" icon="<svg xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 24 24&#x22; fill=&#x22;none&#x22;><path d=&#x22;M12.5 19L12.5 22&#x22; stroke=&#x22;currentColor&#x22; stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/><path d=&#x22;M10.5 22H14.5&#x22; stroke=&#x22;currentColor&#x22; stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/><circle cx=&#x22;7&#x22; cy=&#x22;7&#x22; r=&#x22;7&#x22; transform=&#x22;matrix(-1 0 0 1 20.5 2)&#x22; stroke=&#x22;currentColor&#x22; stroke-linecap=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/><path d=&#x22;M8.5 4C9.15431 4.0385 9.49236 4.35899 10.0735 4.97301C11.1231 6.08206 12.1727 6.1746 12.8724 5.80492C13.922 5.2504 13.04 4.35221 14.2719 3.86409C15.0748 3.54595 15.1868 2.68026 14.7399 2&#x22; stroke=&#x22;currentColor&#x22; stroke-linejoin=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/><path d=&#x22;M20 10C18.5 10 18.2338 11.2468 17 11C14.5 10.5 13.7916 11.0589 13.7916 12.2511C13.7916 13.4432 13.7916 13.4432 13.2717 14.3373C12.9335 14.9189 12.8153 15.5004 13.4894 16&#x22; stroke=&#x22;currentColor&#x22; stroke-linejoin=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/><path d=&#x22;M6.5 2C4.64864 3.79995 3.5 6.3082 3.5 9.08251C3.5 14.5598 7.97715 19 13.5 19C16.2255 19 18.6962 17.9187 20.5 16.165&#x22; stroke=&#x22;currentColor&#x22; stroke-linecap=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/></svg>" href="/es/features/monitoring-web-scale">
    Ejecuta búsquedas web recurrentes y genera alertas cuando aparezca un resultado nuevo que coincida con tu objetivo.
  </Card>
</CardGroup>

Cada comprobación registra resultados por página como `same`, `new`, `changed`, `removed` o `error`. Puedes recibir un webhook cuando termine cada página monitoreada, un webhook por cada comprobación completada, resúmenes por correo electrónico cuando haya cambios o errores, notificaciones de Slack en un canal, o cualquier combinación de estas notificaciones.

<div id="targets">
  ## Objetivos [#objetivos]
</div>

Cada monitor tiene uno o más **objetivos**. El tipo de objetivo determina qué hace cada comprobación:

| Objetivo | Qué supervisa                          | Configuración                                                          |
| -------- | -------------------------------------- | ---------------------------------------------------------------------- |
| `scrape` | URL conocidas que indicas              | [Monitoreo de páginas](/es/features/monitoring-page)                   |
| `crawl`  | Cada página descubierta por un rastreo | [Monitoreo de sitios web](/es/features/monitoring-website)             |
| `search` | Nuevos resultados en toda la web       | [Monitoreo de toda la web a escala](/es/features/monitoring-web-scale) |

Cada monitor acepta entre 1 y 50 objetivos, y puedes mezclar tipos de objetivo en un solo monitor. `retentionDays` es `30` de forma predeterminada y puede configurarse hasta `365`.

Cada llamada de creación devuelve el nuevo monitor con su cron normalizado, `nextRunAt` calculado y `estimatedCreditsPerMonth`. Cuando la evaluación está habilitada, `estimatedCreditsPerMonth` es una estimación de cota superior porque los créditos de evaluación solo se cobran por las páginas modificadas que realmente se evalúan:

```json title="Response"
{
  "success": true,
  "data": {
    "id": "019df960-06e7-7383-9d89-82c0113dc31a",
    "name": "Hacker News AI monitor",
    "status": "active",
    "schedule": {
      "cron": "*/30 * * * *",
      "timezone": "UTC"
    },
    "nextRunAt": "2026-05-17T16:00:00.000Z",
    "lastRunAt": null,
    "currentCheckId": null,
    "goal": "Alert when a new Hacker News story related to AI enters the top 10. Ignore changes to stories that are not about AI. Do not alert on changes outside the top 10.",
    "judgeEnabled": true,
    "targets": [
      {
        "id": "019df960-09bb-7c11-8001-1f12f50ab1c2",
        "type": "scrape",
        "urls": ["https://news.ycombinator.com"]
      }
    ],
    "webhook": null,
    "notification": {
      "email": {
        "enabled": true,
        "recipients": ["alerts@example.com"],
        "includeDiffs": true
      }
    },
    "retentionDays": 30,
    "estimatedCreditsPerMonth": 2880,
    "lastCheckSummary": null,
    "createdAt": "2026-05-17T15:30:00.000Z",
    "updatedAt": "2026-05-17T15:30:00.000Z"
  }
}
```

<div id="goals-and-judging">
  ## Objetivos y evaluación [#objetivos-y-evaluación]
</div>

Añade un `goal` en lenguaje claro cuando solo quieras recibir alertas por cambios significativos. Si `goal` está presente y se omite `judgeEnabled`, Firecrawl habilita la evaluación automáticamente. La evaluación se ejecuta en las páginas que han cambiado y devuelve un `judgment` con `meaningful`, `confidence`, `reason` y `meaningfulChanges`.

La forma en que se aplica el objetivo depende del objetivo: los monitores de [página](/es/features/monitoring-page) y [sitio web](/es/features/monitoring-website) evalúan las páginas modificadas, mientras que los [monitores de toda la web a escala](/es/features/monitoring-web-scale#judging) evalúan cada nuevo resultado de búsqueda.

Usa `judgeEnabled: false` si quieres guardar un objetivo sin evaluar todavía los cambios. El evaluador solo se ejecuta cuando el monitor tiene tanto `judgeEnabled` como un `goal` no vacío.

<Note>
  Se requiere un `goal` para los objetivos `search` (supervisión de toda la web a escala) a menos que establezcas `judgeEnabled: false`. Es opcional para los objetivos `scrape` y `crawl`.
</Note>

<Note>
  Cada comprobación siempre consume créditos por las operaciones subyacentes de scraping o rastreo. Si la evaluación está habilitada, el evaluador añade 1 crédito por cada página modificada que valida. Las comprobaciones sin páginas modificadas no usan créditos del evaluador.
</Note>

Los buenos objetivos son breves y explícitos: indica qué debe activar una alerta, especifica de nuevo cualquier criterio de alcance, como top N, precio, tipo de puesto, empresa, región, tema, estado o entidad, e incluye exclusiones solo cuando formen parte de la intención. Si el objetivo es amplio, mantenlo amplio; por ejemplo, "cualquier cambio" no debería añadir filtros de ruido que oculten cambios.

Por ejemplo, un monitor con este objetivo:

```text
Alerta cuando una nueva historia de Hacker News relacionada con IA entre al top 10. Ignora los cambios en historias que no sean sobre IA. No alertes sobre cambios fuera del top 10.
```

podría generar un webhook `monitor.page` como este cuando una historia coincidente pase a estar dentro del alcance:

```json title="monitor.page"
{
  "success": true,
  "type": "monitor.page",
  "id": "019df960-5f2a-75fb-a98b-bd2d32ca67d4",
  "webhookId": "f1e2d3c4-0000-0000-0000-000000000000",
  "data": [
    {
      "monitorId": "019df960-06e7-7383-9d89-82c0113dc31a",
      "checkId": "019df960-5f2a-75fb-a98b-bd2d32ca67d4",
      "url": "https://news.ycombinator.com",
      "status": "changed",
      "previousScrapeId": "019df94f-82c3-7e41-81f0-00c72b2d9c52",
      "currentScrapeId": "019df960-73ee-7ac2-97a9-fb0e442c21f1",
      "error": null,
      "isMeaningful": true,
      "judgment": {
        "meaningful": true,
        "confidence": "high",
        "reason": "A new AI-related story entered the Hacker News top 10.",
        "meaningfulChanges": [
          {
            "type": "added",
            "after": "4. Show HN: Open-source AI coding assistant",
            "reason": "This is a new AI-related story inside the top 10."
          }
        ]
      },
      "diff": {
        "text": "--- previous\n+++ current\n@@ -1,5 +1,6 @@\n # Hacker News\n 1. Database internals for beginners\n 2. A new approach to CSS\n 3. Building reliable queues\n+4. Show HN: Open-source AI coding assistant\n"
      }
    }
  ],
  "metadata": {
    "environment": "production"
  }
}
```

<div id="schedules">
  ## Programaciones [#programaciones]
</div>

Las programaciones pueden proporcionarse en formato cron o como texto simple en lenguaje natural.

<CodeGroup>
  <CodeBlockTabs defaultValue="Cron" groupId="cron+text">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="Cron">
        Cron
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Text">
        Text
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="Cron">
      ```json  
      {
        "schedule": {
          "cron": "*/30 * * * *",
          "timezone": "UTC"
        }
      }
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Text">
      ```json  
      {
        "schedule": {
          "text": "every 30 minutes",
          "timezone": "UTC"
        }
      }
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

Ejemplos compatibles de lenguaje natural:

* `every 30 minutes`
* `every 15 minutes starting at :07`
* `hourly`
* `every 2 hours`
* `daily`
* `daily at 9:00`
* `daily at 9am`
* `daily at 5:30 PM`
* `weekly`

El intervalo mínimo es de 5 minutos. Las respuestas de la API siempre devuelven la expresión cron normalizada. En las programaciones de texto, `timezone` controla cuándo se ejecutan frases como `daily at 9am`. Las programaciones en texto se distribuyen según el ID del monitor antes de convertirse a cron, para que varios monitores no se ejecuten todos en el mismo instante.

<div id="change-tracking">
  ## Seguimiento de cambios [#seguimiento-de-cambios]
</div>

Los monitores de [Página](/es/features/monitoring-page) y [sitio web](/es/features/monitoring-website) comparan el markdown de cada página de forma predeterminada e informan `same`, `changed`, `new`, `removed` o `error`. Si quieres detectar cambios en **campos estructurados específicos** (precio, encabezado, indicador de disponibilidad, elementos de una lista, etc.), habilita el seguimiento de cambios en modo JSON añadiendo un formato `changeTracking` con `modes: ["json"]` a `scrapeOptions` del objetivo.

<Note>
  El seguimiento de cambios se aplica a los objetivos `scrape` y `crawl`. Los monitores de escala web completos (`search`) generan alertas sobre resultados nuevos en lugar de comparar páginas conocidas. Consulta [Statuses and dedup](/es/features/monitoring-web-scale#statuses-and-dedup).
</Note>

<div id="markdown-mode-default">
  ### Modo Markdown (predeterminado) [#modo-markdown-predeterminado]
</div>

Cuando `scrapeOptions.formats` es solo `["markdown"]`, cada página con cambios en la respuesta de check incluye un diff de texto unificado y un AST al estilo de [parseDiff](https://github.com/sergeyt/parse-diff):

```json title="Markdown-mode diff"
{
  "diff": {
    "text": "--- previous\n+++ current\n@@ -1,3 +1,3 @@\n # Pricing\n-Starter — $19/mo\n+Starter — $24/mo\n",
    "json": {
      "files": [
        {
          "from": "previous",
          "to": "current",
          "chunks": [
            {
              "content": "@@ -1,3 +1,3 @@",
              "changes": []
            }
          ]
        }
      ]
    }
  }
}
```

<div id="json-mode">
  ### Modo JSON [#modo-json]
</div>

Pasa un formato `changeTracking` con `modes: ["json"]` junto con un esquema JSON (o un `prompt`) que describa los campos que te interesan. Firecrawl extrae ese JSON en cada comprobación y genera un **diff por campo** con claves basadas en la ruta del campo, además de un `snapshot.json` con la extracción actual completa para que los consumidores no tengan que volver a obtener el scraping original.

<CodeGroup>
  <CodeBlockTabs defaultValue="Python" groupId="curl+node+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Node">
        Node
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="cURL">
        cURL
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="Python">
      ```python  
      from firecrawl import Firecrawl
      from pydantic import BaseModel
      from typing import List

      firecrawl = Firecrawl(api_key="fc-YOUR-API-KEY")


      class Plan(BaseModel):
          name: str
          price: str
          features: List[str]


      class Pricing(BaseModel):
          plans: List[Plan]


      monitor = firecrawl.create_monitor(
          name="Pricing monitor",
          schedule={"text": "hourly", "timezone": "UTC"},
          goal="Notify me when a pricing tier, price, or headline feature changes",
          targets=[
              {
                  "type": "scrape",
                  "urls": ["https://example.com/pricing"],
                  "scrapeOptions": {
                      "formats": [
                          {
                              "type": "changeTracking",
                              "modes": ["json"],
                              "prompt": "Extract pricing tiers and headline features for each plan.",
                              "schema": Pricing.model_json_schema(),
                          }
                      ]
                  },
              }
          ],
          notification={
              "email": {
                  "enabled": True,
                  "recipients": ["alerts@example.com"],
                  "includeDiffs": True,
              }
          },
      )

      print(monitor.id)
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Node">
      ```js  
      import Firecrawl from "@mendable/firecrawl-js";
      import { z } from "zod";

      const firecrawl = new Firecrawl({ apiKey: "fc-YOUR-API-KEY" });

      const pricingSchema = z.object({
        plans: z.array(
          z.object({
            name: z.string(),
            price: z.string(),
            features: z.array(z.string()),
          }),
        ),
      });

      const monitor = await firecrawl.createMonitor({
        name: "Pricing monitor",
        schedule: { text: "hourly", timezone: "UTC" },
        goal: "Notify me when a pricing tier, price, or headline feature changes",
        notification: {
          email: {
            enabled: true,
            recipients: ["alerts@example.com"],
            includeDiffs: true,
          },
        },
        targets: [
          {
            type: "scrape",
            urls: ["https://example.com/pricing"],
            scrapeOptions: {
              formats: [
                {
                  type: "changeTracking",
                  modes: ["json"],
                  prompt: "Extract pricing tiers and headline features for each plan.",
                  schema: pricingSchema,
                },
              ],
            },
          },
        ],
      });

      console.log(monitor.id);
      ```
    </CodeBlockTab>

    <CodeBlockTab value="cURL">
      ```bash  
      curl -s -X POST "https://api.firecrawl.dev/v2/monitor" \
        -H "Authorization: Bearer $FIRECRAWL_API_KEY" \
        -H "Content-Type: application/json" \
        -d '{
          "name": "Pricing monitor",
          "schedule": {
            "text": "hourly",
            "timezone": "UTC"
          },
          "goal": "Notify me when a pricing tier, price, or headline feature changes",
          "notification": {
            "email": {
              "enabled": true,
              "recipients": ["alerts@example.com"],
              "includeDiffs": true
            }
          },
          "targets": [
            {
              "type": "scrape",
              "urls": ["https://example.com/pricing"],
              "scrapeOptions": {
                "formats": [
                  {
                    "type": "changeTracking",
                    "modes": ["json"],
                    "prompt": "Extract pricing tiers and headline features for each plan.",
                    "schema": {
                      "type": "object",
                      "properties": {
                        "plans": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": { "type": "string" },
                              "price": { "type": "string" },
                              "features": {
                                "type": "array",
                                "items": { "type": "string" }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                ]
              }
            }
          ]
        }'
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

La carga útil del diff usa rutas JSON dentro de la extracción como claves. Cada valor es un par `{previous, current}`:

```json title="JSON-mode diff"
{
  "diff": {
    "json": {
      "plans[0].price": {
        "previous": "$19/mo",
        "current": "$24/mo"
      },
      "plans[1].features[2]": {
        "previous": "10 GB storage",
        "current": "25 GB storage"
      }
    }
  },
  "snapshot": {
    "json": {
      "plans": [
        {
          "name": "Starter",
          "price": "$24/mo",
          "features": ["Up to 3 users", "Basic analytics", "Email support"]
        },
        {
          "name": "Pro",
          "price": "$49/mo",
          "features": ["Unlimited users", "Advanced analytics", "25 GB storage"]
        }
      ]
    }
  }
}
```

<Note>
  Aunque no cambie ningún campo supervisado, si el markdown circundante sí cambia, los monitores en modo JSON seguirán devolviendo `same` a menos que también habilites git-diff (consulta el modo mixto más abajo). El diff se centra exclusivamente en los campos de tu esquema.
</Note>

<div id="mixed-mode-json-git-diff">
  ### Modo mixto (JSON + git-diff) [#modo-mixto-json--git-diff]
</div>

Si quieres tanto el diff estructurado por campo **como** el diff unificado sin procesar en markdown, indica ambos modos:

```json title="Mixed target (JSON + git-diff)"
{
  "type": "scrape",
  "urls": ["https://example.com/pricing"],
  "scrapeOptions": {
    "formats": [
      {
        "type": "changeTracking",
        "modes": ["json", "git-diff"],
        "prompt": "Extract pricing tiers and headline features for each plan.",
        "schema": {
          "type": "object",
          "properties": {
            "plans": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "name": { "type": "string" },
                  "price": { "type": "string" }
                }
              }
            }
          }
        }
      }
    ]
  }
}
```

La respuesta de comprobación contiene entonces tanto `diff.text` (sidecar de markdown) como `diff.json` (diff por campo), junto con la extracción `snapshot.json`:

```json title="Mixed-mode diff (JSON + git-diff)"
{
  "diff": {
    "text": "--- previous\n+++ current\n@@ -1,3 +1,3 @@\n # Pricing\n-Starter — $19/mo\n+Starter — $24/mo\n",
    "json": {
      "plans[0].price": {
        "previous": "$19/mo",
        "current": "$24/mo"
      }
    }
  },
  "snapshot": {
    "json": {
      "plans": [
        { "name": "Starter", "price": "$24/mo" },
        { "name": "Pro", "price": "$49/mo" }
      ]
    }
  }
}
```

Una página en modo mixto informa `changed` siempre que **cualquiera** de las dos representaciones haya cambiado.

<div id="notifications">
  ## Notificaciones [#notificaciones]
</div>

<div id="webhooks">
  ### Webhooks [#webhooks]
</div>

Cuando un monitor tiene un `webhook`, Firecrawl puede enviar dos eventos del monitor:

* `monitor.page`: Se envía a medida que finaliza cada scraping supervisado en el worker de scraping.
* `monitor.check.completed`: Se envía después de que se consolida la comprobación completa. Incluye el estado de la comprobación y los recuentos de resumen. Usa los eventos `monitor.page` o la API de comprobación del monitor para obtener resultados a nivel de página.

`monitor.page` incluye `isMeaningful` y `judgment` cuando se ejecuta la evaluación de cambios significativos en una página modificada.

```json title="Webhook config"
{
  "webhook": {
    "url": "https://example.com/webhooks/firecrawl",
    "headers": {
      "Authorization": "Bearer your-secret"
    },
    "metadata": {
      "environment": "production"
    },
    "events": ["monitor.page", "monitor.check.completed"]
  }
}
```

Carga útil de `monitor.page`:

```json title="monitor.page"
{
  "success": true,
  "type": "monitor.page",
  "id": "019df960-5f2a-75fb-a98b-bd2d32ca67d4",
  "webhookId": "f1e2d3c4-0000-0000-0000-000000000000",
  "data": [
    {
      "monitorId": "019df960-06e7-7383-9d89-82c0113dc31a",
      "checkId": "019df960-5f2a-75fb-a98b-bd2d32ca67d4",
      "url": "https://example.com/blog",
      "status": "changed",
      "previousScrapeId": "019df94f-82c3-7e41-81f0-00c72b2d9c52",
      "currentScrapeId": "019df960-73ee-7ac2-97a9-fb0e442c21f1",
      "error": null,
      "isMeaningful": true,
      "judgment": {
        "meaningful": true,
        "confidence": "high",
        "reason": "The page headline changed to announce a new release cadence.",
        "meaningfulChanges": [
          {
            "type": "changed",
            "before": "Welcome to our weekly update.",
            "after": "Welcome to our weekly update — now with daily releases!",
            "reason": "The headline changed in a way that matches the monitor goal."
          }
        ]
      },
      "diff": {
        "text": "--- previous\n+++ current\n@@ -1,3 +1,3 @@\n # Latest posts\n-Welcome to our weekly update.\n+Welcome to our weekly update — now with daily releases!\n"
      }
    }
  ],
  "metadata": {
    "environment": "production"
  }
}
```

Carga útil de `monitor.check.completed`:

```json title="monitor.check.completed"
{
  "success": true,
  "type": "monitor.check.completed",
  "id": "019df960-5f2a-75fb-a98b-bd2d32ca67d4",
  "webhookId": "f1e2d3c4-0001-0000-0000-000000000000",
  "data": [
    {
      "monitorId": "019df960-06e7-7383-9d89-82c0113dc31a",
      "checkId": "019df960-5f2a-75fb-a98b-bd2d32ca67d4",
      "status": "completed",
      "summary": {
        "totalPages": 2,
        "same": 1,
        "changed": 1,
        "new": 0,
        "removed": 0,
        "error": 0
      }
    }
  ],
  "metadata": {
    "environment": "production"
  }
}
```

`success` es `true` cuando la comprobación se completa sin errores de página. Es `false` en comprobaciones fallidas o parciales, y `error` contiene el motivo del fallo cuando está disponible.

<div id="email">
  ### Correo electrónico [#correo-electrónico]
</div>

Los resúmenes por correo electrónico se envían solo cuando una comprobación tiene páginas modificadas, nuevas, eliminadas o con errores.

```json title="Email config"
{
  "notification": {
    "email": {
      "enabled": true,
      "recipients": ["alerts@example.com"],
      "includeDiffs": true
    }
  }
}
```

Cuando un monitor tiene un objetivo y la evaluación está habilitada, los resúmenes por correo electrónico priorizan las páginas modificadas relevantes. Si todas las páginas modificadas se consideran ruido y no hay páginas nuevas, eliminadas o con errores, el correo electrónico no se envía.

Si se omite `recipients`, Firecrawl envía correos a los miembros del equipo que pueden recibir correos electrónicos de alerta del sistema.
Puedes configurar hasta 25 destinatarios explícitos.

<div id="recipient-confirmation-process">
  #### Proceso de confirmación del destinatario [#proceso-de-confirmación-del-destinatario]
</div>

Cuando se añade un nuevo destinatario a un monitor, Firecrawl le envía un correo electrónico con un enlace de confirmación. Así se garantiza que acepta explícitamente recibir notificaciones de ese monitor. Si el destinatario ya es miembro del equipo, no hace falta confirmación.

<div id="slack">
  ### Slack [#slack]
</div>

También puedes hacer que las notificaciones del monitor se envíen a un canal de Slack.

<Note>
  Las notificaciones de Slack solo están disponibles en el dashboard. Solo se pueden configurar desde el [dashboard de monitoreo](https://www.firecrawl.dev/app/monitoring), no a través de la API ni de los SDKs.
</Note>

Para configurar las notificaciones de Slack:

1. Abre el [dashboard de monitoreo](https://www.firecrawl.dev/app/monitoring). Puedes añadir notificaciones de Slack mientras creas un monitor nuevo o añadirlas a un monitor que ya existe.
2. Durante la creación del monitor, o una vez que hayas seleccionado uno existente, desplázate hasta **Notificación** y selecciona **Slack**.
3. Se te pedirá que continúes con OAuth. Completa el flujo y selecciona el espacio de trabajo y el canal donde quieres recibir las notificaciones.

<div id="check-results">
  ## Resultados de comprobaciones [#resultados-de-comprobaciones]
</div>

Usa `GET /v2/monitor/{monitorId}/checks` para listar comprobaciones y `GET /v2/monitor/{monitorId}/checks/{checkId}` para inspeccionar una comprobación. Los SDKs aplican paginación automática de forma predeterminada.

<CodeGroup>
  <CodeBlockTabs defaultValue="Python" groupId="curl+node+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Node">
        Node
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="cURL">
        cURL
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="Python">
      ```python  
      from firecrawl import Firecrawl

      firecrawl = Firecrawl(api_key="fc-YOUR-API-KEY")

      check = firecrawl.get_monitor_check(monitor_id, check_id, limit=25, status="changed")

      for page in check.pages:
          print(page.url, page.status)

          if page.judgment:
              print(page.judgment.meaningful, page.judgment.reason)

          if page.diff and page.diff.text:
              print(page.diff.text)

          if page.snapshot and page.snapshot.json:
              print(page.snapshot.json)
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Node">
      ```js  
      import Firecrawl from "@mendable/firecrawl-js";

      const firecrawl = new Firecrawl({ apiKey: "fc-YOUR-API-KEY" });

      const check = await firecrawl.getMonitorCheck(monitorId, checkId, {
        limit: 25,
        status: "changed",
      });

      for (const page of check.pages) {
        console.log(page.url, page.status);

        if (page.judgment) {
          console.log(page.judgment.meaningful, page.judgment.reason);
        }

        if (page.diff?.text) {
          console.log(page.diff.text);
        }

        if (page.snapshot?.json) {
          console.log(page.snapshot.json);
        }
      }
      ```
    </CodeBlockTab>

    <CodeBlockTab value="cURL">
      ```bash  
      curl "https://api.firecrawl.dev/v2/monitor/$MONITOR_ID/checks/$CHECK_ID?limit=25&status=changed" \
        -H "Authorization: Bearer $FIRECRAWL_API_KEY"
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

La lista de comprobaciones se puede filtrar por el `status` de la comprobación: `queued`, `running`, `completed`, `failed`, `partial` o `skipped_overlap`.

La respuesta de detalle de la comprobación incluye `estimatedCredits`, `actualCredits`, conteos resumidos y un array paginado de `pages`. `estimatedCredits` es la reserva máxima para la comprobación; `actualCredits` es el importe final cobrado una vez que Firecrawl sabe cuántas páginas cambiaron y requirieron evaluación. Usa la URL `next` de nivel superior para obtener la siguiente página de resultados, igual que en la paginación del rastreo. Puedes filtrar páginas por `status`: `same`, `new`, `changed`, `removed` o `error`. Cada página modificada incluye datos `diff` integrados; las páginas de monitores en modo JSON también incluyen un `snapshot` con la extracción actual.

<Tabs>
  <Tab title="Modo Markdown">
    ```json title="Markdown-mode response"
    {
      "success": true,
      "next": "https://api.firecrawl.dev/v2/monitor/019df960-06e7-7383-9d89-82c0113dc31a/checks/019df960-5f2a-75fb-a98b-bd2d32ca67d4?skip=25&limit=25",
      "data": {
        "id": "019df960-5f2a-75fb-a98b-bd2d32ca67d4",
        "monitorId": "019df960-06e7-7383-9d89-82c0113dc31a",
        "status": "completed",
        "estimatedCredits": 2,
        "actualCredits": 2,
        "summary": {
          "totalPages": 1,
          "same": 0,
          "changed": 1,
          "new": 0,
          "removed": 0,
          "error": 0
        },
        "pages": [
          {
            "id": "019df960-7708-7c62-a5dc-6206f16ac122",
            "targetId": "019df960-09bb-7c11-8001-1f12f50ab1c2",
            "url": "https://example.com/blog",
            "status": "changed",
            "previousScrapeId": "019df94f-82c3-7e41-81f0-00c72b2d9c52",
            "currentScrapeId": "019df960-73ee-7ac2-97a9-fb0e442c21f1",
            "statusCode": 200,
            "error": null,
            "metadata": {
              "title": "Example Blog",
              "creditsUsed": 1
            },
            "judgment": {
              "meaningful": true,
              "confidence": "high",
              "reason": "The page headline changed to announce a new release cadence.",
              "meaningfulChanges": [
                {
                  "type": "changed",
                  "before": "Welcome to our weekly update.",
                  "after": "Welcome to our weekly update — now with daily releases!",
                  "reason": "The headline changed in a way that matches the monitor goal."
                }
              ]
            },
            "createdAt": "2026-05-17T15:35:00.000Z",
            "diff": {
              "text": "--- previous\n+++ current\n@@ -1,3 +1,3 @@\n # Latest posts\n-Welcome to our weekly update.\n+Welcome to our weekly update — now with daily releases!\n",
              "json": {
                "files": [
                  {
                    "from": "previous",
                    "to": "current",
                    "chunks": []
                  }
                ]
              }
            }
          }
        ],
        "next": "https://api.firecrawl.dev/v2/monitor/019df960-06e7-7383-9d89-82c0113dc31a/checks/019df960-5f2a-75fb-a98b-bd2d32ca67d4?skip=25&limit=25"
      }
    }
    ```
  </Tab>

  <Tab title="Modo JSON">
    ```json title="JSON-mode response"
    {
      "success": true,
      "data": {
        "id": "019df960-5f2a-75fb-a98b-bd2d32ca67d4",
        "monitorId": "019df960-06e7-7383-9d89-82c0113dc31a",
        "status": "completed",
        "estimatedCredits": 2,
        "actualCredits": 2,
        "summary": {
          "totalPages": 1,
          "same": 0,
          "changed": 1,
          "new": 0,
          "removed": 0,
          "error": 0
        },
        "pages": [
          {
            "id": "019df960-7708-7c62-a5dc-6206f16ac122",
            "targetId": "019df960-09bb-7c11-8001-1f12f50ab1c2",
            "url": "https://example.com/pricing",
            "status": "changed",
            "previousScrapeId": "019df94f-82c3-7e41-81f0-00c72b2d9c52",
            "currentScrapeId": "019df960-73ee-7ac2-97a9-fb0e442c21f1",
            "statusCode": 200,
            "error": null,
            "metadata": {
              "title": "Pricing",
              "creditsUsed": 1
            },
            "judgment": {
              "meaningful": true,
              "confidence": "high",
              "reason": "The Starter plan price and Pro storage limit changed.",
              "meaningfulChanges": [
                {
                  "type": "changed",
                  "before": "$19/mo",
                  "after": "$24/mo",
                  "reason": "The Starter plan price changed."
                },
                {
                  "type": "changed",
                  "before": "10 GB storage",
                  "after": "25 GB storage",
                  "reason": "The Pro storage limit changed."
                }
              ]
            },
            "createdAt": "2026-05-17T15:35:00.000Z",
            "diff": {
              "json": {
                "plans[0].price": {
                  "previous": "$19/mo",
                  "current": "$24/mo"
                },
                "plans[1].features[2]": {
                  "previous": "10 GB storage",
                  "current": "25 GB storage"
                }
              }
            },
            "snapshot": {
              "json": {
                "plans": [
                  {
                    "name": "Starter",
                    "price": "$24/mo",
                    "features": ["Up to 3 users", "Basic analytics", "Email support"]
                  },
                  {
                    "name": "Pro",
                    "price": "$49/mo",
                    "features": ["Unlimited users", "Advanced analytics", "25 GB storage"]
                  }
                ]
              }
            }
          }
        ]
      }
    }
    ```
  </Tab>

  <Tab title="Modo mixto">
    ```json title="Mixed-mode response (JSON + git-diff)"
    {
      "success": true,
      "data": {
        "id": "019df960-5f2a-75fb-a98b-bd2d32ca67d4",
        "monitorId": "019df960-06e7-7383-9d89-82c0113dc31a",
        "status": "completed",
        "estimatedCredits": 2,
        "actualCredits": 2,
        "summary": {
          "totalPages": 1,
          "same": 0,
          "changed": 1,
          "new": 0,
          "removed": 0,
          "error": 0
        },
        "pages": [
          {
            "id": "019df960-7708-7c62-a5dc-6206f16ac122",
            "targetId": "019df960-09bb-7c11-8001-1f12f50ab1c2",
            "url": "https://example.com/pricing",
            "status": "changed",
            "previousScrapeId": "019df94f-82c3-7e41-81f0-00c72b2d9c52",
            "currentScrapeId": "019df960-73ee-7ac2-97a9-fb0e442c21f1",
            "statusCode": 200,
            "error": null,
            "metadata": {
              "title": "Pricing",
              "creditsUsed": 1
            },
            "judgment": {
              "meaningful": true,
              "confidence": "high",
              "reason": "The Starter plan price changed.",
              "meaningfulChanges": [
                {
                  "type": "changed",
                  "before": "Starter — $19/mo",
                  "after": "Starter — $24/mo",
                  "reason": "The Starter plan price changed."
                }
              ]
            },
            "createdAt": "2026-05-17T15:35:00.000Z",
            "diff": {
              "text": "--- previous\n+++ current\n@@ -1,3 +1,3 @@\n # Pricing\n-Starter — $19/mo\n+Starter — $24/mo\n",
              "json": {
                "plans[0].price": {
                  "previous": "$19/mo",
                  "current": "$24/mo"
                }
              }
            },
            "snapshot": {
              "json": {
                "plans": [
                  { "name": "Starter", "price": "$24/mo" },
                  { "name": "Pro", "price": "$49/mo" }
                ]
              }
            }
          }
        ]
      }
    }
    ```
  </Tab>
</Tabs>

<div id="pricing">
  ## Precios [#precios]
</div>

Los monitores no tienen una tarifa adicional por monitor. Cada comprobación consume los créditos del scraping, rastreo o búsqueda subyacentes que realiza, más un crédito opcional por cada página modificada cuando está habilitada la evaluación de cambios significativos.

| Componente                                                         | Créditos                                                                                                                        |
| ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
| Monitor de scraping                                                | 1 crédito por URL por comprobación                                                                                              |
| Monitor de rastreo                                                 | 1 crédito por página descubierta por comprobación                                                                               |
| Monitor web                                                        | 2 créditos por cada 10 resultados por comprobación                                                                              |
| Evaluación del monitor web                                         | 1 crédito por resultado evaluado, cuando la evaluación con IA está habilitada (cubre el scraping y la evaluación del resultado) |
| Evaluación de cambios significativos habilitada                    | 1 crédito adicional por cada página modificada que valide el evaluador                                                          |
| Complementos de formato (JSON, PDF, question, enhanced mode, etc.) | Igual que el [scraping](/es/features/scrape) independiente                                                                      |

<div id="api-reference">
  ## Referencia de la API [#referencia-de-la-api]
</div>

* [Crear monitor](/es/api-reference/endpoint/monitor-create)
* [Listar monitores](/es/api-reference/endpoint/monitor-list)
* [Obtener monitor](/es/api-reference/endpoint/monitor-get)
* [Actualizar monitor](/es/api-reference/endpoint/monitor-update)
* [Eliminar monitor](/es/api-reference/endpoint/monitor-delete)
* [Ejecutar monitor](/es/api-reference/endpoint/monitor-run)
* [Listar comprobaciones del monitor](/es/api-reference/endpoint/monitor-checks-list)
* [Obtener una comprobación del monitor](/es/api-reference/endpoint/monitor-check-get)
* [Carga útil del webhook de la página del monitor](/es/api-reference/endpoint/webhook-monitor-page)
* [Carga útil del webhook de comprobación completada del monitor](/es/api-reference/endpoint/webhook-monitor-check-completed)
