Overview

Base URL: https://api.exa.ai/websets/v0 Auth: Pass your API key via the x-api-key header. Get one at https://dashboard.exa.ai/api-keys. Websets is an asynchronous search system. You define a query, criteria for verification, and optional enrichments. The system searches, verifies each result, and returns structured items over time. Results are available via polling or webhooks.

Installation

pip install exa-py    # Python
npm install exa-js    # JavaScript

Minimal Working Example

from exa_py import Exa
from exa_py.websets.types import CreateWebsetParameters, CreateEnrichmentParameters
import os

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

webset = exa.websets.create(
    params=CreateWebsetParameters(
        search={
            "query": "Top AI research labs focusing on large language models",
            "count": 5
        },
        enrichments=[
            CreateEnrichmentParameters(
                description="LinkedIn profile of VP of Engineering",
                format="text",
            ),
        ],
    )
)
print(f"Webset ID: {webset.id}")
print(f"Dashboard: {webset.dashboard_url}")

# Wait for completion
webset = exa.websets.wait_until_idle(webset.id)

# Get results
items = exa.websets.items.list(webset_id=webset.id)
for item in items.data:
    print(item.model_dump_json(indent=2))
import Exa from "exa-js";
const exa = new Exa(process.env.EXA_API_KEY);

const webset = await exa.websets.create({
  search: {
    query: "Top AI research labs focusing on large language models",
    count: 10
  },
  enrichments: [
    { description: "Estimate founding year", format: "number" }
  ],
});
console.log(`Webset ID: ${webset.id}`);

const idleWebset = await exa.websets.waitUntilIdle(webset.id, {
  timeout: 60000,
  pollInterval: 2000
});

const items = await exa.websets.items.list(webset.id, { limit: 10 });
for (const item of items.data) {
  console.log(JSON.stringify(item, null, 2));
}
# Create a webset
curl -s -X POST "https://api.exa.ai/websets/v0/websets/" \
  -H "accept: application/json" \
  -H "content-type: application/json" \
  -H "x-api-key: ${EXA_API_KEY}" \
  -d '{
    "search": {
      "query": "Top AI research labs focusing on large language models",
      "count": 5
    },
    "enrichments": [
      {"description": "Find founding year", "format": "number"}
    ]
  }'

# Check status
curl "https://api.exa.ai/websets/v0/websets/{WEBSET_ID}" \
  -H "accept: application/json" \
  -H "x-api-key: ${EXA_API_KEY}"

# List items
curl "https://api.exa.ai/websets/v0/websets/{WEBSET_ID}/items" \
  -H "accept: application/json" \
  -H "x-api-key: ${EXA_API_KEY}"

# Get webset with items expanded
curl "https://api.exa.ai/websets/v0/websets/{WEBSET_ID}?expand=items" \
  -H "accept: application/json" \
  -H "x-api-key: ${EXA_API_KEY}"

How Websets Work

Lifecycle

  1. Create — You POST a search config (query, count, optional criteria/enrichments/entity type). A webset is created with status running.
  2. Search — The system searches and verifies each result against your criteria. Matching items are added to the webset. Each item triggers a webset.item.created event.
  3. Enrichment — If enrichments are configured, each item is processed. webset.item.enriched events fire as enrichment results arrive.
  4. Idle — When all searches and enrichments complete, the webset status becomes idle and a webset.idle event fires.

Key Concepts

  • Search: Defines what to look for (query + count). Multiple searches can be added to one webset.
  • Criteria: Verification rules. Each result is checked against criteria before becoming an item. Max 5 criteria per search.
  • Entity: Optional type hint (e.g. "company", "person", "article", "research_paper", "custom") that shapes how results are found and verified. Auto-detected if not specified.
  • Enrichments: Additional data extraction applied to each item (e.g. “Find the CEO name”). Max 10 per webset.
  • Monitors: Scheduled re-runs that keep websets updated. Supports cron expressions.
  • Webhooks: Real-time HTTP callbacks for events.
  • Imports: Bring your own URLs and run enrichments on them.
  • Exports: Bulk download of webset items as CSV/JSON.

API Endpoints — Full Reference

Websets

POST /websets/ — Create a Webset

Request body:

{
  "search": {
    "query": "AI companies in Europe that raised Series A funding",
    "count": 50,
    "criteria": [
      {"description": "Company is an AI startup"},
      {"description": "Company has raised Series A funding"}
    ],
    "entity": {"type": "company"},
    "behaviour": "override"
  },
  "enrichments": [
    {"description": "Find the CEO name", "format": "text"},
    {"description": "Estimate founding year", "format": "number"},
    {"description": "Industry vertical", "format": "options", "options": [{"label": "Healthcare"}, {"label": "Finance"}, {"label": "Education"}, {"label": "Other"}]} 
  ],
  "externalId": "my-unique-id",
  "metadata": {"project": "market-research"}
}

Field details:

Field Type Required Description
search.query string (min 1 char) Yes Natural language query. Any URL in the query will be crawled and used as context.
search.count number (>= 1) No (default 10) Target number of items to find. Actual results may be fewer depending on query complexity.
search.criteria array (1–5 items) No Verification rules. Auto-detected from query if omitted. Each has a description string.
search.entity object No One of: { "type": "company" }, { "type": "person" }, { "type": "article" }, { "type": "research_paper" }, { "type": "custom", "description": "Job Postings" }. Auto-detected if omitted.
search.behaviour string No (default "override") "override": reuses existing items, re-evaluates against new criteria, discards non-matching.
enrichments array (max 10) No Each enrichment has description (required), format, options, metadata.
externalId string No Your own identifier. Can be used in place of webset ID in all GET/PATCH/DELETE calls. Returns 409 if duplicate.
metadata object No Arbitrary key-value pairs for the webset.

Response: A Webset object (see Object Schemas below).

GET /websets/{id} — Get a Webset

  • {id} can be the webset ID or externalId.
  • Query param ?expand=items includes up to 100 items in the response.

Response: A Webset object. When expanded, includes an items array of WebsetItem objects.

GET /websets/ — List All Websets

Query params:

Param Type Description
cursor string Pagination cursor from previous response’s nextCursor.
limit number Results per page (max 200).

Response: { "data": [Webset, ...], "hasMore": boolean, "nextCursor": string | null }

Items

GET /websets/{websetId}/items — List Items

Query params:

Param Type Description
cursor string Pagination cursor.
limit number Results per page.

Response: { "data": [WebsetItem, ...], "hasMore": boolean, "nextCursor": string | null }

GET /websets/{websetId}/items/{itemId} — Get a Single Item

Response: A WebsetItem object.

Enrichments

POST /websets/{websetId}/enrichments — Add an Enrichment

{
  "description": "Find the company's LinkedIn page URL",
  "format": "url",
  "metadata": {"source": "linkedin"}
}

GET /websets/{websetId}/enrichments/{enrichmentId} — Get Enrichment Status

Response: A WebsetEnrichment object.