Searching with Exa (Search API)
This skill is a recipe for consistent web research using Exa’s Search API: you choose the right search mode, apply the right filters, request only the content you need (highlights/text/summary), and return clean citations.
Quick start (default path)
- Ensure an API key is available as an environment variable:
EXA_API_KEY (preferred)
- or pass
--api-key to the scripts.
- Run a search (JSON response to stdout):
python {baseDir}/scripts/exa_search.py --query "latest research in LLMs" --type auto --category "research paper" --num-results 5 --highlights --highlights-per-url 3 --num-sentences 2
Operating principles (always follow)
- Always return URLs. Prefer also returning title + a 1–2 sentence “why this source” note.
- Prefer
highlights first for agentic workflows. Escalate to full text only when necessary.
- Use filters aggressively: domain allowlists, date windows, and
category improve relevance and reduce noise.
- Freshness is explicit: if the user asks for “latest”, “today”, “current”, etc., set a freshness policy (see below).
- Don’t overfetch: cap content length with
maxCharacters when requesting text.
- If the user needs hard evidence (numbers, quotes), fetch full text for the top 1–3 pages and verify.
Workflow
Step 1 — Translate the user task into a search plan
Decide:
Search type
auto (default): best general quality.
instant: lowest latency, for autocomplete / live suggestions.
deep: more comprehensive; can use additionalQueries.
fast / neural: streamlined alternatives.
Category (when appropriate)
news, research paper, company, people, tweet, personal site, financial report, etc.
Freshness
- If “real-time / latest”: consider live crawling via
maxAgeHours (see Freshness).
- If “historical/static”: use cache only (e.g.,
maxAgeHours: -1).
Content mode
highlights: token-efficient evidence snippets.
text: deep reading (cap via maxCharacters).
summary: quick structured overviews (optionally with a guiding query).
Step 2 — Build the request payload
Start from this template and fill only what you need:
{
"query": "...",
"type": "auto",
"category": "news",
"numResults": 10,
"includeDomains": ["..."],
"excludeDomains": ["..."],
"startPublishedDate": "2025-01-01T00:00:00.000Z",
"endPublishedDate": "2025-12-31T23:59:59.999Z",
"includeText": ["must contain phrase"],
"excludeText": ["must not contain phrase"],
"contents": {
"highlights": true,
"text": { "maxCharacters": 8000, "includeHtmlTags": false },
"summary": { "query": "..." },
"subpages": 0,
"extras": { "links": 0, "imageLinks": 0 },
"maxAgeHours": 24
}
}
Notes:
contents is optional. If omitted, you’ll only get metadata (title, url, etc.).
maxAgeHours controls when Exa should live-crawl vs use cached content (see below).
context is deprecated; use highlights or text instead.
Step 3 — Execute the request
Option A (recommended): use the bundled script so requests are consistent and validated.
python {baseDir}/scripts/exa_search.py --query "..." --highlights --num-results 10
Option B: call the HTTP endpoint directly.
curl --request POST --url https://api.exa.ai/search --header "content-type: application/json" --header "x-api-key: $EXA_API_KEY" --data '{"query":"...","type":"auto","numResults":5}'
Step 4 — Post-process results into an answer with citations
- De-duplicate near-identical domains/pages when the user wants breadth.
- Select the top sources (usually 3–7) that jointly cover the claim space.
- For each selected result, extract:
- title, url
- key highlight(s) or a short quote from
text
- published date (if available)
- Write the response with inline citations (URLs) and clear uncertainty where needed.
- If the user wants a deliverable (report, memo), preserve a “Sources” section listing all URLs.
Freshness policy (use this when “latest/current/today” appears)
Use contents.maxAgeHours (or the maxAgeHours top-level alias if the API accepts it):
24: daily-fresh content (use cache if <24h else livecrawl)
1: near-real-time (cache if <1h else livecrawl)
0: always livecrawl (slowest, most current)
-1: never livecrawl (fastest; cache only)
- omit: default behaviour (livecrawl only when cache missing)
Common patterns
Pattern A — “Give me sources for X” (fast + token efficient)
type: auto, numResults: 5–10
contents.highlights: true
- Optional:
category and includeDomains
Pattern B — “Do deep research on X” (read a few pages thoroughly)
- Start with highlights on 10–20 results.
- Then fetch full
text for the top 3–5 URLs with a maxCharacters cap.
- Summarise with citations.
Pattern C — “Latest news about X”
category: news
- Apply a date window (
startPublishedDate) if the question is time-bound.
- Use a freshness setting (often
maxAgeHours: 1–24).
Pattern D — “Find a company / person page”
category: company or people
- If using
people, allowlist LinkedIn domains when needed.
- IMPORTANT: some filters are unsupported for
company/people; see troubleshooting.
Troubleshooting
401 / 403 (auth)
- Confirm
x-api-key header is present and valid.
- Confirm you aren’t accidentally using a placeholder like
YOUR-EXA-API-KEY.
400 (invalid parameters)
company and people categories support a limited set of filters; unsupported parameters can trigger 400 errors.
- If in doubt, remove date and text filters first, then re-add one-by-one.
Too much content / token blow-ups
- Prefer
highlights over text.
- Cap
text.maxCharacters.
- Reduce
numResults.
Bundled references
- API + parameter cheat sheet:
references/exa-search-api.md
- Best-practice recipes:
references/exa-search-best-practices.md
- Quickstart snippets (SDK + curl):
references/exa-search-quickstart.md
1---2name: exa-search3description: Searches the web via Exa’s Search API and returns source URLs (optionally with highlights, full text, summaries, and subpages). Use when the user asks to “search with Exa”, “use Exa”, “find sources/URLs”, “do web research”, “retrieve webpage text”, “get highlights/summaries”, “filter by domain/date/category”, or needs fresh results (news, real-time lookups).4---5
6# Searching with Exa (Search API)
7
8This skill is a **recipe for consistent web research** using Exa’s Search API: you choose the right search mode, apply the right filters, request only the content you need (highlights/text/summary), and return clean citations.
9
10## Quick start (default path)
11
121) Ensure an API key is available as an environment variable:
13
14- `EXA_API_KEY` (preferred)
15- or pass `--api-key` to the scripts.
16
172) Run a search (JSON response to stdout):
18
19```bash
20python {baseDir}/scripts/exa_search.py --query "latest research in LLMs" --type auto --category "research paper" --num-results 5 --highlights --highlights-per-url 3 --num-sentences 2
21```
22
23## Operating principles (always follow)
24
25- **Always return URLs**. Prefer also returning title + a 1–2 sentence “why this source” note.
26- **Prefer `highlights` first** for agentic workflows. Escalate to full `text` only when necessary.
27- **Use filters aggressively**: domain allowlists, date windows, and `category` improve relevance and reduce noise.
28- **Freshness is explicit**: if the user asks for “latest”, “today”, “current”, etc., set a freshness policy (see below).
29- **Don’t overfetch**: cap content length with `maxCharacters` when requesting `text`.
30- **If the user needs hard evidence** (numbers, quotes), fetch full text for the top 1–3 pages and verify.
31
32## Workflow
33
34### Step 1 — Translate the user task into a search plan
35
36Decide:
37
381. **Search type**
39 - `auto` (default): best general quality.
40 - `instant`: lowest latency, for autocomplete / live suggestions.
41 - `deep`: more comprehensive; can use `additionalQueries`.
42 - `fast` / `neural`: streamlined alternatives.
43
442. **Category** (when appropriate)
45 - `news`, `research paper`, `company`, `people`, `tweet`, `personal site`, `financial report`, etc.
46
473. **Freshness**
48 - If “real-time / latest”: consider live crawling via `maxAgeHours` (see *Freshness*).
49 - If “historical/static”: use cache only (e.g., `maxAgeHours: -1`).
50
514. **Content mode**
52 - `highlights`: token-efficient evidence snippets.
53 - `text`: deep reading (cap via `maxCharacters`).
54 - `summary`: quick structured overviews (optionally with a guiding `query`).
55
56### Step 2 — Build the request payload
57
58Start from this template and fill only what you need:
59
60```json
61{
62 "query": "...",
63 "type": "auto",
64 "category": "news",
65 "numResults": 10,
66 "includeDomains": ["..."],
67 "excludeDomains": ["..."],
68 "startPublishedDate": "2025-01-01T00:00:00.000Z",
69 "endPublishedDate": "2025-12-31T23:59:59.999Z",
70 "includeText": ["must contain phrase"],
71 "excludeText": ["must not contain phrase"],
72 "contents": {
73 "highlights": true,
74 "text": { "maxCharacters": 8000, "includeHtmlTags": false },
75 "summary": { "query": "..." },
76 "subpages": 0,
77 "extras": { "links": 0, "imageLinks": 0 },
78 "maxAgeHours": 24
79 }
80}
81```
82
83Notes:
84- `contents` is optional. If omitted, you’ll only get metadata (`title`, `url`, etc.).
85- `maxAgeHours` controls when Exa should live-crawl vs use cached content (see below).
86- `context` is deprecated; use `highlights` or `text` instead.
87
88### Step 3 — Execute the request
89
90**Option A (recommended):** use the bundled script so requests are consistent and validated.
91
92```bash
93python {baseDir}/scripts/exa_search.py --query "..." --highlights --num-results 10
94```
95
96**Option B:** call the HTTP endpoint directly.
97
98```bash
99curl --request POST --url https://api.exa.ai/search --header "content-type: application/json" --header "x-api-key: $EXA_API_KEY" --data '{"query":"...","type":"auto","numResults":5}'
100```
101
102### Step 4 — Post-process results into an answer with citations
103
1041. **De-duplicate** near-identical domains/pages when the user wants breadth.
1052. **Select the top sources** (usually 3–7) that jointly cover the claim space.
1063. For each selected result, extract:
107 - title, url
108 - key highlight(s) or a short quote from `text`
109 - published date (if available)
1104. **Write the response** with inline citations (URLs) and clear uncertainty where needed.
1115. If the user wants a deliverable (report, memo), preserve a “Sources” section listing all URLs.
112
113## Freshness policy (use this when “latest/current/today” appears)
114
115Use `contents.maxAgeHours` (or the `maxAgeHours` top-level alias if the API accepts it):
116
117- `24`: daily-fresh content (use cache if <24h else livecrawl)
118- `1`: near-real-time (cache if <1h else livecrawl)
119- `0`: always livecrawl (slowest, most current)
120- `-1`: never livecrawl (fastest; cache only)
121- omit: default behaviour (livecrawl only when cache missing)
122
123## Common patterns
124
125### Pattern A — “Give me sources for X” (fast + token efficient)
126- `type: auto`, `numResults: 5–10`
127- `contents.highlights: true`
128- Optional: `category` and `includeDomains`
129
130### Pattern B — “Do deep research on X” (read a few pages thoroughly)
131- Start with highlights on 10–20 results.
132- Then fetch full `text` for the top 3–5 URLs with a `maxCharacters` cap.
133- Summarise with citations.
134
135### Pattern C — “Latest news about X”
136- `category: news`
137- Apply a date window (`startPublishedDate`) if the question is time-bound.
138- Use a freshness setting (often `maxAgeHours: 1–24`).
139
140### Pattern D — “Find a company / person page”
141- `category: company` or `people`
142- If using `people`, allowlist LinkedIn domains when needed.
143- IMPORTANT: some filters are unsupported for `company`/`people`; see troubleshooting.
144
145## Troubleshooting
146
147### 401 / 403 (auth)
148- Confirm `x-api-key` header is present and valid.
149- Confirm you aren’t accidentally using a placeholder like `YOUR-EXA-API-KEY`.
150
151### 400 (invalid parameters)
152- `company` and `people` categories support a limited set of filters; unsupported parameters can trigger 400 errors.
153- If in doubt, remove date and text filters first, then re-add one-by-one.
154
155### Too much content / token blow-ups
156- Prefer `highlights` over `text`.
157- Cap `text.maxCharacters`.
158- Reduce `numResults`.
159
160## Bundled references
161
162- API + parameter cheat sheet: `references/exa-search-api.md`
163- Best-practice recipes: `references/exa-search-best-practices.md`
164- Quickstart snippets (SDK + curl): `references/exa-search-quickstart.md`