Skip to content
Back to skills

Build With Exa

ASecurity

Build applications and agents with Exa's API: search, contents extraction, answer, Agent API, monitors, websets, OpenAI-compatible endpoints, and exa-py/exa-js SDKs. Use when choosing Exa endpoints, writing Exa API calls, integrating semantic web search or research into products, or debugging Exa request shapes.

  • 3 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 27, 2026
ai-agentsjavascripttypescriptpythongojavabashexpresstestingdebugginggit

Works with

  • terminal
  • cli
  • api

Security analysis

A92/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 14 files and shows the line behind each finding

Scanned September 27, 2026

npx -y skills add gengirish/social-media-agency --skill build-with-exa --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Build With Exa?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Build With Exa
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/gengirish-build-with-exa/badge)](https://www.skillsdirectory.com/skills/gengirish-build-with-exa)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: build-with-exa
description: "Build applications and agents with Exa's API: search, contents extraction, answer, Agent API, monitors, websets, OpenAI-compatible endpoints, and exa-py/exa-js SDKs. Use when choosing Exa endpoints, writing Exa API calls, integrating semantic web search or research into products, or debugging Exa request shapes."
metadata:
  author: Exa
  version: "0.2.0"
  docs: "https://exa.ai/docs"
---

# Build with Exa

## Scope

Included by default:

- Core retrieval APIs: search endpoint, contents endpoint, answer endpoint
- Long-running research workflows: Agent API (`/agent`)
- Async and recurring workflows: Monitors API
- Legacy surface: Websets API (existing integrations only; new collection-building work uses the Agent API)
- SDK guidance: Python `exa-py`, TypeScript `exa-js`

> Note on data retention: `/search`, `/answer`, and `/agent/` offer Zero Data Retention (ZDR). Websets and Monitors are not ZDR. If a use case requires ZDR, stay on the ZDR surfaces or contact Exa.

## Installation

```bash
# Python
pip install exa-py

# TypeScript / JavaScript
npm install exa-js
```

Install the latest SDK release with the package manager so it resolves the latest release and all SDK surfaces will be available.

## Authentication

```bash
export EXA_API_KEY="your_api_key_here"
```

Exa accepts either the `x-api-key` header or `Authorization: Bearer <key>`.

The recommended Exa search request is the query plus token-efficient content extraction, and nothing else. Content extraction is a recommendation, not a server default: omit `contents` and results carry only metadata (title, URL, dates), no page content.

```json
{
  "query": "latest developments in LLMs",
  "type": "auto",
  "contents": { "highlights": true }
}
```

**Every other request field is gated: add it only when the user's task explicitly requires it.** Do not restate server defaults, and do not add controls because they seem plausibly useful. In particular:

- `type` defaults to `auto`; stating `type: "auto"` explicitly is fine, but do not send another mode unless the task requires it (for example a latency-critical UX or deep synthesis).
- `numResults` defaults to 10; omit `numResults` unless the task requires a different number of results. Set it only as an intentional product decision, not as boilerplate.
- Omit `category`. Use it only when the user explicitly asks for category-constrained retrieval.
- `includeDomains` and `excludeDomains` should be set only when the user explicitly requests a hard allowlist or blocklist and supplies or approves its contents. Express source preferences through query phrasing or `systemPrompt` instead.
- `maxAgeHours` should be set only when extracted page content must be current. It caps cache age before a live crawl; it is not a publication-recency filter.
- For "recent stories" tasks, put the recency in the query ("latest", "recent"). `startPublishedDate` / `endPublishedDate` are hard filters that drop undated and misdated pages; add them only when the task states a bounded window that must be enforced ("from the last seven days", "published in 2026"). Do not reach for `maxAgeHours`.
- `highlights` should be set to `true` by default for all tasks unless otherwise specified. Do not add `maxCharacters` or other highlight options without an explicit budget requirement in the task.

## API Decision Workflow

Before picking an endpoint, decide which workflow shape fits:

- Raw web content for your own LLM or agent: use `/search` with the recommended request above
- A specific output shape, or fields that have to be extracted or synthesized from the pages: use `/search` and add `outputSchema` (and `systemPrompt` if behavior guidance is needed). The user does not have to say "JSON" or "schema": "the funding amount each article reports", "name, title, and company for each person", or a field the result must carry that result metadata only sometimes has (a required author) are all structured-output requests. Fields every result already carries (title, URL, published date) are not: "10 articles with title and URL" is the recommended request with `numResults`. A compact schema (author and URL per article) stays on `auto`; `type: "deep"` when the schema is wide or its fields take more than one search to fill, since it runs several. See Structured Output in `references/search.md`.
- Long-running multi-step research, list-building, or enrichment with structured output: use the Agent API (`/agent`), with the same `outputSchema` rule for its fields

**Default to the search endpoint.** Use the search endpoint (`/search`) for most new integrations, then move to a more specialized Exa surface only when the task shape clearly calls for it.

1. Need general semantic web retrieval, synthesized output, or content extraction from search results: use the search endpoint (`/search`)
2. Already know the URLs and need clean page extraction or freshness controls: use the contents endpoint (`/contents`)
3. Need pages related to a known seed URL: use the search endpoint (`/search`) with a query derived from the page (for example title, topic, or text from `/contents`)
4. Need a grounded answer with citations and no LLM of your own doing generation: use the answer endpoint (`/answer`). If the product already has a chat LLM, give it `/search` as a tool instead.
5. Need OpenAI SDK drop-in compatibility for chat or responses clients: use the OpenAI-compatible endpoints (`/chat/completions`, `/responses`)
6. Need asynchronous multi-step research, list-building, enrichment, or follow-up questions over prior research: use the Agent API (`/agent`)
7. Need scheduled recurring search with webhook delivery: use the Monitors API (`/monitors`)
8. Maintaining an existing Websets integration: see the migration guide (`references/migrate-websets-to-agent.md`) and transition to the Agent API (`references/agent.md`). Do not use Websets for new work; use the Agent API instead.
9. Need page content as it was at a past datetime (backtesting agents, reproducible evals, comparing earlier versions of docs, pricing pages, policies, or filings): use Exa Snapshot, the `snapshotAsOf` field on `/contents` (top level) or `/search` (inside `contents`). See `references/snapshot.md`.

## Quick Start

For more complete examples, see the relevant reference file in the table below.

**Python** (`/search`):

```python
from exa_py import Exa

exa = Exa(api_key="YOUR_EXA_API_KEY")
result = exa.search(
    "latest developments in LLMs",
    type="auto",
    contents={"highlights": True}
)

for item in result.results:
    print(item.title, item.url)
```

**TypeScript** (`/search`):

```typescript
import Exa from "exa-js";

const exa = new Exa();
const result = await exa.search("latest developments in LLMs", {
  type: "auto",
  contents: { highlights: true }
});

for (const item of result.results) {
  console.log(item.title, item.url);
}
```

**Raw HTTP** (`/search`):

```bash
curl -X POST "https://api.exa.ai/search" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $EXA_API_KEY" \
  -d '{
    "query": "latest developments in LLMs",
    "type": "auto",
    "contents": {
      "highlights": true
    }
  }'
```

## Critical Pitfalls

- Do not decorate the recommended request without reason. Adding `category`, domain filters, boilerplate `numResults`, or freshness controls without an explicit task requirement is the most common integration mistake.
- Do not answer an extraction request with a bare search. A field that has to come out of the page, or a metadata field the user requires on every result, goes in `outputSchema`; keep/drop rules go in `systemPrompt`; `query` is retrieval intent only. If a clause of the query says `only`, `include`, `exclude`, `drop`, or `return`, it is in the wrong field. Do not add `outputSchema` for fields every result already carries (title, URL, published date).
- On the search endpoint, `text`, `highlights`, and `summary` belong inside `contents`, not at the top level.
- On the contents endpoint, `text`, `highlights`, and `summary` are top-level fields, not nested inside `contents`.
- Pick one of `highlights`, `text`, or `summary`. Do not stack them. `summary` requires an explicit user request for Exa-side per-result synthesis.
- Almost all tasks should use bare `highlights: true`. `numSentences` and `highlightsPerUrl` are deprecated, and `maxCharacters` needs an explicit budget requirement.
- List-building and enrichment workflows belong on the Agent API (`/agent`), not on `/search` with `category: "people"` or `category: "company"`. Those categories are only for retrieving raw people or company documents.
- `maxAgeHours` controls crawl/cache freshness (how old extracted page content may be before a live crawl), not publication recency. Do not use it as a "recent results" control; recency belongs in query phrasing. `startPublishedDate` / `endPublishedDate` are for task-stated bounded windows ("the last seven days", "in 2026") that must be enforced, not for "recent" or "latest" alone.
- Never invent category values like `github`, `documentation`, `qa`, or `pdf`. When a user does request category-constrained retrieval, check the search reference first: specialized categories such as `people` and `company` restrict which filters are valid.
- OpenAI-compatible endpoints are for compatibility-first use cases. Prefer native Exa endpoints for new integrations when you want clearer request semantics.
- Do not treat `/agent` as a drop-in replacement for `/search`. It is higher-latency and async, so use the dedicated Agent reference when that workflow shape is the real fit. Prefer it over Websets for new collection-building work.
- Agent requests should always set `effort` explicitly, wait for a terminal status via polling or SSE and check how the run ended before reading `output`, and expose `output.grounding` when relevant in a product.
- Treat `/findSimilar` as deprecated. Prefer `/search` (optionally after `/contents` on the seed URL) for related-page discovery.

## Reference Files

| File | Topics |
|------|--------|
| [references/search.md](references/search.md) | Search endpoint request/response shape, search types, filters, nested contents, structured output |
| [references/contents.md](references/contents.md) | Contents endpoint extraction, freshness, statuses, top-level content fields |
| [references/snapshot.md](references/snapshot.md) | Exa Snapshot: `snapshotAsOf` historical page versions on `/contents` and `/search`, limits, snapshot vs freshness |
| [references/answer.md](references/answer.md) | Grounded answer generation with citations and structured output |
| [references/agent.md](references/agent.md) | Agent API for async multi-step research, enrichment, structured output, polling, and events |
| [references/openai-compat.md](references/openai-compat.md) | OpenAI-compatible endpoints, model routing, `extra_body` usage |
| [references/monitors.md](references/monitors.md) | Standalone Monitors API for scheduled recurring search |
| [references/migrate-websets-to-agent.md](references/migrate-websets-to-agent.md) | Migrate Websets to the Agent API: call-site classification, request mapping, delivery rewrite, verification |
| [references/sdks.md](references/sdks.md) | Python and TypeScript SDK naming, methods, and shape differences |
| [references/http-requests.md](references/http-requests.md) | Minimal raw HTTP examples across major Exa surfaces |
| [references/models-and-modes.md](references/models-and-modes.md) | Search type selection, answer/research model routing, latency tradeoffs |
| [references/prompting-and-patterns.md](references/prompting-and-patterns.md) | Durable query, prompting, freshness, and output-schema patterns |
| [references/common-mistakes.md](references/common-mistakes.md) | Over-specification and parameter-shape corrections |

## Canonical Docs

- Docs home: `https://exa.ai/docs`
- Documentation index: `https://exa.ai/docs/llms.txt`
- Search reference: `https://exa.ai/docs/reference/search`
- Agent API guide: `https://exa.ai/docs/reference/agent-api-guide`
- Exa Connect overview: `https://exa.ai/docs/reference/agent-api/connect/overview`
- Exa Snapshot: `https://exa.ai/docs/search/snapshot`
- Python SDK spec: `https://exa.ai/docs/sdks/python-sdk-specification`
- TypeScript SDK spec: `https://exa.ai/docs/sdks/typescript-sdk-specification`

Files in this skill

  • SKILL.md12.1 KB
  • references/agent.md9.7 KB
  • references/answer.md3.5 KB
  • references/common-mistakes.md5.1 KB
  • references/contents.md4.8 KB
  • references/http-requests.md3.9 KB
  • references/migrate-websets-to-agent.md9 KB
  • references/models-and-modes.md2.9 KB
  • references/monitors.md3.9 KB
  • references/openai-compat.md3.3 KB
  • references/prompting-and-patterns.md6.2 KB
  • references/sdks.md4.6 KB
  • references/search.md14.2 KB
  • references/snapshot.md4.6 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…