> ## Documentation Index
> Fetch the complete documentation index at: https://exa.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Monitors

> Schedule recurring Exa searches and get results delivered to your webhook.

<div className="callout-box not-prose">
  <p className="callout-title">Just want working code?</p>

  <p className="callout-body">
    Stop reading. Skip to the [Monitors coding agent reference](/reference/monitors-api-guide-for-coding-agents)
    and copy paste to your agent.
  </p>
</div>

## What Are Monitors?

Monitors run Exa searches on a recurring schedule and deliver results to a webhook endpoint. Each run finds and synthesizes results, with automatic deduplication so you only see new content across runs.

Use them to track competitor announcements, new funding rounds, regulatory changes, research publications, or any topic you want to follow over time.

## Key Capabilities

| Feature                     | What It Does                                                                         |
| --------------------------- | ------------------------------------------------------------------------------------ |
| **Scheduled search**        | Runs your query on a recurring interval anchored to when the monitor was created     |
| **Automatic deduplication** | Date filtering and semantic dedup ensure each run surfaces only new content          |
| **Structured output**       | Use `outputSchema` to get results as plain text summaries or structured JSON objects |
| **Contents options**        | Request text, highlights, or summaries alongside search results                      |
| **Webhook delivery**        | Get notified in real time when runs complete                                         |
| **Manual trigger**          | Run on demand without waiting for the next scheduled time                            |

## Common Use Cases

<Accordion title="Track funding announcements">
  Get notified when new companies raise funding in a specific sector.

  <Tabs>
    <Tab title="Python">
      ```python theme={null}
      monitor = exa.monitors.create(params={
          "name": "Series A Tracker",
          "search": {
              "query": "AI startups that raised Series A funding",
              "numResults": 10
          },
          "trigger": {
              "type": "interval",
              "period": "7d"
          },
          "webhook": {
              "url": "https://example.com/webhook"
          }
      })
      ```
    </Tab>

    <Tab title="JavaScript">
      ```javascript theme={null}
      const monitor = await exa.monitors.create({
        name: "Series A Tracker",
        search: {
          query: "AI startups that raised Series A funding",
          numResults: 10
        },
        trigger: {
          type: "interval",
          period: "7d"
        },
        webhook: {
          url: "https://example.com/webhook"
        }
      });
      ```
    </Tab>
  </Tabs>
</Accordion>

<Accordion title="Monitor competitor news with structured output">
  Extract structured data from competitor coverage using an output schema.

  <Tabs>
    <Tab title="Python">
      ```python theme={null}
      monitor = exa.monitors.create(params={
          "name": "Competitor News",
          "search": {
              "query": "Acme Corp product launches and partnerships",
              "numResults": 5
          },
          "outputSchema": {
              "type": "object",
              "properties": {
                  "headline": {"type": "string"},
                  "category": {
                      "type": "string",
                      "enum": ["product_launch", "partnership", "hiring", "other"]
                  },
                  "summary": {"type": "string"}
              },
              "required": ["headline", "category", "summary"]
          },
          "trigger": {
              "type": "interval",
              "period": "1d"
          },
          "webhook": {
              "url": "https://example.com/webhook"
          }
      })
      ```
    </Tab>

    <Tab title="JavaScript">
      ```javascript theme={null}
      const monitor = await exa.monitors.create({
        name: "Competitor News",
        search: {
          query: "Acme Corp product launches and partnerships",
          numResults: 5
        },
        outputSchema: {
          type: "object",
          properties: {
            headline: { type: "string" },
            category: {
              type: "string",
              enum: ["product_launch", "partnership", "hiring", "other"]
            },
            summary: { type: "string" }
          },
          required: ["headline", "category", "summary"]
        },
        trigger: {
          type: "interval",
          period: "1d"
        },
        webhook: {
          url: "https://example.com/webhook"
        }
      });
      ```
    </Tab>
  </Tabs>
</Accordion>

<Accordion title="Track research papers with highlights">
  Follow new publications in a field, with token-efficient highlights included.

  <Tabs>
    <Tab title="Python">
      ```python theme={null}
      monitor = exa.monitors.create(params={
          "name": "LLM Research Tracker",
          "search": {
              "query": "new large language model training techniques and architectures",
              "numResults": 10,
              "contents": {
                  "highlights": True
              }
          },
          "trigger": {
              "type": "interval",
              "period": "7d"
          },
          "webhook": {
              "url": "https://example.com/webhook"
          }
      })
      ```
    </Tab>

    <Tab title="JavaScript">
      ```javascript theme={null}
      const monitor = await exa.monitors.create({
        name: "LLM Research Tracker",
        search: {
          query: "new large language model training techniques and architectures",
          numResults: 10,
          contents: {
            highlights: true
          }
        },
        trigger: {
          type: "interval",
          period: "7d"
        },
        webhook: {
          url: "https://example.com/webhook"
        }
      });
      ```
    </Tab>
  </Tabs>
</Accordion>

## Human Quickstart

Get your API key from the [Exa Dashboard](https://dashboard.exa.ai/api-keys).

<Tabs>
  <Tab title="Python">
    ```bash theme={null}
    pip install exa-py
    ```

    ```python theme={null}
    from exa_py import Exa
    import os

    exa = Exa(os.getenv("EXA_API_KEY"))

    # Create a monitor that runs daily anchored at creation time
    monitor = exa.monitors.create(params={
        "name": "AI Funding Tracker",
        "search": {
            "query": "AI startups that raised Series A funding",
            "numResults": 10
        },
        "trigger": {
          "type": "interval",
          "period": "1d"
        },
        "webhook": {
            "url": "https://example.com/webhook"
        }
    })

    print(f"Monitor ID: {monitor.id}")

    # Store the webhook secret securely — only returned on creation
    print(f"Webhook secret: {monitor.webhook_secret}")

    # Trigger a run manually
    exa.monitors.trigger(monitor.id)

    # Poll for results
    import time
    while True:
        runs = exa.monitors.runs.list(monitor.id)
        latest = runs.data[0]
        if latest.status in ("completed", "failed"):
            break
        time.sleep(2)

    # Print results
    if latest.status == "completed" and latest.output:
        run = exa.monitors.runs.get(monitor.id, latest.id)
        for result in run.output.results:
            print(f"- {result['title']}: {result['url']}")
    ```
  </Tab>

  <Tab title="JavaScript">
    ```bash theme={null}
    npm install exa-js
    ```

    ```javascript theme={null}
    import Exa from "exa-js";

    const exa = new Exa(process.env.EXA_API_KEY);

    // Create a monitor that runs daily anchored at creation time
    const monitor = await exa.monitors.create({
      name: "AI Funding Tracker",
      search: {
        query: "AI startups that raised Series A funding",
        numResults: 10
      },
      trigger: {
        type: "interval",
        period: "1d"
      },
      webhook: {
        url: "https://example.com/webhook"
      }
    });

    console.log(`Monitor ID: ${monitor.id}`);

    // Store the webhook secret securely — only returned on creation
    console.log(`Webhook secret: ${monitor.webhookSecret}`);

    // Trigger a run manually
    await exa.monitors.trigger(monitor.id);

    // Poll for results
    let latest;
    while (true) {
      const runs = await exa.monitors.runs.list(monitor.id);
      latest = runs.data[0];
      if (latest.status === "completed" || latest.status === "failed") break;
      await new Promise(r => setTimeout(r, 2000));
    }

    // Print results
    if (latest.status === "completed" && latest.output) {
      const run = await exa.monitors.runs.get(monitor.id, latest.id);
      for (const result of run.output.results) {
        console.log(`- ${result.title}: ${result.url}`);
      }
    }
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    # Create a monitor that runs daily anchored at creation time
    curl -X POST "https://api.exa.ai/monitors" \
      -H "Content-Type: application/json" \
      -H "x-api-key: $EXA_API_KEY" \
      -d '{
        "name": "AI Funding Tracker",
        "search": {
          "query": "AI startups that raised Series A funding",
          "numResults": 10
        },
        "trigger": {
          "type": "interval",
          "period": "1d"
        },
        "webhook": {
          "url": "https://example.com/webhook"
        }
      }'

    # Trigger a run
    curl -X POST "https://api.exa.ai/monitors/{MONITOR_ID}/trigger" \
      -H "x-api-key: $EXA_API_KEY"

    # List runs
    curl "https://api.exa.ai/monitors/{MONITOR_ID}/runs" \
      -H "x-api-key: $EXA_API_KEY"

    # Get a specific run
    curl "https://api.exa.ai/monitors/{MONITOR_ID}/runs/{RUN_ID}" \
      -H "x-api-key: $EXA_API_KEY"
    ```
  </Tab>
</Tabs>

## Slack Routing Pattern

Monitor `metadata` can be echoed in webhook deliveries and used to route updates back into the right channel or thread.

```json theme={null}
{
  "name": "Competitor Launches",
  "search": {
    "query": "New product launches by Acme competitors"
  },
  "metadata": {
    "slack_channel_id": "C123ABC",
    "slack_thread_id": "1745444400.123456",
    "user_id": "U123ABC"
  },
  "webhook": {
    "url": "https://example.com/exa-monitor-webhook",
    "events": ["monitor.run.completed"]
  }
}
```

When the run webhook fires, Exa echoes that metadata back in the payload, including the Slack routing fields.

## Next

* [**Monitors coding agent reference**](/reference/monitors-api-guide-for-coding-agents) — Full parameter reference for coding agents
* [**Monitors API Reference**](/reference/monitors/create-a-monitor) — Interactive API reference with request/response schemas
* [**Search API**](/reference/search-api-guide) — Learn about Exa's search capabilities
* [**Search Best Practices**](/reference/search-best-practices) — Tips for writing effective queries
