> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.eyelevel.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.eyelevel.ai/_mcp/server.

## Introduction

This tutorial covers the GroundX search API.

If you'd rather have an agent search and answer for you instead of wiring this
up in application code, see [Use GroundX With Your Agent](/documentation/agent-harness/ingest-search-and-answer-with-an-agent).

**Under the hood, the GroundX Search API does the following:**

* Analyzes your search query and improves it if necessary, then runs a semantic search
  that avoids the hallucination trap most RAG apps fall into with vectorized search.

* Searches the GroundX buckets where your content and its extra search data are stored.
  GroundX's extra search data keeps your content in its original context. The Search API
  returns more than raw text chunks: a response bundled with intelligible text chunks,
  extra search data, automatically generated document and section summaries, source URL,
  and a readable, contextualized, performant version of the text chunk ready for LLM use.

* Uses a proprietary re-ranker that scores every chunk on how well it answers the
  original question, so the most trustworthy results are on top.

* Merges all of this into a simple text block you can send to the LLM of your choice,
  for accurate, contextualized, hallucination-free responses from your content.

## LLM Integration

GroundX handles the heavy lifting in the background. Here's the flow:

1. Make an API search request.

*Example:*

**`Python`**

```python title="Python"
import os
from groundx import GroundX

client = GroundX(
    api_key=os.environ["GROUNDX_API_KEY"],
)

bucket_id = 0
query = "How many workers walk to work in the Bay Area?"

result = client.search.content(
    id=bucket_id, 
    query=query,
)

llm_text = result.search.text
```

**`TypeScript`**

```typescript title="TypeScript"
import { GroundXClient } from "groundx";

const client = new GroundXClient({
    apiKey: process.env.GROUNDX_API_KEY,
});

const bucketId = 0;
const query = "How many workers walk to work in the Bay Area?";

const result = await client.search.content(
    bucketId,
    {
        query: query,
    }
);

const llmText = result.search.text;
```

> **API Key**
>
> * Go to the [GroundX dashboard](https://dashboard.groundx.ai/auth/login) to get your API key.
> * GroundX can be installed for Python via [pip install groundx](https://pypi.org/project/groundx/)
> * GroundX can be installed for NPM via [npm i -s groundx](https://www.npmjs.com/package/groundx)

2. Retrieve the `search.text` property and pass it on to the LLM of your choice.

*Example:*

**`Python`**

```python title="Python"
import os
from openai import OpenAI
openai_client = OpenAI(
    api_key=os.environ["OPENAI_API_KEY"],
)

completion = openai_client.chat.completions.create(
  model="gpt-4o-mini",
  messages=[
    {
        "role": "system", 
        "content": """Get response from this data:
===
%s
===
"""
      % (llm_text),
    },
    {
        "role": "user", 
        "content": query,
    }
  ]
)
```

**`TypeScript`**

```typescript title="TypeScript"
import OpenAI from "openai";

const openaiClient = new OpenAI({
    apiKey: process.env.OPENAI_API_KEY,
});

const chatCompletion = await openaiClient.chat.completions.create({
  model: "gpt-4o-mini",
  messages: [
    {
      "role": "system",
      "content": `Respond only with:
===
${llmText}
===
`
    },
    {
       "role": "user",   
       "content": query
    },
  ],
});
```

> **LLM API**
>
> Make sure to get the API key, endpoints, and SDK from your LLM provider. For example, if using ChatGPT, go to the [OpenAI documentation](https://platform.openai.com/docs/overview)

3. Get a response from the LLM using your retrieved data.

*Example using:*

**`Python`**

```python title="Python"
print(completion.choices[0].message.content)
```

**`TypeScript`**

```typescript title="TypeScript"
console.log(chatCompletion.choices[0].message.content);
```

**The end result**: *retrievals that outperform traditional vector systems and boost the accuracy of LLM completions.*

## Getting Started

The example above used placeholder values. Here's the same flow with more detail on each parameter.

To make an API request, do the following:

### Ingest content

Make sure you've already uploaded the content you want to search to a GroundX bucket. See the documentation on content ingestion for more information.

### Set up environment

Set up your environment with the GroundX SDK.

**`Python`**

```python title="Python"
from groundx import GroundX

client = GroundX(
    api_key="YOUR_API_KEY",
)
```

**`TypeScript`**

```typescript title="TypeScript"
import { GroundXClient } from "groundx";

const client = new GroundXClient({ 
    apiKey: "YOUR_API_KEY"
});
```

### Bucket or Group ID

Get the ID of the group or bucket you want to search.

*Example:*

**`Python`**

```python title="Python"
bucket_id = 3839
```

**`TypeScript`**

```typescript title="TypeScript"
const bucketId = 3839;
```

> **Note**
>
> See the documentation on content ingestion for more information to learn about bucket creation.

## Search Query String

Create a search query string — a question or the keywords you want to search for.

If the string is more than 30 words long, GroundX automatically rewrites it with keywords using its internal LLM.

GroundX processes the string against your content and its extra search data to retrieve the most relevant results.

*Example:*

**`Python`**

```python title="Python"
query = "How many workers walk to work in the Bay Area?"
```

**`TypeScript`**

```typescript title="TypeScript"
const query = "How many workers walk to work in the Bay Area?";
```

## Number of Results

Optionally, set the number of results returned by the search request. By default, search queries return up to 20 results.

*Example:*

**`Python`**

```python title="Python"
n = 10
```

**`TypeScript`**

```typescript title="TypeScript"
const n = 10;
```

## API Request

Make the API search request, including the ID and search query string in the request body.

In addition to `id`, `query`, and `n`, the search request accepts a few more optional
parameters:

| Parameter   | Default | Description                                                                                                                                                                                                                                                         |
| ----------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `verbosity` | `1`     | Controls whether `search.results` is returned and whether each result includes `searchData`. `0` omits `search.results` entirely; `1` returns `search.results` without `searchData`; `2` returns `search.results` with the full `searchData` object on each result. |
| `relevance` | `10.0`  | Minimum relevance score a result must meet to be included. Results scoring below this threshold are excluded.                                                                                                                                                       |
| `filter`    | —       | A pre-filter expression (MongoDB-style) used to restrict which documents are eligible to appear in results, based on document metadata. See the documentation on filtering content for more information.                                                            |

For search rate limits (concurrent requests, requests per minute) and error-handling
guidance, see the [Direct SDK/API Quickstart's Errors and Rate Limits section](/documentation/get-started/direct-sdk-api-quickstart#errors-and-rate-limits).

*Example:*

**`Python`**

```python title="Python"
response = client.search.content(
    id=bucket_id, 
    query=query,
    n=n,
)

print(response.search.text)
```

**`TypeScript`**

```typescript title="TypeScript"
const response = await client.search.content(
    bucketId,
    {
        query: query,
        n: n,
    }
)

console.log(response.search.text)
```

## API Response

The request returns a Search object.

**The Search schema includes the following details.**

*Response sample:*

```json
{
    "count": 10,
    "query": "How many workers walk to work in the Bay Area?",
    "results":  [
         {
            "bucketId": 6839,
            "documentId": "81111b9e-ff13-41ef-a89a-af667a4b1cac",
            "chunkId": "3af6a2c1-9e4d-4c2a-8f36-1e2f0a5d7b90",
            "processId": "2b7e6a2c-1e4d-4c2a-8f36-1e2f0a5d7b90",
            "score": 357.09656,
            "fileSummary": "This document is a detailed report from the Healthy Communities Data and Indicators Project by UCSF and CDPH...",
            "sectionSummary": "Given a row from the provided TSV table, this row represents data about the commuting habits of workers in a specific region in California over two time periods: 2005-2007 and 2008...",
            "searchData": {
                "documentSummary": "This document is a detailed report from the Healthy Communities Data and Indicators Project by UCSF and CDPH...",
                "sectionSummary": "Given a row from the provided TSV table, this row represents data about the commuting habits of workers in a specific region in California over two time periods: 2005-2007 and 2008...",
                "fullTitle": "Percent of population aged 16 years or older whose commute to work is 10 or more minutes/day by walking or biking",
                "publisher": "California Department of Public Health"
            },
            "sourceUrl": "https://upload.groundx.ai/file/hciwalkbicycle778narrativeandexamples3-26-14.pdf",
            "suggestedText": "In the Bay Area between 2005-2007, 70,287 out of 3,122,743 workers, or 2.25%, walked for 10 or more minutes per day. This number increased to 81,737 out of 3,202,761 workers, or 2.55%, in the 2008-2010 period. In Butte, 1,266 out of 85,042 workers, or 1.49%, walked for 10 or more minutes per day between 2005-2007. This increased to 1,678...",
            "text": "\t|\t\t|\t2005-2007\t|\t\t|\t\t|\t2008-2010\n\t|\tWorkers who\t|\t\t|\t\t|\tWorkers who\n\t|\twalk ≥10\t|\t\t|\t\t|\twalk ≥10\nRegion name\t|\tmin / day\t|\tTotal...",
            "multimodalUrl": "https://upload.groundx.ai/file/hciwalkbicycle778narrativeandexamples3-26-14-table2.jpg",
            "boundingBoxes": [
                {
                    "pageNumber": 2,
                    "topLeftX": 72.5,
                    "topLeftY": 140.2,
                    "bottomRightX": 520.8,
                    "bottomRightY": 310.6
                }
            ],
            "pages": [
                {
                    "number": 2,
                    "imageUrl": "https://upload.groundx.ai/file/hciwalkbicycle778narrativeandexamples3-26-14-page2.jpg",
                    "width": 1700,
                    "height": 2200
                }
            ]
            }
    ],
    "score": 369.19244,
    "text": "fullTitle: Percent of population aged 16 years or older whose commute to work is 10 or more minutes/day by walking or biking\npublisher: California Department of Public Health\nIn the Bay Area between 2005-2007, 70,287 out of 3,122,743 workers, or 2.25%, walked for 10 or more minutes per day. This number increased to 81,737 out of 3,202,761 workers, or 2.55%, in the 2008-2010 period. In Butte, 1,266 out of 85,042 workers, or 1.49%, walked for 10 or more minutes per day between 2005-2007. This increased to 1,678 out of 81,321 workers, or 2.06%, in 2008-2010..."
}
```

### Recommended data

The most significant property in the search response is `text`: a string containing the
automatically rewritten text chunks and the extra search data added to the original
content. This content, generated by GroundX's internal LLM, is intelligible,
contextualized, and machine-understandable — pass it straight to your LLM.

### Advanced data handling

We recommend passing `search.text` directly to your LLM, but you can also add your own
logic around the `search.results` property.

`results` is a list of the original text chunks that matched the search query, ordered by
a score based on semantic search and re-ranking. Each result includes the suggested text
mentioned above — the more intelligible, performant version of the text chunk.

Each result also carries automatically generated extra search data, like summaries of the
document and section the chunk is found in. As of SDK 3.5.4, the document-level and
section-level summaries are also available directly on each result as the top-level
`fileSummary` and `sectionSummary` fields, in addition to the `documentSummary`/
`sectionSummary` pair inside `searchData` — use the top-level fields when you just need
the summary text and don't need the rest of `searchData`.

The GroundX URL, document ID, and bucket ID of the source content are provided too.

Each result also carries a unique `chunkId`, and — when the chunk is a visual element such
as a table or chart — a `multimodalUrl` pointing to an image clipping of that element. For
source-attribution UIs, `boundingBoxes` gives the coordinates of where the chunk appears
on its source page(s), and `pages` gives the rendered page image(s) (with pixel
dimensions) those coordinates are relative to.

Use `verbosity` (see API Request above) to control whether `results` is returned at all,
and whether each result includes the full `searchData` object.

## Final Details

You're now ready to integrate GroundX with your LLM to generate accurate,
hallucination-free responses from your own content.

## Next Steps

* For tips on turning search results into consistent, high-quality LLM responses, see
  [Prompting and Integration](/documentation/guides/prompting-and-integration).
* Want an agent to run search and answer for you instead of wiring this up in
  application code? See [Use GroundX With Your Agent](/documentation/agent-harness/ingest-search-and-answer-with-an-agent) (also
  linked in the Introduction above).