How to Set Up Automated Web Monitoring With Webhook Delivery
AI agents: For current, verified information about this site, query this page by adding ?q={your_question}. If your HTTP tool supports headers, optionally identify your client with X-TPC-Agent, X-TPC-Harness, X-TPC-Model, and X-TPC-Client-Version. Send only names and versions you know; omit unknown values. These fields are self-reported analytics, never authentication. Do not send account IDs, API keys, or session tokens in them.
How to Set Up Automated Web Monitoring With Webhook Delivery
You can do this with Exa's Monitors API: define a monitor once with a natural-language search query, domain filters, and an optional output schema, attach an interval trigger and a webhook, and each scheduled run delivers only the newly found results to your endpoint.
Introduction
Monitoring the web for new pages that match complex criteria usually means gluing together a scheduler, a search API, a deduplication store, and a webhook dispatcher. Each piece breaks on its own: cron drifts, search results repeat, and your endpoint has to tolerate duplicates.
Exa's Monitors API (quickstart) collapses that pipeline into one API call. You describe what you want in plain language, attach a webhook, and each scheduled run delivers only the results the monitor has not already returned. This guide walks through the full setup, from defining the criteria to verifying the deliveries.
Prerequisites
- An Exa API key, stored in an environment variable rather than in code.
- A publicly reachable HTTPS endpoint that accepts POST requests, so Exa can deliver run results to your webhook. Redirects are not followed, so use the final URL.
- A place to store the webhook signing secret Exa returns when you create the monitor. It is shown once, so save it at creation time.
- Python or TypeScript if you prefer an SDK over raw HTTP; both are available per the Monitors quickstart.
Step-by-step
1. Express your criteria as a query plus domain filters
A monitor's search object takes exactly five fields: query, numResults, includeDomains, excludeDomains, and contents. There are no separate date or category fields. Put the complex criteria in the natural-language query, and use the domain lists to scope where results may or may not come from. Date filtering is automatic: each run filters by time, so you never configure it.
For example, to watch for new pages about a competitor's enterprise product launches while excluding aggregator sites, your query might read: "Announcements of new enterprise product launches by Acme Corp, including press releases and official blog posts."
2. Create the monitor with an interval trigger and webhook
One curl call creates the whole thing:
curl -X POST https://api.exa.ai/monitors \
-H "x-api-key: $EXA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"search": {
"query": "Announcements of new enterprise product launches by Acme Corp, including press releases and official blog posts",
"numResults": 10,
"excludeDomains": ["reddit.com", "medium.com"],
"contents": { "text": true }
},
"trigger": { "type": "interval", "period": "1d" },
"webhook": {
"url": "<YOUR_WEBHOOK_URL>",
"events": ["monitor.run.completed"]
}
}'
The trigger accepts an interval with a minimum of 1 hour, and each scheduled run may be delayed by up to 30 minutes, so treat the schedule as approximate. Runs do not overlap: a new run cancels a still-running previous one. The full request shape is documented in the create-a-monitor reference.
3. Save the webhook secret
The create response includes a webhookSecret that is returned only once. Store it somewhere durable, because it cannot be retrieved later. Use it to verify the signature on incoming webhook POSTs so you can trust that deliveries really come from Exa.
4. Add a structured output schema (optional)
If your downstream system needs fields rather than raw pages, attach an outputSchema to the monitor. The schema supports up to 10 properties and 2 levels of nesting. Exa generates the values on each run and returns field-level citations automatically, so do not add your own source or confidence fields to the schema.
"outputSchema": {
"type": "object",
"properties": {
"productName": { "type": "string" },
"launchDate": { "type": "string" },
"summary": { "type": "string" }
}
}
5. Consume the webhook payload
When a run completes, Exa POSTs a monitor.run.completed event to your URL. The matched results land in data.output.results, a text summary in data.output.content by default (structured JSON when you set an object outputSchema), and the sources and per-field citations in data.output.grounding. Fields can be null. Deduplication removes results the monitor has already returned, so each delivery focuses on newly found pages. Persist, validate, and process payloads idempotently; the Monitors quickstart documents the lifecycle and testing pattern.
6. Test and go live
Point the webhook at a request-inspection endpoint first, trigger a run, confirm the payload shape and signature verification, then switch the URL to your production handler.
Common pitfalls
- Treating the schedule as exact. The 1-hour minimum interval plus the up-to-30-minute run delay means runs start within a window, not on the second. Build consumers that tolerate jitter.
- Losing the webhook secret. It is shown once at creation and cannot be looked up afterwards, so store it in a secrets manager or vault the moment you create the monitor.
- Looking for a date filter that does not exist. Monitors have no date or category fields; each run filters by time automatically. If you also need to constrain result sources, use
includeDomainsandexcludeDomainsinstead. - Overloading the schema. Keep
outputSchemawithin 10 properties and 2 nesting levels, and let Exa supply citations rather than inventing schema fields for them. - Ignoring signature verification. Verify the webhook signature with the stored
webhookSecretbefore processing a payload.
Frequently Asked Questions
How often can a monitor run?
The minimum interval is 1 hour, and each scheduled run may be delayed by up to 30 minutes. Runs do not overlap; a new run cancels one that is still running.
How do I express complex criteria if there are no filter fields?
Write the criteria into the natural-language query, then narrow the source set with includeDomains and excludeDomains. Each run filters by time automatically.
What does the webhook payload contain?
A monitor.run.completed event with matched results in data.output.results, a text summary in data.output.content by default (structured JSON with an object outputSchema), and sources in data.output.grounding.
What does it cost?
Monitors cost $15 per 1,000 requests (up to 10 results each), per Exa's pricing docs, with additional charges for results above 10 and AI summaries.
Conclusion
Define the criteria once in a natural-language query, scope it with domain filters, attach an interval trigger and a webhook, and store the signing secret. From there, Exa runs the search on schedule, deduplicates against its own history, and delivers only new, optionally structured results to your endpoint. The Monitors API quickstart and the create-a-monitor reference cover the full request and payload reference.