---
title: "Search API"
description: "Search a bot's knowledge with the Chat Thing REST API and get back the most relevant passages, each with the data source row it came from."
canonical_url: "https://chatthing.ai/docs/developers/search-api"
last_updated: "2026-10-21"
---

# Search API

**Available on:** Standard, Pro, Enterprise plans.

Use the search API to run the same semantic search your bot uses when it answers, from your own code. You send a question and get back the most relevant passages from the bot's data sources, best match first. Each passage tells you which data source row it came from, such as a Notion page, a web page or a file, so you can match it to your own records.

> **Before you start**
>
> You need the API channel turned on for your bot, its **Channel ID** and a **Secret key**. The API channel is on the Standard, Pro and Enterprise plans. See [API overview](https://chatthing.ai/docs/developers/api-overview#authentication).

Search covers every type of data source on the bot, not only manual ones. It only finds content that has finished syncing.

Each channel can search 120 times a minute. Searches don't use message tokens.

## Search a bot's knowledge

```text
POST https://app.chatthing.ai/api/public/channels/{channelId}/2.0/search
```

It also works with `1.0` in place of `2.0`. Every request needs these headers:

```bash
Content-Type: application/json
X-API-Secret-Key: {secretKey}
```

| Field | Type | Description |
| --- | --- | --- |
| `query` | string | What to search for, up to 2,000 characters. A question or a short description works best |
| `limit` | integer | Optional. Most passages to return, from 1 to 100. Default `10` |
| `dataSourceId` | string | Optional. Only search this data source. It must belong to the channel's bot |
| `minRelevance` | number | Optional. Lowest similarity to include, from 0 to 1. Defaults to the bot's **Document relevance** setting |

**curl**

```bash
curl --request POST \
  --url https://app.chatthing.ai/api/public/channels/{channelId}/2.0/search \
  --header 'Content-Type: application/json' \
  --header 'X-API-Secret-Key: {secretKey}' \
  --data '{"query": "How do I reset my password?", "limit": 5}'
```

**JavaScript**

```javascript
const response = await fetch(
  `https://app.chatthing.ai/api/public/channels/${channelId}/2.0/search`,
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-API-Secret-Key": secretKey,
    },
    body: JSON.stringify({ query: "How do I reset my password?", limit: 5 }),
  },
);
const { results } = await response.json();
```

**Python**

```python
import requests

url = f"https://app.chatthing.ai/api/public/channels/{channel_id}/2.0/search"
headers = {
    "Content-Type": "application/json",
    "X-API-Secret-Key": secret_key,
}

response = requests.post(
    url, headers=headers, json={"query": "How do I reset my password?", "limit": 5}
)
results = response.json()["results"]
```

```json
{
  "success": true,
  "results": [
    {
      "id": "7f0c1d52-3c2e-4f0e-9a51-9d2b8f3c6a10",
      "content": "To reset your password, open Settings and choose Security...",
      "meta": {
        "url": "https://example.com/help/reset-password",
        "title": "Reset your password"
      },
      "similarity": 0.89,
      "rank": 1,
      "source": {
        "dataSourceId": "41559b21-b8ff-44c3-8658-1c9e34273070",
        "dataSourceRowId": "0b9d3a77-5d0e-4c1f-8f4e-2f6a1c9e8b33",
        "parentDataSourceRowId": null,
        "type": "WEB",
        "config": {
          "url": "https://example.com/help/reset-password"
        }
      }
    }
  ]
}
```

## The result object

| Field | Type | Description |
| --- | --- | --- |
| `id` | string | The passage's id |
| `content` | string | The passage text, in markdown |
| `meta` | object or null | Extra details saved with the passage, such as a web page's `url` and `title` |
| `similarity` | number | How closely the passage matches the query, from 0 to 1 |
| `rank` | integer | Position in the results, starting at 1 |
| `source` | object or null | The data source row the passage came from. `null` if the row has since been deleted |

Long documents are split into several passages, so more than one result can share the same `source`.

## The source object

| Field | Type | Description |
| --- | --- | --- |
| `dataSourceId` | string | The data source the row belongs to |
| `dataSourceRowId` | string | The row the passage came from |
| `parentDataSourceRowId` | string or null | The row this one was found under, such as the Notion database a page belongs to |
| `type` | string | The data source type: `NOTION`, `WEB`, `FILE`, `GOOGLE`, `RSS`, `YOUTUBE` or `MANUAL` |
| `config` | object | How the row identifies its content. Its fields depend on `type`, and only the fields below are returned |

The `config` fields for each type:

| Type | Fields |
| --- | --- |
| `NOTION` | `id` (the Notion page or database id), `type` (`page` or `database`), and sometimes `title` |
| `WEB` | `url` |
| `RSS`, `YOUTUBE` | `url` |
| `FILE` | `path`, `file.name` (the uploaded file's name), and `id` on some older rows |
| `GOOGLE` | `id` (the Google Drive file id), `name` and `mimeType` |
| `MANUAL` | `file.name` (the row's name) and `path` |

## Errors

| Status | Meaning |
| --- | --- |
| `400` | The request body isn't valid, for example an empty `query` or a `limit` over 100 |
| `403` | The secret key is wrong |
| `404` | The channel doesn't exist or is turned off, or `dataSourceId` isn't one of the bot's data sources |
| `429` | Too many searches. Each channel can search 120 times a minute |
| `500` | The search failed. Try again |

## Related

- [API overview](https://chatthing.ai/docs/developers/api-overview): Base URL, API keys, authentication headers, versions, error codes and usage limits for the Chat Thing REST API.
- [Data sources API](https://chatthing.ai/docs/developers/data-sources-api): Create, update, sync and delete a bot's manual data sources and their entries with the Chat Thing REST API, to keep its knowledge in step with your system.
