@exa-labs/exa-search

Call Exa Search directly with cURL or raw HTTP. Use when an agent needs Exa semantic web retrieval from POST /search without an SDK, including ranked results, domain or category filters, freshness-aware result content, highlights or text extraction, structured output, or streaming search responses.

View in AI SkillSafe app
Scanned · no findings
0 downloads
0 stars
0 demos
SKILL.md
nameexa-search
descriptionCall Exa Search directly with cURL or raw HTTP. Use when an agent needs Exa semantic web retrieval from POST /search without an SDK, including ranked results, domain or category filters, freshness-aware result content, highlights or text extraction, structured output, or streaming search responses.

Exa Search

Requires API key: Get one at https://dashboard.exa.ai/api-keys

Header: x-api-key: $EXA_API_KEY

Use POST https://api.exa.ai/search for semantic web retrieval, ranked results, and optional result-level extraction in one raw HTTP call. Start with type: "auto" for general retrieval. Add contents only when the caller needs page text, highlights, summaries, freshness-controlled crawling, subpages, or extracted links.

Quick Start (cURL)

Basic search

curl -sS -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",
    "numResults": 10
  }'

Search with highlights

curl -sS -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",
    "numResults": 5,
    "contents": {
      "highlights": true
    }
  }'

With filters and freshness

curl -sS -X POST "https://api.exa.ai/search" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $EXA_API_KEY" \
  -d '{
    "query": "AI regulation policy updates",
    "type": "auto",
    "category": "news",
    "numResults": 10,
    "includeDomains": ["reuters.com", "bbc.com"],
    "startPublishedDate": "2025-01-01",
    "contents": {
      "text": {
        "maxCharacters": 2000
      },
      "maxAgeHours": 24,
      "livecrawlTimeout": 12000
    }
  }'

Deep search

curl -sS -X POST "https://api.exa.ai/search" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $EXA_API_KEY" \
  -d '{
    "query": "map the major technical and commercial tradeoffs in sodium-ion batteries for grid storage",
    "type": "deep",
    "numResults": 8
  }'

Endpoint

POST https://api.exa.ai/search

Authentication: x-api-key: <API_KEY> header. Exa also accepts Authorization: Bearer <API_KEY>, but prefer x-api-key in cURL examples for consistency.

Use this endpoint when the agent needs search results. If the agent already has URLs and only needs extraction, use POST /contents instead.

Parameters

Core request parameters

Parameter Type Required Default Description
query string Yes - Natural-language search query. Long, semantically rich descriptions work well.
type string No auto Search method: auto, fast, instant, deep-lite, deep, or deep-reasoning.
numResults integer No 10 Number of results to return. Use small values for agent loops; maximum is 100.
category string No - Specialized result type: company, people, research paper, news, personal site, or financial report.
includeDomains string[] No - Only return results from these domains, paths, or wildcard patterns. Max 1200.
excludeDomains string[] No - Exclude these domains, paths, or wildcard patterns. Max 1200.
startPublishedDate string No - ISO 8601 lower bound for result publication date.
endPublishedDate string No - ISO 8601 upper bound for result publication date.
userLocation string No - Two-letter ISO country code such as US or GB.
moderation boolean No false Filter unsafe content from results.
additionalQueries string[] No - Extra query variants for deep-search variants. Use alongside the main query.
systemPrompt string No - Instructions for synthesized output and deep-search planning, such as source preferences.
outputSchema object No - JSON Schema controlling output.content. Adds synthesized output and grounding.
stream boolean No false If true, returns SSE instead of a single JSON response.
compliance string No - Enterprise-only compliance mode, such as hipaa, when enabled for the account.

Content parameters nested under contents

On /search, text, highlights, and summary must be nested under contents.

Parameter Type Required Default Description
contents.text boolean or object No - Return full page text as markdown. Object form supports maxCharacters, includeHtmlTags, verbosity, includeSections, and excludeSections.
contents.highlights boolean or object No - Return query-relevant excerpts. Prefer true for agent workflows unless a fixed character budget is required.
contents.summary boolean or object No - Return per-result LLM summaries. Use sparingly because each result adds synthesis work.
contents.maxAgeHours integer No - Freshness control. 0 always live crawls; -1 uses cache only; omit for default cache-first behavior with crawl fallback.
contents.livecrawlTimeout integer No 10000 Timeout for live crawling in milliseconds. Use 10000 to 15000 for most freshness-sensitive calls.
contents.subpages integer No 0 Number of linked subpages to crawl per result.
contents.subpageTarget string or string[] No - Terms used to prioritize which subpages matter, such as ["api", "pricing"].
contents.extras.links integer No 0 Number of links to extract from each result page.
contents.extras.imageLinks integer No 0 Number of image URLs to extract from each result page.

Text object options

Parameter Type Default Description
maxCharacters integer - Character limit for returned text. Use this instead of tokensNum.
includeHtmlTags boolean false Preserve HTML tags in output.
verbosity string compact compact, standard, or full. Pair fresh section-aware extraction with contents.maxAgeHours: 0.
includeSections string[] - Only include selected sections: header, navigation, banner, body, sidebar, footer, metadata.
excludeSections string[] - Exclude selected sections from the same section list.

Highlights object options

Prefer contents.highlights: true for the highest-quality default. Only use object form when the agent needs a custom focus or budget.

Parameter Type Default Description
query string - Custom query guiding which excerpts are returned.
maxCharacters integer - Cap highlight characters per URL. Omit unless the caller has a strict budget.

Summary object options

Parameter Type Default Description
query string - Custom query for the summary.
schema object - JSON Schema for structured per-result summaries.

Search Types

Search type controls the retrieval and synthesis mode. Pick the mode for the workflow, not just the output format. outputSchema can be used with any search type; use deeper modes when the search process itself needs more planning, synthesis, or reasoning.

Type Best for Tradeoff
auto General default search and most new integrations Balances speed and quality without requiring the caller to tune retrieval strategy.
fast Low-latency agent loops and product paths Faster than auto; use when responsiveness matters more than maximum reasoning depth.
instant Real-time UI, chat, voice, and autocomplete-style paths Lowest latency path; use for quick retrieval rather than deep synthesis.
deep-lite Lightweight research or synthesis Adds more planning and synthesis than auto while staying lighter than full deep.
deep Multi-step research, comparisons, and synthesis-heavy retrieval Higher latency; better when the query needs exploration across several sources.
deep-reasoning Hard research tasks with high ambiguity or complex tradeoffs Highest latency and reasoning depth.

Use auto unless latency or reasoning depth is the primary constraint. Use fast or instant for time-sensitive calls. Use deep, deep-lite, or deep-reasoning when the query needs multi-step source discovery, comparison, or synthesis.

Mode-only examples

{
  "query": "recent product launches from major AI chip companies",
  "type": "fast",
  "numResults": 5
}
{
  "query": "compare competing explanations for the recent rise in grid-scale battery deployments",
  "type": "deep",
  "numResults": 8
}

Structured Output

Use systemPrompt for behavior and outputSchema for shape.

curl -sS -X POST "https://api.exa.ai/search" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $EXA_API_KEY" \
  -d '{
    "query": "compare the latest frontier AI model releases",
    "type": "deep",
    "systemPrompt": "Prefer official sources and avoid duplicate results.",
    "outputSchema": {
      "type": "object",
      "properties": {
        "models": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": { "type": "string" },
              "notable_claims": {
                "type": "array",
                "items": { "type": "string" }
              }
            },
            "required": ["name", "notable_claims"]
          }
        }
      },
      "required": ["models"]
    },
    "contents": {
      "highlights": true
    }
  }'

Keep schemas compact and bounded. Do not add citation fields to the schema; grounding is returned separately in output.grounding.

Streaming

Streaming applies to synthesized output, so include outputSchema along with -N, Accept: text/event-stream, and stream: true. Without outputSchema, the endpoint returns the normal JSON search response even when stream is true.

curl -sS -N -X POST "https://api.exa.ai/search" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -H "x-api-key: $EXA_API_KEY" \
  -d '{
    "query": "recent grid-scale battery deployments",
    "type": "deep",
    "stream": true,
    "outputSchema": {
      "type": "object",
      "properties": {
        "summary": { "type": "string" }
      },
      "required": ["summary"]
    },
    "contents": {
      "highlights": true
    }
  }'

Treat streaming as SSE rather than JSON. Each data: frame contains an OpenAI-compatible chat completion chunk; read partial text from choices[0].delta.content and handle completion or error frames defensively.

Response Fields

Field Type Description
requestId string Unique request identifier.
results array Ranked result objects.
results[].title string Page title.
results[].url string Page URL.
results[].publishedDate string or null Estimated publication date when available.
results[].author string or null Author when available.
results[].text string Returned when contents.text is requested.
results[].highlights string[] Returned when contents.highlights is requested.
results[].highlightScores number[] Similarity scores for highlights.
results[].summary string Returned when contents.summary is requested.
results[].subpages array Nested result objects from subpage crawling.
results[].extras.links string[] Extracted links when requested.
output.content string or object Synthesized output when outputSchema is provided.
output.grounding array Citations and confidence labels for synthesized fields.
costDollars.total number Total request cost when returned.
searchTime number Search latency when returned.

Critical Pitfalls

  • Keep text, highlights, and summary inside contents on /search.
  • Do not send top-level text, highlights, or summary; that shape belongs to /contents.
  • Do not send tokensNum; use contents.text.maxCharacters to cap extracted text.
  • Do not use useAutoprompt, numSentences, or highlightsPerUrl in new requests.
  • Use contents.maxAgeHours instead of livecrawl.
  • Use documented categories only: company, people, research paper, news, personal site, and financial report.
  • Avoid invalid category/filter combinations. company and people do not support startPublishedDate or endPublishedDate. company supports excludeDomains; people does not, and people only accepts LinkedIn domains in includeDomains.
  • Pick one of contents.highlights, contents.text, or contents.summary by default. Stack modes only when the caller truly needs multiple views of each page.
  • Expect SSE only when stream: true is paired with outputSchema; otherwise /search returns its normal JSON response.

Embed badges

Add these to your README to show the skill's verification status.

SkillSafe verified badge
Verified badge
[![SkillSafe verified badge](https://api.skillsafe.ai/v1/badge/@exa-labs/exa-search/verified)](https://skillsafe.ai/skill/@exa-labs/exa-search/)
Installs badge
Installs badge
[![Installs badge](https://api.skillsafe.ai/v1/badge/@exa-labs/exa-search/installs)](https://skillsafe.ai/skill/@exa-labs/exa-search/)
Scan badge
Scan badge
[![Scan badge](https://api.skillsafe.ai/v1/badge/@exa-labs/exa-search/scan)](https://skillsafe.ai/skill/@exa-labs/exa-search/)
Eval pass rate badge
Eval pass rate
[![Eval pass rate badge](https://api.skillsafe.ai/v1/badge/@exa-labs/exa-search/eval)](https://skillsafe.ai/skill/@exa-labs/exa-search/)