When using the Exa API, you can request different types of content to be returned for each search result. The three content return types are:

Text (text=True):

Returns the full text content of the result, such as the main body of an article or webpage. This is extractive content directly taken from the source.

Highlights (highlights=True):

Delivers key excerpts from the text that are most relevant to your search query, emphasizing important information within the content. This is also extractive content from the source.

Summary (summary=True):

Provides a concise summary generated from the text, tailored to a specific query you provide. This is abstractive content created by processing the source text using Gemini Flash.

Structured Summaries

You can also request structured summaries by providing a JSON schema:

{
  "summary": {
    "query": "Provide company information",
    "schema": {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Company Information",
      "type": "object",
      "properties": {
        "name": { "type": "string", "description": "The name of the company" },
        "industry": { "type": "string", "description": "The industry the company operates in" },
        "foundedYear": { "type": "number", "description": "The year the company was founded" }
      },
      "required": ["name", "industry"]
    }
  }
}

The API will return the summary as a JSON string that matches your schema structure, which you can parse to access the structured data.

By specifying these options in your API call, you can control the depth and focus of the information returned, making your search results more actionable and relevant.

To see the full configurability of the contents returns, check out our Dashboard and sample queries.

Images and favicons

When making API requests, Exa can return:

  • Image URLs from the source content (you can specify how many images you want returned)
  • Website favicons associated with each search result (when available)

Crawl Errors

The contents endpoint provides detailed status information for each URL through the statuses field in the response. The endpoint only returns an error if there’s an internal issue on Exa’s end - all other cases are reported through individual URL statuses.

Each response includes a statuses array with status information for each requested URL:

{
  "results": [...],
  "statuses": [
    {
      "id": "https://example.com",
      "status": "success" | "error",
      "error": {
        "tag": "CRAWL_NOT_FOUND" | "CRAWL_TIMEOUT" | "CRAWL_LIVECRAWL_TIMEOUT" | "SOURCE_NOT_AVAILABLE" | "CRAWL_UNKNOWN_ERROR",
        "httpStatusCode": 404 | 408 | 403 | 500
      }
    }
  ]
}

The error tags correspond to different failure scenarios:

  • CRAWL_NOT_FOUND: Content not found (HTTP 404)
  • CRAWL_TIMEOUT: The target page returned a timeout error (HTTP 408)
  • CRAWL_LIVECRAWL_TIMEOUT: The livecrawlTimeout parameter limit was reached during crawling
  • SOURCE_NOT_AVAILABLE: Access forbidden or source unavailable (HTTP 403)
  • CRAWL_UNKNOWN_ERROR: Other errors (HTTP 500+)

To handle errors, check the statuses field for each URL:

result = exa.get_contents(["https://example.com"])
for status in result.statuses:
    if status.status == "error":
        print(f"Error for {status.id}: {status.error.tag} ({status.error.httpStatusCode})")

This allows you to handle different failure scenarios appropriately for each URL in your request.