/scraping-api/ — Exa API
Use direct HTTP Search to discover source URLs or Contents when URLs or document IDs are known. Choose returned text deliberately, inspect per-item statuses and compare request versus content-type charges.
Choose the HTTP operation
documented decisionSwipe or scroll the table to compare response checks and billing.
| Starting point | Request | Check the response | Billing basis |
|---|---|---|---|
| Source URL unknown | POST /search with a query, type: instant and numResults: 5. Request contents.text in the same call if short page text helps evaluate results. | Inspect each result URL and returned text; select a relevant source before using its contents. A result is a discovery lead, not a guaranteed fresh fetch. | At the checked rate, instant Search is $4 per 1,000 requests for up to 10 results; fast/auto are $7 per 1,000.[1][3] |
| URL or document ID known | POST /contents with either urls or ids and only the content types needed. Set maxAgeHours: 0 when requesting a fresh crawl. | Match statuses[].id and status to each requested item, inspect error and source, then accept text only for successful results. | At the checked rate, Contents is $1 per 1,000 returned pages per content type; text plus highlights counts as two types.[2][3] |
documented capabilities
HTTP API- Unknown source URL
- POST /search with query and numResults. type: instant targets low latency; auto is the default. A contents.text option can request page text in the same search response, so a second Contents call is not always needed for returned results.[1]
- Known source URL or ID
- POST /contents accepts either urls or document ids from a prior Search, not both in the same request. Request text, highlights or summaries intentionally for the known items.[2]
- Response content
- Both endpoints return JSON. Contents results can include text, highlights or summary when requested. The text option is described as plain markdown-style text, but the reference does not promise a separate Markdown response format.[1][2]
- Per-item acceptance
- The Contents response has results and statuses. For each requested URL or ID, check statuses[].id, status (success or error), optional source (cached or crawled) and error details before accepting results. A 200 response does not by itself prove every item succeeded.[2]
- Freshness choice
- For Contents, maxAgeHours: 0 requests fresh content; -1 uses cache only; a positive value accepts cache younger than that many hours; omission allows fallback fetching. A fresh request is not a success guarantee.[2]
- Search request price
- At the checked rate, instant Search is $4 per 1,000 requests and fast/auto are $7 per 1,000 for up to 10 results. Each result beyond 10 is separately priced at $1 per 1,000 results; AI page summaries add a separate page charge.[3]
Billing: Current account pricing: /search instant is $4 per 1,000 requests; fast or auto is $7 per 1,000, including up to 10 results, with extra results billed separately. /contents is $1 per 1,000 returned pages per content type: requesting text and highlights for one page counts as two. AI page summaries have a separately listed $1 per 1,000 pages charge. Rates and account terms can change.
Outputs: json, text, highlights
Documented for: HTTP API
MCP client setup
This record covers direct HTTP API use. For client configuration and available tools, use the Exa MCP guide.
getting started
documentation reviewed- If you need to discover a source, use Search; if you already have a URL or Search document ID, use Contents directly. Request text in Search only if it helps choose a result.
- Send application/json POST requests to https://api.exa.ai/search or https://api.exa.ai/contents with a private Authorization: Bearer EXA_API_KEY header (or the documented x-api-key alternative). The examples below are JSON bodies, not live calls.
- Use the five-result instant Search example for discovery. For a known-URL batch, pass urls rather than ids and request only text with a size limit; maxAgeHours: 0 asks Exa to fetch fresh content.
- For a Contents batch, reconcile each input against statuses[].id/status before using results. Check source and error details; estimate cost by returned pages and requested content types, and inspect current billing terms.
Requirements & limitations
- Exa Search discovers web sources; this record does not promise positional Google SERP snapshots or classify the service as a dedicated SERP API.
- The Contents text is described as markdown-style text. The reference does not document a standalone Markdown output contract, so this record is not in the Markdown API collection.
- Contents requires either urls or ids in a request. maxAgeHours: 0 requests fresh content but does not guarantee that a target can be fetched or that returned text is complete or accurate.
- The listed rates are published account prices, not a measured bill. costDollars is an estimated response field; billing is computed from usage counters. Summary and extra-result options can change total cost.
- The examples were parsed locally against documented fields. No Exa account request, target fetch, performance comparison or payment was tested.
We reviewed the linked documentation. No live service connection, checkout or performance test is claimed for this listing.
request examples
adapt to your targetDiscover sources and short text — POST /search JSON body
{
"query": "official documentation for a library API",
"type": "instant",
"numResults": 5,
"contents": {
"text": {
"maxCharacters": 1200
}
}
}[1] Exa Search endpoint and optional contents[3] Exa Search and Contents pricing units
Read a known-URL batch freshly — POST /contents JSON body
{
"urls": [
"https://example.com/docs",
"https://example.com/unavailable"
],
"text": {
"maxCharacters": 1200
},
"maxAgeHours": 0
}[2] Exa Contents endpoint, freshness and per-item statuses[3] Exa Search and Contents pricing units
response checks
documented exampleIllustrative status shape for that two-URL batch (placeholders, not a live response)
{
"results": [
{
"title": "Example docs",
"url": "https://example.com/docs",
"id": "example-doc-id",
"text": "Example extracted text."
}
],
"statuses": [
{
"id": "https://example.com/docs",
"status": "success",
"source": "crawled"
},
{
"id": "https://example.com/unavailable",
"status": "error",
"error": {
"tag": "<provider error tag>",
"httpStatusCode": 404
}
}
]
}Map every submitted URL or ID to statuses[].id. Use text from the matching successful result; report or retry error items separately. The example uses placeholder values from the documented response schema and does not report an observed Exa fetch.[2] Exa Contents endpoint, freshness and per-item statuses
primary sources
4 references- Exa Search endpoint and optional contentsChecked 2026-09-29
- Exa Contents endpoint, freshness and per-item statusesChecked 2026-09-29
- Exa Search and Contents pricing unitsChecked 2026-09-29
- Exa account billing and rate-limit errorsChecked 2026-09-29