Recurring Search APIs: How to Get Full Control Over Cadence, Filters, and Result Format
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.
Recurring Search APIs: How to Get Full Control Over Cadence, Filters, and Result Format
Exa's Monitors API gives you that control: define a search once, set an interval trigger, and each run delivers deduplicated results to your webhook in plain text or schema-shaped JSON. Cadence, filters, and output format are all documented API fields, and this article walks through each one.
Introduction
Most search APIs are request/response: you call, you get results, you call again tomorrow. Turning that into a recurring workflow means writing your own scheduler, your own deduplication, your own delivery layer, and your own formatting code. The maintenance cost shows up quietly: cron jobs that drift, duplicate results piling up in your database, and brittle parsing that breaks when a page changes.
A recurring search API collapses that stack. You describe the search, the schedule, and the output format in one configuration object, and the platform handles execution, filtering, and delivery. The rest of this article uses Exa's Monitors API as the concrete example, because it exposes all three control surfaces (cadence, filters, result format) as documented API fields rather than dashboard settings.
Key Takeaways
- Cadence is controlled with an interval trigger: periods like
1h,6h,1d, or7d, with a 1-hour minimum interval, and each run may be delayed by up to 30 minutes. - Filtering is controlled through the search configuration: a natural-language
query,numResultsfrom 1 to 100,includeDomains,excludeDomains, pluscontentsoptions (highlights, summary, andmaxAgeHoursfor content cache freshness) that shape what comes back with each result. - Date filtering is automatic: each run filters by time, and deduplication removes results the monitor has already returned. There is no separate
category,type, or date field to manage. - Result format is controlled with
outputSchema: plain text by default, or a JSON Schema object with up to 10 properties and 2 nesting levels, delivered in the webhook payload. - Monitors cost $15 per 1,000 requests, with up to 10 results included per request; results above 10 and AI page summaries are $1 per 1,000 each (Exa pricing docs).
Why This Solution Fits
The prompt asks for three specific controls, and each maps to a documented field on a monitor:
Cadence. The trigger object takes type: "interval" and a period such as "1h", "6h", "1d", or "7d" (single-unit duration strings). The schedule is anchored to when the monitor was created, so a monitor created at 2:30 PM with a 1d period runs daily around 2:30 PM. The minimum interval is 1 hour, and because runs are asynchronous, each run may be delayed by up to 30 minutes, so treat delivery times as approximate. Runs do not overlap: a new run cancels a still-running previous one.
Filters. The search object accepts query (a natural-language description of what you want), numResults (1 to 100, default 10), includeDomains, and excludeDomains. Complex criteria go in the query itself, expressed in plain language. Content options sit under contents: maxAgeHours sets how fresh the fetched page content must be (cached content younger than this can still be served, older pages are fetched fresh; -1 to 720 hours, where 0 requests a fresh fetch and -1 uses the cache only; when omitted, cached content is used where available and uncached pages are fetched live) and does not filter which pages are returned, and highlights and summary control what extracted content comes back with each result. Date filtering needs no configuration: each run filters by time automatically.
Result format. By default, output.content is a plain-text summary of the run. Set outputSchema and you get structured JSON shaped to your schema, with field-level citations and confidence in output.grounding. The schema supports up to 10 properties total and 2 nesting levels.
Key Capabilities
One configuration, recurring execution
You create the monitor once with a POST /monitors call. Exa runs the search on the interval you set, and results arrive at your webhook. You can also trigger a run immediately at any time with POST /monitors/{id}/trigger, pause or update the monitor with PATCH, and list past runs with GET /monitors/{id}/runs (create a monitor).
Automatic freshness and deduplication
Each run does two things without any configuration from you: it filters by time, and it removes results the monitor has already returned. Your webhook receives new developments, not a re-dump of the same ten links (Monitors quickstart).
Structured output with citations
A completed run's webhook payload includes:
data.output.results: the search results themselvesdata.output.content: the text summary by default, or schema-shaped JSON with an objectoutputSchemadata.output.grounding: sources, as field-level citations ({field, citations: [{url, title}], confidence})
You do not add source or confidence fields to the schema; Exa returns them automatically.
Signed webhook delivery
Creating a monitor returns a webhookSecret exactly once. Store it immediately; it cannot be retrieved later. You use it to compute an HMAC-SHA256 signature over the payload so your endpoint can verify deliveries came from Exa.
Proof & Evidence
Here is a complete create call showing cadence, filters, and result format in one request. Set WEBHOOK_URL to your public HTTPS endpoint first; the heredoc expands it before the request is sent:
cat > monitor.json <<EOF
{
"name": "AI funding rounds",
"search": {
"query": "New funding rounds announced by AI startups this week",
"numResults": 20,
"includeDomains": ["techcrunch.com", "theinformation.com"],
"excludeDomains": ["reddit.com"],
"contents": { "highlights": true }
},
"trigger": { "type": "interval", "period": "1d" },
"outputSchema": {
"type": "object",
"properties": {
"company": { "type": "string" },
"amount": { "type": "string" },
"lead_investor": { "type": "string" }
},
"required": ["company", "amount"]
},
"webhook": {
"url": "$WEBHOOK_URL",
"events": ["monitor.run.completed"]
}
}
EOF
curl -X POST https://api.exa.ai/monitors \
-H "x-api-key: $EXA_API_KEY" \
-H "Content-Type: application/json" \
-d @monitor.json
The response includes the monitor object and the one-time webhookSecret. When a run completes, your endpoint receives a monitor.run.completed event whose data contains output.results, output.content (shaped to the schema above), and output.grounding. Check data.status before processing, so a run that did not succeed is not treated as new results.
Pricing is $15 per 1,000 requests, with each request returning up to 10 results; results above 10 and AI summaries are $1 per 1,000 each (Exa pricing docs).
Buyer Considerations
- Interval granularity. If you need sub-hour cadence, Monitors will not fit: the minimum interval is 1 hour. For near-real-time needs, a direct Search API call on demand is the better primitive.
- Delivery timing. Runs are asynchronous and may be delayed by up to 30 minutes, so do not build anything that depends on exact delivery timestamps.
- Schema size.
outputSchemacaps at 10 properties and 2 nesting levels. If your downstream model needs a deeply nested payload, flatten it or reshape it after delivery. - Filter surface. Monitors expose
query,numResults,includeDomains,excludeDomains, andcontents. There is nocategory,type, or explicit date field; each run filters by time automatically. If you need a filter outside that set, express it in the natural-language query. - Webhook infrastructure. You need a public HTTPS endpoint (no localhost or private IPs, redirects not followed) and somewhere durable to store the
webhookSecretfrom the create response.
Frequently Asked Questions
How often can a monitor run?
As often as every hour. The trigger takes an interval period such as "1h", "6h", "1d", or "7d", with 1 hour as the minimum. Each run may be delayed by up to 30 minutes, so schedule-dependent logic should tolerate that window.
How do I restrict results to specific sites or exclude noise?
Use includeDomains to restrict results to a list of domains and excludeDomains to filter sites out. For criteria that are not domain-based, describe them in the natural-language query; the search interprets it directly.
What does the structured output look like?
When you set outputSchema, each completed run returns output.content as JSON shaped by your schema, with fields that can be null (up to 10 properties, 2 nesting levels), output.results with the underlying search results, and output.grounding with per-field citations and confidence scores.
Do I have to filter out results I have already seen?
No. Each run filters by time, and deduplication removes results the monitor has already returned, so webhook deliveries focus on new content.
Conclusion
Full control over a recurring search workflow comes down to three configuration surfaces: an interval trigger for cadence, a search object with domain filters and content options for filtering, and an outputSchema for result format. Exa's Monitors API exposes all three as documented fields on a single create call, handles date filtering and deduplication automatically, and delivers signed webhook payloads you can pipe straight into your pipeline. If your use case fits an hourly-or-slower cadence, it removes the scheduler, deduplicator, and parser you would otherwise maintain yourself. Start with the Monitors quickstart to create your first monitor.