openapi: 3.1.0
info:
title: Exa Agent Monitors API
version: 2.0.0
description: Exa Agent API - subset of the Exa Public API.
servers:
- url: https://api.exa.ai
security:
- apiKey: []
- bearer: []
tags:
- name: Monitors
paths:
/monitors:
post:
operationId: createMonitor
summary: Create a Monitor
description: 'Creates a new Monitor to run recurring Exa searches on a schedule.
Monitors automatically execute your search query on a recurring schedule and deliver results to your webhook endpoint with automatic deduplication:
- **Date-based filtering** only fetches content since the last run
- **Semantic deduplication** tracks previous outputs to surface only new developments
The response includes a `webhookSecret` that is only returned once at creation time. Store it securely for webhook signature verification.'
tags:
- Monitors
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateSearchMonitorParameters'
responses:
'201':
description: The created monitor with webhook secret
content:
application/json:
schema:
$ref: '#/components/schemas/CreateSearchMonitorResponse'
get:
operationId: listMonitors
summary: List Monitors
description: Lists all monitors for the authenticated team. Supports filtering by status and cursor-based pagination.
tags:
- Monitors
parameters:
- in: query
name: status
schema:
type: string
enum:
- active
- paused
- disabled
description: Filter monitors by status
- in: query
name: cursor
schema:
type: string
description: Pagination cursor from a previous response
- in: query
name: limit
schema:
type: integer
minimum: 1
maximum: 100
description: Number of results per page
default: 50
- in: query
name: name
schema:
type: string
maxLength: 250
description: Filter monitors by name (case-insensitive substring match)
- in: query
name: metadata
schema:
description: 'Filter monitors by metadata key-value pairs (exact match, AND semantics). Use bracket notation: `metadata[key]=value`.'
type: object
propertyNames:
type: string
additionalProperties:
type: string
style: deepObject
explode: true
description: 'Filter monitors by metadata key-value pairs (exact match, AND semantics). Use bracket notation: `metadata[key]=value`.'
responses:
'200':
description: A paginated list of monitors
content:
application/json:
schema:
$ref: '#/components/schemas/ListSearchMonitorsResponse'
/monitors/batch:
post:
operationId: batchMonitors
summary: Batch Action on Monitors
description: 'Perform a batch action on monitors matching the provided filters.
Supported actions:
- **delete**: Permanently remove matching monitors
- **pause**: Pause matching monitors
- **unpause**: Unpause matching monitors
Use `dry_run: true` (the default) to preview which monitors would be affected before performing the action. Results are paginated via the `limit` parameter; loop until `has_more` is `false` to process all matching monitors.'
tags:
- Monitors
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BatchMonitorsRequest'
responses:
'200':
description: Batch action result
content:
application/json:
schema:
$ref: '#/components/schemas/BatchMonitorsResponse'
/monitors/{id}:
get:
operationId: getMonitor
summary: Get a Monitor
description: Retrieves a single monitor by its ID.
tags:
- Monitors
parameters:
- in: path
name: id
schema:
type: string
description: The monitor ID
required: true
description: The monitor ID
responses:
'200':
description: The monitor
content:
application/json:
schema:
$ref: '#/components/schemas/SearchMonitor'
patch:
operationId: updateMonitor
summary: Update a Monitor
description: Updates an existing monitor. All fields are optional. For `search`, you can send a partial object containing only the fields you want to change. Set `trigger` to `null` to remove the schedule.
tags:
- Monitors
parameters:
- in: path
name: id
schema:
type: string
description: The monitor ID
required: true
description: The monitor ID
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateSearchMonitorParameters'
responses:
'200':
description: The updated monitor
content:
application/json:
schema:
$ref: '#/components/schemas/SearchMonitor'
delete:
operationId: deleteMonitor
summary: Delete a Monitor
description: Deletes a monitor. This cannot be undone.
tags:
- Monitors
parameters:
- in: path
name: id
schema:
type: string
description: The monitor ID
required: true
description: The monitor ID
responses:
'200':
description: The deleted monitor
content:
application/json:
schema:
$ref: '#/components/schemas/SearchMonitor'
/monitors/{id}/trigger:
post:
operationId: triggerMonitor
summary: Trigger a Monitor
description: Triggers a run immediately, regardless of the schedule. Works for monitors with status `active` or `paused`.
tags:
- Monitors
parameters:
- in: path
name: id
schema:
type: string
description: The monitor ID
required: true
description: The monitor ID
responses:
'200':
description: Whether the monitor was triggered
content:
application/json:
schema:
$ref: '#/components/schemas/TriggerSearchMonitorResponse'
/v0/monitors:
servers:
- url: https://api.exa.ai/websets
post:
description: 'Creates a new `Monitor` to continuously keep your Websets updated with fresh data.
Monitors automatically run on your defined schedule to ensure your Websets stay current without manual intervention:
- **Find new content**: Execute `search` operations to discover fresh items matching your criteria
- **Update existing content**: Run `refresh` operations to update items contents and enrichments
- **Automated scheduling**: Configure `cron` expressions and `timezone` for precise scheduling control'
operationId: monitors-create
parameters: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateMonitorParameters'
responses:
'201':
description: Monitor created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Monitor'
headers:
X-Request-Id:
schema:
type: string
description: Unique identifier for the request.
example: req_N6SsgoiaOQOPqsYKKiw5
required: true
summary: Create a Monitor
tags:
- Monitors
security:
- apiKey: []
- bearer: []
x-codeSamples:
- lang: javascript
label: JavaScript
source: "// npm install exa-js\nimport Exa from \"exa-js\";\nconst exa = new Exa(\"YOUR_EXA_API_KEY\");\n\nconst monitor = await exa.websets.monitors.create({\n websetId: \"webset_id\",\n cadence: {\n cron: \"0 9 * * 1\", // Every Monday at 9 AM\n timezone: \"America/New_York\",\n },\n behavior: {\n type: \"search\",\n config: {\n behavior: \"append\",\n query: \"new companies to monitor\",\n count: 10,\n },\n },\n});\n\nconsole.log(`Created monitor: ${monitor.id}`);"
- lang: python
label: Python
source: "# pip install exa-py\nfrom exa_py import Exa\n\nexa = Exa(\"YOUR_EXA_API_KEY\")\n\nmonitor = exa.websets.monitors.create(\n params={\n \"websetId\": \"webset_id\",\n \"cadence\": {\n \"cron\": \"0 9 * * 1\", # Every Monday at 9 AM\n \"timezone\": \"America/New_York\",\n },\n \"behavior\": {\n \"type\": \"search\",\n \"config\": {\n \"behavior\": \"append\",\n \"query\": \"new companies to monitor\",\n \"count\": 10,\n },\n },\n }\n)\n\nprint(f\"Created monitor: {monitor.id}\")"
get:
description: Lists all monitors for the Webset.
operationId: monitors-list
parameters:
- name: cursor
required: false
in: query
description: The cursor to paginate through the results
schema:
minLength: 1
type: string
- name: limit
required: false
in: query
description: The number of results to return
schema:
minimum: 1
maximum: 200
default: 25
type: number
- name: websetId
required: false
in: query
description: The id of the Webset to list monitors for
schema:
type: string
responses:
'200':
description: List of monitors
content:
application/json:
schema:
$ref: '#/components/schemas/ListMonitorsResponse'
headers:
X-Request-Id:
schema:
type: string
description: Unique identifier for the request.
example: req_N6SsgoiaOQOPqsYKKiw5
required: true
summary: List Monitors
tags:
- Monitors
security:
- apiKey: []
- bearer: []
x-codeSamples:
- lang: javascript
label: JavaScript
source: "// npm install exa-js\nimport Exa from \"exa-js\";\nconst exa = new Exa(\"YOUR_EXA_API_KEY\");\n\nconst monitors = await exa.websets.monitors.list({\n webset_id: \"webset_id\",\n});\n\nconsole.log(`Found ${monitors.data.length} monitors`);\nmonitors.data.forEach((monitor) => {\n console.log(`- ${monitor.id}: ${monitor.status}`);\n});"
- lang: python
label: Python
source: "# pip install exa-py\nfrom exa_py import Exa\n\nexa = Exa(\"YOUR_EXA_API_KEY\")\n\nmonitors = exa.websets.monitors.list(webset_id=\"webset_id\")\n\nprint(f\"Found {len(monitors.data)} monitors\")\nfor monitor in monitors.data:\n print(f\"- {monitor.id}: {monitor.status}\")"
/v0/monitors/{id}:
servers:
- url: https://api.exa.ai/websets
get:
description: Gets a specific monitor.
operationId: monitors-get
parameters:
- name: id
required: true
in: path
description: The id of the Monitor
schema:
type: string
responses:
'200':
description: Monitor details
content:
application/json:
schema:
$ref: '#/components/schemas/Monitor'
headers:
X-Request-Id:
schema:
type: string
description: Unique identifier for the request.
example: req_N6SsgoiaOQOPqsYKKiw5
required: true
summary: Get Monitor
tags:
- Monitors
security:
- apiKey: []
- bearer: []
x-codeSamples:
- lang: javascript
label: JavaScript
source: '// npm install exa-js
import Exa from "exa-js";
const exa = new Exa("YOUR_EXA_API_KEY");
const monitor = await exa.websets.monitors.get("monitor_id");
console.log(`Monitor: ${monitor.id} - ${monitor.status}`);'
- lang: python
label: Python
source: '# pip install exa-py
from exa_py import Exa
exa = Exa("YOUR_EXA_API_KEY")
monitor = exa.websets.monitors.get("monitor_id")
print(f"Monitor: {monitor.id} - {monitor.status}")'
patch:
description: Updates a monitor configuration.
operationId: monitors-update
parameters:
- name: id
required: true
in: path
description: The id of the Monitor
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateMonitor'
responses:
'200':
description: Monitor updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Monitor'
headers:
X-Request-Id:
schema:
type: string
description: Unique identifier for the request.
example: req_N6SsgoiaOQOPqsYKKiw5
required: true
summary: Update Monitor
tags:
- Monitors
security:
- apiKey: []
- bearer: []
x-codeSamples:
- lang: javascript
label: JavaScript
source: "// npm install exa-js\nimport Exa from \"exa-js\";\nconst exa = new Exa(\"YOUR_EXA_API_KEY\");\n\nconst monitor = await exa.websets.monitors.update(\"monitor_id\", {\n cadence: {\n cron: \"0 14 * * *\", // Every day at 2 PM\n timezone: \"America/New_York\",\n },\n});\n\nconsole.log(`Updated monitor: ${monitor.id}`);"
- lang: python
label: Python
source: "# pip install exa-py\nfrom exa_py import Exa\n\nexa = Exa(\"YOUR_EXA_API_KEY\")\n\nmonitor = exa.websets.monitors.update(\n \"monitor_id\",\n params={\n \"cadence\": {\n \"cron\": \"0 14 * * *\", # Every day at 2 PM\n \"timezone\": \"America/New_York\",\n }\n },\n)\n\nprint(f\"Updated monitor: {monitor.id}\")"
delete:
description: Deletes a monitor.
operationId: monitors-delete
parameters:
- name: id
required: true
in: path
description: The id of the Monitor
schema:
type: string
responses:
'200':
description: Monitor deleted successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Monitor'
headers:
X-Request-Id:
schema:
type: string
description: Unique identifier for the request.
example: req_N6SsgoiaOQOPqsYKKiw5
required: true
summary: Delete Monitor
tags:
- Monitors
security:
- apiKey: []
- bearer: []
x-codeSamples:
- lang: javascript
label: JavaScript
source: '// npm install exa-js
import Exa from "exa-js";
const exa = new Exa("YOUR_EXA_API_KEY");
await exa.websets.monitors.delete("monitor_id");
console.log("Monitor deleted successfully");'
- lang: python
label: Python
source: '# pip install exa-py
from exa_py import Exa
exa = Exa("YOUR_EXA_API_KEY")
exa.websets.monitors.delete("monitor_id")
print("Monitor deleted successfully")'
components:
schemas:
CustomEntity:
type:
- object
properties:
type:
type: string
const: custom
default: custom
description:
type:
- string
minLength: 2
maxLength: 200
required:
- type
- description
title: Custom
Monitor:
type:
- object
properties:
id:
type:
- string
description: The unique identifier for the Monitor
object:
type:
- string
enum:
- monitor
description: The type of object
status:
type:
- string
enum:
- enabled
- disabled
description: The status of the Monitor
websetId:
type:
- string
description: The id of the Webset the Monitor belongs to
cadence:
type:
- object
properties:
cron:
description: Cron expression for monitor cadence (must be a valid Unix cron with 5 fields). The schedule must trigger at most once per day.
type:
- string
timezone:
description: IANA timezone (e.g., "America/New_York")
default: Etc/UTC
type:
- string
required:
- cron
description: How often the monitor will run
behavior:
type:
- object
properties:
type:
type: string
const: search
default: search
config:
type:
- object
properties:
query:
type:
- string
minLength: 2
maxLength: 10000
description: The query to search for. By default, the query from the last search is used.
criteria:
type:
- array
items:
type:
- object
properties:
description:
type:
- string
minLength: 2
maxLength: 1000
required:
- description
maxItems: 5
description: The criteria to search for. By default, the criteria from the last search is used.
entity:
$ref: '#/components/schemas/Entity'
title: Entity
description: The entity to search for. By default, the entity from the last search/import is used.
count:
type:
- number
exclusiveMinimum: 0
description: The maximum number of results to find
behavior:
default: append
type:
- string
enum:
- override
- append
description: The behaviour of the Search when it is added to a Webset.
required:
- count
description: 'Specify the search parameters for the Monitor.
By default, the search parameters (query, entity and criteria) from the last search are used when no parameters are provided.'
required:
- type
- config
description: Behavior to perform when monitor runs
lastRun:
type: object
$ref: '#/components/schemas/MonitorRun'
title: MonitorRun
description: The last run of the monitor
nullable: true
nextRunAt:
type: string
format: date-time
description: Date and time when the next run will occur in
nullable: true
metadata:
description: Set of key-value pairs you want to associate with this object.
type:
- object
additionalProperties:
type:
- string
maxLength: 1000
createdAt:
type:
- string
format: date-time
description: When the monitor was created
updatedAt:
type:
- string
format: date-time
description: When the monitor was last updated
required:
- id
- object
- status
- websetId
- cadence
- behavior
- lastRun
- nextRunAt
- metadata
- createdAt
- updatedAt
SearchMonitorContents:
type: object
properties:
text:
description: Text extraction options for each result.
oneOf:
- type: boolean
title: Simple text retrieval
description: If true, returns full page text with default settings. If false, disables text return.
default: false
- type: object
properties:
maxCharacters:
anyOf:
- type: integer
minimum: 1
maximum: 10000
description: Maximum character limit for the full page text. Useful for controlling response size and API costs. Maximum supported value is 10000.
example: 1000
- type: 'null'
includeHtmlTags:
anyOf:
- type: boolean
description: 'If true, include lightweight HTML tags in returned text instead of plain markdown-style text. Use maxAgeHours: 0 when you need this applied to freshly fetched content.'
example: false
default: false
- type: 'null'
verbosity:
anyOf:
- type: string
enum:
- compact
- standard
- full
description: 'Controls text rendering verbosity. compact focuses on main content, standard includes more surrounding page context, and full requests the most complete rendered text. Some pages may produce identical standard and full output. Use maxAgeHours: 0 when you need this applied to freshly fetched content.'
example: standard
default: compact
- type: 'null'
includeSections:
anyOf:
- type: array
items:
type: string
enum:
- header
- navigation
- banner
- body
- sidebar
- footer
- metadata
description: 'Best-effort. Only include content classified into these semantic page sections. Section classification may be unavailable or incomplete for some pages; validate output if strict filtering is required. Use maxAgeHours: 0 when you need this applied to freshly fetched content.'
example:
- body
- header
- type: 'null'
excludeSections:
anyOf:
- type: array
items:
type: string
enum:
- header
- navigation
- banner
- body
- sidebar
- footer
- metadata
description: 'Exclude content classified into these semantic page sections. Section classification is best-effort. Use maxAgeHours: 0 when you need this applied to freshly fetched content.'
example:
- navigation
- footer
- sidebar
- type: 'null'
title: Advanced text options
description: Advanced options for controlling text extraction. Use this when you need to limit text length or include HTML structure.
highlights:
description: Text snippets the LLM identifies as most relevant from each page.
oneOf:
- type: boolean
title: Simple highlights retrieval
description: If true, returns highlights with default settings. If false, disables highlights.
default: false
- type: object
properties:
query:
anyOf:
- type: string
description: Custom query that guides which highlights the LLM picks.
example: Key advancements
- type: 'null'
maxCharacters:
anyOf:
- type: integer
minimum: 1
maximum: 10000
description: Maximum number of characters to return for highlights. Controls the total length of highlight text returned per URL. Maximum supported value is 10000.
example: 2000
- type: 'null'
numSentences:
anyOf:
- type: integer
minimum: 1
description: 'Deprecated and will be removed in a future release. Currently mapped to a character budget of about 1333 characters per sentence. Pass highlights: true for default highlights, or { query } to guide selection with your own query.'
example: 1
deprecated: true
- type: 'null'
highlightsPerUrl:
anyOf:
- type: integer
minimum: 1
description: 'Deprecated and will be removed in a future release. Currently ignored. Pass highlights: true for default highlights, or { query } to guide selection with your own query.'
example: 1
deprecated: true
- type: 'null'
title: Advanced highlights options
description: 'Advanced options for steering highlight extraction. Pass highlights: true for the highest-quality default; supply this object only when you need to guide selection with your own query.'
summary:
description: Return an LLM-generated summary. Pass `true` for defaults, or an object with `query` and `maxTokens`.
oneOf:
- type: boolean
- type: object
properties:
query:
anyOf:
- type: string
description: Custom query for the LLM-generated summary.
example: Main developments
- type: 'null'
maxTokens:
type: integer
minimum: 1
description: Maximum tokens for the generated summary.
extras:
type: object
properties:
links:
anyOf:
- type: integer
minimum: 0
maximum: 1000
description: Number of URLs to return from each webpage.
example: 1
default: 0
- type: 'null'
imageLinks:
anyOf:
- type: integer
minimum: 0
maximum: 1000
description: Number of images to return for each result.
example: 1
default: 0
- type: 'null'
richImageLinks:
anyOf:
- type: integer
minimum: 0
maximum: 1000
description: Number of rich image links to return for each result.
default: 0
- type: 'null'
richLinks:
anyOf:
- type: integer
minimum: 0
maximum: 1000
description: Number of rich links to return for each result.
default: 0
- type: 'null'
codeBlocks:
anyOf:
- type: integer
minimum: 0
maximum: 1000
description: Number of code blocks to return for each result.
default: 0
- type: 'null'
description: Extra parameters to pass.
context:
description: 'Deprecated: Use highlights or text instead. Returns page contents as a combined context string.'
deprecated: true
oneOf:
- type: boolean
description: 'Deprecated: Use highlights or text instead. Returns page contents as a combined context string.'
example: true
deprecated: true
- type: object
properties:
maxCharacters:
type: integer
minimum: 1
maximum: 10000
description: Deprecated. Maximum character limit for the context string. Maximum supported value is 10000.
example: 10000
description: 'Deprecated: Use highlights or text instead. Returns page contents as a combined context string.'
deprecated: true
livecrawl:
description: Crawl strategy for fetching page content
oneOf:
- type: string
enum:
- never
- always
- fallback
- preferred
- type: string
const: auto
livecrawlTimeout:
type: integer
exclusiveMinimum: 0
maximum: 90000
description: The timeout for livecrawling in milliseconds.
example: 1000
default: 10000
maxAgeHours:
type: integer
minimum: -1
maximum: 720
description: Maximum age of cached content in hours. Positive values use cached content if it is less than this many hours old; 0 fetches fresh content and is the supported way to apply text rendering options to newly fetched pages; -1 always uses cache; omitted uses fallback fetching when cached content is unavailable. Maximum supported value is 720 hours.
example: 24
filterEmptyResults:
type: boolean
description: Filter out results with no content
subpages:
type: integer
minimum: 0
maximum: 100
description: The number of subpages to crawl. The actual number crawled may be limited by system constraints.
example: 1
default: 0
subpageTarget:
description: Term to find specific subpages of search results. Can be a single string or an array of strings.
example: sources
oneOf:
- type: string
minLength: 1
maxLength: 100
- minItems: 0
maxItems: 100
type: array
items:
type: string
minLength: 1
maxLength: 100
description: Content extraction options applied to each search result. All fields are optional.
PersonEntity:
type:
- object
properties:
type:
type: string
const: person
default: person
required:
- type
title: Person
CreateSearchMonitorResponse:
type: object
properties:
id:
type: string
description: The unique identifier for the monitor
name:
anyOf:
- type: string
- type: 'null'
description: An optional display name
status:
type: string
enum:
- active
- paused
- disabled
description: The status of the monitor. `active` monitors run on schedule and can be triggered manually. `paused` monitors can only be triggered manually. `disabled` monitors are auto-disabled after 10 consecutive authentication failures.
search:
$ref: '#/components/schemas/SearchMonitorSearchOutput'
trigger:
anyOf:
- $ref: '#/components/schemas/SearchMonitorTriggerOutput'
- type: 'null'
description: The interval-based schedule for automatic runs. Null if no schedule is set.
outputSchema:
$ref: '#/components/schemas/SearchMonitorOutputSchemaOutput'
metadata:
anyOf:
- type: object
propertyNames:
type: string
additionalProperties:
type: string
descripti
# --- truncated at 32 KB (70 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/exa-ai/refs/heads/main/openapi/exa-ai-monitors-api-openapi.yml