> For the complete documentation index, see [llms.txt](https://developer.eagle.cool/web-api/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.eagle.cool/web-api/api/ai-search.md).

# AI Search

{% hint style="info" %}
**Requires** [**AI Search**](https://eagle.cool/support/article/ai-search) **Plugin.** The AI Search features require the Eagle AI Search plugin to be installed and running. Use the status endpoints to check availability before performing searches.
{% endhint %}

## Endpoints Overview

| Method | Endpoint                              | Description                        |
| ------ | ------------------------------------- | ---------------------------------- |
| GET    | `/api/v2/aiSearch/isInstalled`        | Check if AI Search is installed    |
| GET    | `/api/v2/aiSearch/isReady`            | Check if AI Search is ready        |
| GET    | `/api/v2/aiSearch/isStarting`         | Check if AI Search is starting up  |
| GET    | `/api/v2/aiSearch/isSyncing`          | Check if AI Search is syncing data |
| GET    | `/api/v2/aiSearch/getSyncStatus`      | Get detailed sync status           |
| GET    | `/api/v2/aiSearch/checkServiceHealth` | Check service health               |
| POST   | `/api/v2/aiSearch/searchByText`       | Search by text description         |
| POST   | `/api/v2/aiSearch/searchByBase64`     | Search by image (Base64)           |
| POST   | `/api/v2/aiSearch/searchByItemId`     | Find similar items by item ID      |

***

## Status Endpoints

### GET /api/v2/aiSearch/isInstalled <a href="#is-installed" id="is-installed"></a>

Check whether the AI Search plugin is installed.

```javascript
await fetch("http://localhost:41595/api/v2/aiSearch/isInstalled").then(r => r.json());
```

**Response:**

```json
{
    "status": "success",
    "data": true
}
```

***

### GET /api/v2/aiSearch/isReady <a href="#is-ready" id="is-ready"></a>

Check whether AI Search is fully initialized and ready to accept search queries.

```javascript
await fetch("http://localhost:41595/api/v2/aiSearch/isReady").then(r => r.json());
```

**Response:**

```json
{
    "status": "success",
    "data": true
}
```

***

### GET /api/v2/aiSearch/isStarting <a href="#is-starting" id="is-starting"></a>

Check whether the AI Search service is currently starting up.

```javascript
await fetch("http://localhost:41595/api/v2/aiSearch/isStarting").then(r => r.json());
```

**Response:**

```json
{
    "status": "success",
    "data": false
}
```

***

### GET /api/v2/aiSearch/isSyncing <a href="#is-syncing" id="is-syncing"></a>

Check whether AI Search is currently syncing (indexing) library data.

```javascript
await fetch("http://localhost:41595/api/v2/aiSearch/isSyncing").then(r => r.json());
```

**Response:**

```json
{
    "status": "success",
    "data": false
}
```

***

### GET /api/v2/aiSearch/getSyncStatus <a href="#sync-status" id="sync-status"></a>

Get detailed synchronization status, including progress information.

```javascript
await fetch("http://localhost:41595/api/v2/aiSearch/getSyncStatus").then(r => r.json());
```

**Response:**

```json
{
    "status": "success",
    "data": {
        "isSyncing": false,
        "syncedCount": 12500,
        "totalCount": 12500,
        "progress": 1.0
    }
}
```

***

### GET /api/v2/aiSearch/checkServiceHealth <a href="#health" id="health"></a>

Perform a health check on the AI Search service.

```javascript
await fetch("http://localhost:41595/api/v2/aiSearch/checkServiceHealth").then(r => r.json());
```

**Response:**

```json
{
    "status": "success",
    "data": {
        "healthy": true
    }
}
```

***

## Search Endpoints

### POST /api/v2/aiSearch/searchByText <a href="#search-by-text" id="search-by-text"></a>

Search for items using a natural language text description. The AI model finds visually or semantically matching items.

#### Request Body

* `query` string (required) — Text description to search for
* `options` Object (optional)
  * `limit` integer — Maximum number of results (default varies by AI Search config)

#### Response

```json
{
    "status": "success",
    "data": {
        "results": [
            {
                "item": {
                    "id": "M3QSGJNQTC2DG",
                    "name": "sunset-beach",
                    "ext": "jpg",
                    "width": 1920,
                    "height": 1080,
                    "tags": ["nature", "sunset"],
                    "star": 4
                },
                "score": 0.892
            },
            {
                "item": {
                    "id": "K7XPWQBN9TC3F",
                    "name": "golden-hour",
                    "ext": "png",
                    "width": 2560,
                    "height": 1440,
                    "tags": ["photography"],
                    "star": 3
                },
                "score": 0.756
            }
        ]
    }
}
```

#### Examples

```javascript
// Search by text description
await fetch("http://localhost:41595/api/v2/aiSearch/searchByText", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ query: "an orange cat sitting on a windowsill" })
}).then(r => r.json());

// Search with result limit
await fetch("http://localhost:41595/api/v2/aiSearch/searchByText", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
        query: "minimalist logo design",
        options: { limit: 20 }
    })
}).then(r => r.json());
```

***

### POST /api/v2/aiSearch/searchByBase64 <a href="#search-by-image" id="search-by-image"></a>

Find visually similar items by providing a Base64-encoded image.

#### Request Body

* `base64` string (required) — Base64-encoded image data
* `options` Object (optional)
  * `limit` integer — Maximum number of results

#### Response

Same format as `searchByText` — returns an array of `{ item, score }` results sorted by similarity.

#### Example

```javascript
await fetch("http://localhost:41595/api/v2/aiSearch/searchByBase64", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
        base64: "/9j/4AAQSkZJRg...",
        options: { limit: 10 }
    })
}).then(r => r.json());
```

***

### POST /api/v2/aiSearch/searchByItemId <a href="#search-by-item" id="search-by-item"></a>

Find items visually similar to an existing item in the library.

#### Request Body

* `itemId` string (required) — The item ID to find similar items for
* `options` Object (optional)
  * `limit` integer — Maximum number of results

#### Response

Same format as `searchByText` — returns an array of `{ item, score }` results sorted by similarity.

#### Example

```javascript
await fetch("http://localhost:41595/api/v2/aiSearch/searchByItemId", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
        itemId: "M3QSGJNQTC2DG",
        options: { limit: 10 }
    })
}).then(r => r.json());
```

***

## Recommended Workflow

1. **Check availability** — Call `isInstalled` and `isReady` before searching
2. **Wait if starting** — If `isStarting` returns `true`, poll until `isReady` becomes `true`
3. **Check sync status** — Use `getSyncStatus` to verify the index is up to date
4. **Search** — Use `searchByText` for description-based search, `searchByBase64` for reverse image search, or `searchByItemId` to find similar items

```javascript
// Step 1: Verify AI Search is ready
const { data: isReady } = await fetch("http://localhost:41595/api/v2/aiSearch/isReady")
    .then(r => r.json());

if (isReady) {
    // Step 2: Perform search
    const results = await fetch("http://localhost:41595/api/v2/aiSearch/searchByText", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ query: "sunset landscape", options: { limit: 10 } })
    }).then(r => r.json());

    console.log(results.data.results);
}
```
