# Exa API — Orthogonal API

> Pay-per-use API on Orthogonal. Each call is billed to your Orthogonal balance.
> Base API: `https://api.orth.sh/v1/run` · [llms.txt](https://orthogonal.com/llms.txt) · [browse all APIs](https://orthogonal.com/discover)

Exa is a search engine made for AIs.

**Verified:** no

## Access

**Run API:** `POST https://api.orth.sh/v1/run`
**Auth:** `Authorization: Bearer $ORTHOGONAL_API_KEY`
Get an API key at https://orthogonal.com/dashboard/settings/api-keys

Every call goes through the unified Run API: send the API `slug`, the endpoint `path`, and the `query`/`body` parameters. The response is `{ "success": true, "price": "<usd>", "data": { ... } }`.

## Endpoints

### Exa Research

Retrieve a paginated list of your research tasks. The response follows a cursor-based pagination pattern. Pass the `limit` parameter to control page size (max 50) and use the `cursor` token returned in the response to fetch subsequent pages.

`GET /research/v1`

**Estimated cost:** $0.01

**Docs:** https://exa.ai/docs/reference/research/list-tasks

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `cursor` | string | No | The cursor to paginate through the results Minimum string length: `1` |
| `limit` | number | No | Number of results per page (1-50) Required range: `1 <= x <= 50` |

```bash
curl -X POST 'https://api.orth.sh/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"exa","path":"/research/v1","method":"GET","query":{"cursor":"<string>","limit":"<number>"}}'
```

### Answer

Get an LLM answer to a question informed by Exa search results. /answer performs an Exa search and uses an LLM to generate either:

A direct answer for specific queries. (i.e. “What is the capital of France?” would return “Paris”)
A detailed summary with citations for open-ended queries (i.e. “What is the state of ai in healthcare?” would return a summary with citations to relevant sources)

The response includes both the generated answer and the sources used to create it. The endpoint also supports streaming (as stream=True), which will return tokens as they are generated.
Alternatively, you can use the OpenAI compatible chat completions interface.

`POST /answer`

**Estimated cost:** $0.01

**Docs:** https://exa.ai/docs/reference/answer

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `query` | string | Yes | The question or query to answer. |
| `stream` | boolean | No | If true, the response is returned as a server-sent events (SSS) stream. |
| `text` | boolean | No | If true, the response includes full text content in the search results |

```bash
curl -X POST 'https://api.orth.sh/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"exa","path":"/answer","body":{"query":"<string>","stream":"<boolean>","text":"<boolean>"}}'
```

### Search

The search endpoint lets you intelligently search the web and extract contents from the results.By default, it automatically chooses the best search method using Exa’s embeddings-based model and other techniques to find the most relevant results for your query. You can also use Deep search for comprehensive results with query expansion and detailed context.

`POST /search`

**Estimated cost:** $0.01

**Docs:** https://exa.ai/docs/reference/search

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `query` | string | Yes | The query string for the search. |
| `additionalQueries` | string[] | No | Additional query variations for deep search. Only works with type="deep". When provided, these queries are used alongside the main query for comprehensive results. |
| `type` | enum<string> | No | The type of search. Neural uses an embeddings-based model, auto (default) intelligently combines neural and other search methods, fast uses streamlined versions of the search models, and deep provides comprehensive search with query expansion and detailed context. |
| `category` | enum<string> | No | A data category to focus on. The people and company categories have improved quality for finding LinkedIn profiles and company pages. Note: The company and people categories only support a limited set of filters. The following parameters are NOT supported for these categories: startPublishedDate, endPublishedDate, startCrawlDate, endCrawlDate, includeText, excludeText, excludeDomains. For people category, includeDomains only accepts LinkedIn domains. Using unsupported parameters will result in a 400 error. |
| `userLocation` | string | No | The two-letter ISO country code of the user, e.g. US. |
| `numResults` | integer | No | Number of results to return. Limits vary by search type: With "neural": max 100 results With "deep": max 100 results If you want to increase the num results beyond these limits, contact sales (hello@exa.ai) |
| `includeDomains` | string[] | No | List of domains to include in the search. If specified, results will only come from these domains. |
| `excludeDomains` | string[] | No | List of domains to exclude from search results. If specified, no results will be returned from these domains. |
| `startCrawlDate` | string<date-time> | No | Crawl date refers to the date that Exa discovered a link. Results will include links that were crawled after this date. Must be specified in ISO 8601 format. |
| `endCrawlDate` | string<date-time> | No | Crawl date refers to the date that Exa discovered a link. Results will include links that were crawled before this date. Must be specified in ISO 8601 format. |
| `startPublishedDate` | string<date-time> | No | Only links with a published date after this will be returned. Must be specified in ISO 8601 format. |
| `endPublishedDate` | string<date-time> | No | Only links with a published date before this will be returned. Must be specified in ISO 8601 format. |
| `includeText` | string[] | No | List of strings that must be present in webpage text of results. Currently, only 1 string is supported, of up to 5 words. |
| `excludeText` | string[] | No | List of strings that must not be present in webpage text of results. Currently, only 1 string is supported, of up to 5 words. Checks from the first 1000 words of the webpage text. |
| `context` | string | No | Return page contents as a context string for LLM. When true, combines all result contents into one string. We recommend using 10000+ characters for best results, though no limit works best. Context strings often perform better than highlights for RAG applications. |
| `moderation` | boolean | No | Enable content moderation to filter unsafe content from search results. |
| `contents` | object | No |  |

```bash
curl -X POST 'https://api.orth.sh/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"exa","path":"/search","body":{"query":"<string>","additionalQueries":"<string>","type":"<string>","category":"<string>","userLocation":"<string>","numResults":"<integer>","includeDomains":"<string>","excludeDomains":"<string>","startCrawlDate":"<string>","endCrawlDate":"<string>","startPublishedDate":"<string>","endPublishedDate":"<string>","includeText":"<string>","excludeText":"<string>","context":"<string>","moderation":"<boolean>","contents":"<object>"}}'
```

### Get a task

Retrieve the status and results of a previously created research task.Use the unique researchId returned from POST /research/v1 to poll until the task is finished.

`GET /research/v1/{researchId}`

**Estimated cost:** $0.01

**Docs:** https://exa.ai/docs/reference/research/get-a-task

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `researchId` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |
| `stream` | string | No | Set to "true" to receive real-time updates via Server-Sent Events (SSE) |
| `events` | string | No | Set to "true" to include the detailed event log of all operations performed |

```bash
# Replace {researchId} in "path" with real values before sending
curl -X POST 'https://api.orth.sh/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"exa","path":"/research/v1/{researchId}","method":"GET","query":{"stream":"<string>","events":"<string>"}}'
```

### Find similar links

Find similar links to the link provided and optionally return the contents of the pages.

`POST /findSimilar`

**Estimated cost:** $0.01

**Docs:** https://exa.ai/docs/reference/find-similar-links

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `url` | string | Yes | The url for which you would like to find similar links. |
| `numResults` | integer | No | Number of results to return. Limits vary by search type: With "neural": max 100 results With "deep": max 100 results If you want to increase the num results beyond these limits, contact sales (hello@exa.ai) |
| `includeDomains` | string[] | No | List of domains to include in the search. If specified, results will only come from these domains. |
| `excludeDomains` | string[] | No | List of domains to exclude from search results. If specified, no results will be returned from these domains. |
| `startCrawlDate` | string<date-time> | No | Crawl date refers to the date that Exa discovered a link. Results will include links that were crawled after this date. Must be specified in ISO 8601 format. |
| `endCrawlDate` | string<date-time> | No | Crawl date refers to the date that Exa discovered a link. Results will include links that were crawled before this date. Must be specified in ISO 8601 format. |
| `startPublishedDate` | string<date-time> | No | Only links with a published date after this will be returned. Must be specified in ISO 8601 format. |
| `endPublishedDate` | string<date-time> | No | Only links with a published date before this will be returned. Must be specified in ISO 8601 format. |
| `includeText` | string[] | No | List of strings that must be present in webpage text of results. Currently, only 1 string is supported, of up to 5 words. |
| `excludeText` | string[] | No | List of strings that must not be present in webpage text of results. Currently, only 1 string is supported, of up to 5 words. Checks from the first 1000 words of the webpage text. |
| `context` | string | No | Return page contents as a context string for LLM. When true, combines all result contents into one string. We recommend using 10000+ characters for best results, though no limit works best. Context strings often perform better than highlights for RAG applications. |
| `moderation` | boolean | No | Enable content moderation to filter unsafe content from search results. |
| `contents` | object | No |  |

```bash
curl -X POST 'https://api.orth.sh/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"exa","path":"/findSimilar","body":{"url":"<string>","numResults":"<integer>","includeDomains":"<string>","excludeDomains":"<string>","startCrawlDate":"<string>","endCrawlDate":"<string>","startPublishedDate":"<string>","endPublishedDate":"<string>","includeText":"<string>","excludeText":"<string>","context":"<string>","moderation":"<boolean>","contents":"<object>"}}'
```

### Create a task

Create an asynchronous research task that explores the web, gathers sources, synthesizes findings, and returns results with citations. Can be used to generate:

Structured JSON matching an outputSchema you provide.
A detailed markdown report when no schema is provided.

The API responds immediately with a researchId for polling completion status. For more details, see Exa Research.
Alternatively, you can use the OpenAI compatible chat completions interface.

`POST /research/v1`

**Estimated cost:** $0.01

**Docs:** https://exa.ai/docs/reference/research/create-a-task

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `instructions` | string | Yes | Instructions for what you would like research on. A good prompt clearly defines what information you want to find, how research should be conducted, and what the output should look like. |
| `model` | enum<string> | No | Research model to use. exa-research is faster and cheaper, while exa-research-pro provides more thorough analysis and stronger reasoning. |
| `outputSchema` | object | No | JSON Schema to enforce structured output. When provided, the research output will be validated against this schema and returned as parsed JSON. |

```bash
curl -X POST 'https://api.orth.sh/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"exa","path":"/research/v1","body":{"instructions":"<string>","model":"<string>","outputSchema":"<object>"}}'
```

### Get contents

Get the full page contents, summaries, and metadata for a list of URLs.Returns instant results from our cache, with automatic live crawling as fallback for uncached pages.

`POST /contents`

**Estimated cost:** $0.01

**Docs:** https://exa.ai/docs/reference/get-contents

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `urls` | string[] | Yes | Array of URLs to crawl (backwards compatible with 'ids' parameter). |
| `ids` | string[] | No | Deprecated - use 'urls' instead. Array of document IDs obtained from searches. |
| `text` | string | No | If true, returns full page text with default settings. If false, disables text return. |
| `highlights` | object | No | Text snippets the LLM identifies as most relevant from each page. |
| `summary` | object | No | Summary of the webpage |
| `livecrawl` | enum<string> | No | Options for livecrawling pages.'never': Disable livecrawling (default for neural search).'fallback': Livecrawl when cache is empty.'preferred': Always try to livecrawl, but fall back to cache if crawling fails.'always': Always live-crawl, never use cache. Only use if you cannot tolerate any cached content. This option is not recommended unless consulted with the Exa team. |
| `livecrawlTimeout` | integer | No | The timeout for livecrawling in milliseconds. |
| `subpages` | integer | No | The number of subpages to crawl. The actual number crawled may be limited by system constraints. |
| `subpageTarget` | string | No | Term to find specific subpages of search results. Can be a single string or an array of strings, comma delimited. |
| `extras` | object | No | Extra parameters to pass. |
| `context` | string | No | Return page contents as a context string for LLM. When true, combines all result contents into one string. We recommend using 10000+ characters for best results, though no limit works best. Context strings often perform better than highlights for RAG applications. |

```bash
curl -X POST 'https://api.orth.sh/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"exa","path":"/contents","body":{"urls":"<string>","ids":"<string>","text":"<string>","highlights":"<object>","summary":"<object>","livecrawl":"<string>","livecrawlTimeout":"<integer>","subpages":"<integer>","subpageTarget":"<string>","extras":"<object>","context":"<string>"}}'
```

---

Full details and an interactive quickstart: https://orthogonal.com/discover/exa
