---
title: Overview
description: Cloudflare AI Search is a managed search service. Index your content and query it with natural language from a Workers binding, REST API, or MCP server.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Overview

The search primitive for your applications and agents.

 Available on all plans 

AI Search lets you add search to any application or agent without having to build an entire retrieval infrastructure. Create an instance, give it your data, and search it with natural language.

You can use AI Search for:

* Documentation and knowledge base search
* AI agent tool use and memory
* Per-tenant or per-agent file search

[ Get started ](https://developers.cloudflare.com/ai-search/get-started/)[ Watch AI Search demo ](https://www.youtube.com/watch?v=JUFdbkiDN2U)

Latest update

New AI Search instances created after April 16, 2026 include [managed storage](https://developers.cloudflare.com/ai-search/configuration/data-source/built-in-storage/), vector index, and web crawling. [View limits and pricing](https://developers.cloudflare.com/ai-search/platform/limits-pricing/).

---

## Features

###  Automated indexing 

Automatically and continuously index your data source, keeping your content fresh without manual reprocessing.

[ View indexing ](https://developers.cloudflare.com/ai-search/configuration/indexing/syncing/) 

###  Metadata filtering 

Define custom metadata fields and filter search results by category, version, language, or any attribute you define.

[ Add filters ](https://developers.cloudflare.com/ai-search/configuration/indexing/metadata/) 

###  Hybrid search 

Combine semantic and keyword matching in the same query for more accurate results.

[ Configure hybrid search ](https://developers.cloudflare.com/ai-search/configuration/indexing/hybrid-search/) 

###  MCP and UI snippets 

Every instance includes a built-in MCP endpoint for AI agents and embeddable search components for your website.

[ Connect agents ](https://developers.cloudflare.com/ai-search/api/search/mcp/) 

---

## Related products

**[Workers AI](https://developers.cloudflare.com/workers-ai/)** 

Run machine learning models, powered by serverless GPUs, on Cloudflare's global network.

**[AI Gateway](https://developers.cloudflare.com/ai-gateway/)** 

Observe and control your AI applications with caching, rate limiting, request retries, model fallback, and more.

**[Vectorize](https://developers.cloudflare.com/vectorize/)** 

Build full-stack AI applications with Vectorize, Cloudflare's vector database.

**[Workers](https://developers.cloudflare.com/workers/)** 

Build serverless applications and deploy instantly across the globe for exceptional performance, reliability, and scale.

**[R2](https://developers.cloudflare.com/r2/)** 

Store large amounts of unstructured data without the costly egress bandwidth fees associated with typical cloud storage services.

---

## More resources

[Get started](https://developers.cloudflare.com/ai-search/get-started/) 

Create your first AI Search instance and run your first query.

[Developer Discord](https://discord.cloudflare.com) 

Connect with the Workers community on Discord to ask questions, share what you are building, and discuss the platform with other developers.

[@CloudflareDev](https://x.com/cloudflaredev) 

Follow @CloudflareDev on Twitter to learn about product announcements, and what is new in Cloudflare Workers.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}}]}
```

---

---
title: Get started
description: Create fully-managed, retrieval-augmented generation pipelines with Cloudflare AI Search.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Get started

AI Search is a managed search service. Connect a website, an R2 bucket, or upload your own documents, and AI Search indexes your content for natural language queries.

## Prerequisites

If you plan to use an R2 bucket as your data source, you must have an active [R2 subscription](https://developers.cloudflare.com/r2/get-started/) before creating your AI Search instance. If you plan to use a website or upload files directly, no additional setup is required.

## Choose your setup method

[ Dashboard ](https://developers.cloudflare.com/ai-search/get-started/dashboard/) Create and configure AI Search using the Cloudflare dashboard. 

[ API ](https://developers.cloudflare.com/ai-search/get-started/api/) Create AI Search instances programmatically using the REST API. 

[ Wrangler commands ](https://developers.cloudflare.com/ai-search/get-started/wrangler/) Create and manage AI Search instances from the command line. 

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/get-started/","name":"Get started"}}]}
```

---

---
title: REST API
description: Create AI Search instances programmatically using the REST API.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# REST API

This guide walks you through creating an AI Search instance using the REST API.

## 1\. Create an API token

You need an API token with **AI Search:Edit** and **AI Search:Run** permissions.

1. In the Cloudflare dashboard, go to **My Profile** \> **API Tokens**.  
[ Go to **API Tokens** ](https://dash.cloudflare.com/profile/api-tokens)
2. Select **Create Token**.
3. Select **Create Custom Token**.
4. Enter a **Token name**, for example `AI Search Manager`.
5. Under **Permissions**, add two permissions:  
   * **Account** \> **AI Search:Edit**  
   * **Account** \> **AI Search:Run**
6. Select **Continue to summary**, then select **Create Token**.
7. Copy and save the token value. This is your `API_TOKEN`.

## 2\. Create an AI Search instance

Use the [Create instance API](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/instances/methods/create/) to create an instance. Replace `<ACCOUNT_ID>` with your [account ID](https://developers.cloudflare.com/fundamentals/account/find-account-and-zone-ids/).

Terminal window

```

curl -X POST "https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai-search/instances" \

  -H "Authorization: Bearer <API_TOKEN>" \

  -H "Content-Type: application/json" \

  --data '{

    "id": "my-instance"

  }'


```

### Connect a data source (optional)

You can create an instance that is connected to a website or R2 bucket as a data source. AI Search indexes the content automatically.

**Website:**

Automatically crawl and index a [website](https://developers.cloudflare.com/ai-search/configuration/data-source/website/) that you own.

Terminal window

```

curl -X POST "https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai-search/instances" \

  -H "Authorization: Bearer <API_TOKEN>" \

  -H "Content-Type: application/json" \

  --data '{

    "id": "my-instance",

    "type": "web-crawler",

    "source": "example.com"

  }'


```

**R2 bucket:**

Index documents stored in an [R2 bucket](https://developers.cloudflare.com/ai-search/configuration/data-source/r2/). Connecting an R2 bucket requires a [service API token](https://developers.cloudflare.com/ai-search/configuration/indexing/service-api-token/). If you have never created an R2-backed instance before, you need to pass the `token_id` field in the create request. Refer to the [service API token configuration](https://developers.cloudflare.com/ai-search/configuration/indexing/service-api-token/) for setup instructions.

Terminal window

```

curl -X POST "https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai-search/instances" \

  -H "Authorization: Bearer <API_TOKEN>" \

  -H "Content-Type: application/json" \

  --data '{

    "id": "my-instance",

    "type": "r2",

    "source": "<R2_BUCKET_NAME>",

    "token_id": "<SERVICE_TOKEN_ID>"

  }'


```

## 3\. Add content

If you did not create an instance that is connected to a data source, upload files using the [Items API](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/namespaces/subresources/instances/subresources/items/methods/upload/). You can skip this step if you connected a website or R2 bucket.

Terminal window

```

curl -X POST "https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai-search/instances/my-instance/items" \

  -H "Authorization: Bearer <API_TOKEN>" \

  -F "file=@/path/to/your/file.pdf"


```

AI Search indexes uploaded files automatically.

## 4\. Check indexing status

Check if your content has finished indexing.

Terminal window

```

curl "https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai-search/instances/my-instance/stats" \

  -H "Authorization: Bearer <API_TOKEN>"


```

## Try it out

Once indexing is complete, run your first query.

Terminal window

```

curl "https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai-search/instances/my-instance/search" \

  -H "Authorization: Bearer <API_TOKEN>" \

  -H "Content-Type: application/json" \

  -d '{

    "messages": [

      {

        "content": "How do I get started?",

        "role": "user"

      }

    ]

  }'


```

You can also test queries in the dashboard by going to your instance and selecting the **Playground** tab.

## Add to your application

[ Workers binding ](https://developers.cloudflare.com/ai-search/api/search/workers-binding/) Query AI Search directly from your Workers code. 

[ REST API ](https://developers.cloudflare.com/ai-search/api/search/rest-api/) Query AI Search using HTTP requests. 

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/get-started/","name":"Get started"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/get-started/api/","name":"REST API"}}]}
```

---

---
title: Dashboard
description: Create and configure AI Search using the Cloudflare dashboard.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Dashboard

This guide walks you through creating an AI Search instance using the Cloudflare dashboard.

## Create an AI Search instance

1. Go to **AI Search** in the Cloudflare dashboard.  
[ Go to **AI Search** ](https://dash.cloudflare.com/?to=/:account/ai/ai-search)
2. Select **Create Instance**.
3. Name your AI Search instance.
4. Optionally connect a [data source](https://developers.cloudflare.com/ai-search/configuration/data-source/) such as a website you own or an R2 bucket.
5. Review your configurations.
6. Select **Create**.

## Upload content

Once an instance has been created, you can upload files directly from the dashboard.

1. Go to **AI Search** in the Cloudflare dashboard.  
[ Go to **AI Search** ](https://dash.cloudflare.com/?to=/:account/ai/ai-search)
2. Select your instance.
3. Select the **Items** tab.
4. Upload your files. AI Search indexes them automatically.

## Try it out

Once your content is indexed, you can run your first query.

1. Go to your AI Search instance.
2. Select the **Playground** tab.
3. Select **Chat** or **Search**.
4. Enter a query to test the response.

## Add to your application

There are multiple ways you can connect AI Search to your application:

[ Workers Binding ](https://developers.cloudflare.com/ai-search/api/search/workers-binding/) Query AI Search directly from your Workers code. 

[ REST API ](https://developers.cloudflare.com/ai-search/api/search/rest-api/) Query AI Search using HTTP requests. 

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/get-started/","name":"Get started"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/get-started/dashboard/","name":"Dashboard"}}]}
```

---

---
title: Wrangler commands
description: Create and manage AI Search instances from the command line.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Wrangler commands

This guide walks you through creating an AI Search instance using the [Wrangler CLI](https://developers.cloudflare.com/workers/wrangler/).

## 1\. Install Wrangler

Install [Wrangler](https://developers.cloudflare.com/workers/wrangler/), the command-line tool for Cloudflare Workers and developer platform products.

 npm  yarn  pnpm  bun 

```
npm install wrangler
```

```
yarn install wrangler
```

```
pnpm install wrangler
```

```
bun install wrangler
```

## 2\. Create an AI Search instance

Create a new instance.

Terminal window

```

wrangler ai-search create my-instance


```

You can upload files to the instance using the [dashboard](https://developers.cloudflare.com/ai-search/get-started/dashboard/#upload-content) or the [REST API](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/namespaces/subresources/instances/subresources/items/methods/upload/).

### Connect a data source (optional)

You can optionally connect a website or R2 bucket when creating the instance.

**Website:**

Automatically crawl and index a [website](https://developers.cloudflare.com/ai-search/configuration/data-source/website/) that you own.

Terminal window

```

wrangler ai-search create my-instance --type web-crawler --source developers.cloudflare.com


```

**R2 bucket:**

Index documents stored in an [R2 bucket](https://developers.cloudflare.com/ai-search/configuration/data-source/r2/).

Terminal window

```

wrangler ai-search create my-instance --type r2 --source my-bucket


```

## 3\. Check indexing status

Check if your content has finished indexing by running the `stats` command.

Terminal window

```

wrangler ai-search stats my-instance


```

## 4\. Test your instance

Once indexing is complete, run a search query against your instance.

Terminal window

```

wrangler ai-search search my-instance --query "What is Cloudflare?"


```

For the full list of available commands, refer to [Wrangler commands](https://developers.cloudflare.com/ai-search/wrangler-commands/).

## Add to your application

[ Workers binding ](https://developers.cloudflare.com/ai-search/api/search/workers-binding/) Query AI Search directly from your Workers code. 

[ REST API ](https://developers.cloudflare.com/ai-search/api/search/rest-api/) Query AI Search using HTTP requests. 

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/get-started/","name":"Get started"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/get-started/wrangler/","name":"Wrangler commands"}}]}
```

---

---
title: Wrangler commands
description: Manage AI Search instances from the command line using Wrangler.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Wrangler commands

## `ai-search list`

List all AI Search instances

* [  npm ](#tab-panel-6489)
* [  pnpm ](#tab-panel-6490)
* [  yarn ](#tab-panel-6491)

Terminal window

```

npx wrangler ai-search list


```

Terminal window

```

pnpm wrangler ai-search list


```

Terminal window

```

yarn wrangler ai-search list


```

* `--namespace` ` string ` alias: --n default: default  
The namespace to list instances from.
* `--json` ` boolean ` default: false  
Return output as clean JSON
* `--page` ` number ` default: 1  
Page number of the results, can configure page size using "per-page"
* `--per-page` ` number `  
Number of instances to show per page

Global flags

* `--v` ` boolean ` alias: --version  
Show version number
* `--cwd` ` string `  
Run as if Wrangler was started in the specified directory instead of the current working directory
* `--config` ` string ` alias: --c  
Path to Wrangler configuration file
* `--env` ` string ` alias: --e  
Environment to use for operations, and for selecting .env and .dev.vars files
* `--env-file` ` string `  
Path to an .env file to load - can be specified multiple times - values from earlier files are overridden by values in later files
* `--experimental-provision` ` boolean ` aliases: --x-provision default: true  
Experimental: Enable automatic resource provisioning
* `--experimental-auto-create` ` boolean ` alias: --x-auto-create default: true  
Automatically provision draft bindings with new resources
* `--install-skills` ` boolean ` default: false  
Install Cloudflare agents skills, if not already present, without asking the user for confirmation

## `ai-search create`

Create a new AI Search instance

* [  npm ](#tab-panel-6492)
* [  pnpm ](#tab-panel-6493)
* [  yarn ](#tab-panel-6494)

Terminal window

```

npx wrangler ai-search create [NAME]


```

Terminal window

```

pnpm wrangler ai-search create [NAME]


```

Terminal window

```

yarn wrangler ai-search create [NAME]


```

* `[NAME]` ` string ` required  
The name of the AI Search instance to create (must be unique within its namespace).
* `--namespace` ` string ` alias: --n  
The namespace to create the instance in.
* `--source` ` string `  
Data source identifier (R2 bucket name or web URL).
* `--type` ` string `  
The source type for the instance.
* `--embedding-model` ` string `  
Embedding model to use.
* `--generation-model` ` string `  
LLM model for chat completions.
* `--chunk-size` ` number `  
Chunk size for document splitting (min: 64).
* `--chunk-overlap` ` number `  
Overlap between document chunks.
* `--max-num-results` ` number `  
Maximum search results per query.
* `--reranking` ` boolean `  
Enable reranking of search results.
* `--reranking-model` ` string `  
Model to use for reranking.
* `--hybrid-search` ` boolean `  
Enable hybrid (keyword + vector) search.
* `--cache` ` boolean `  
Enable response caching.
* `--score-threshold` ` number `  
Minimum relevance score threshold (0-1).
* `--prefix` ` string `  
R2 key prefix to scope indexing.
* `--include-items` ` array `  
Glob patterns for items to include.
* `--exclude-items` ` array `  
Glob patterns for items to exclude.
* `--custom-metadata` ` array `  
Custom metadata fields, formatted as 'field\_name:data\_type'. data\_type must be one of: text, number, boolean, datetime. Repeat the flag for multiple fields (e.g. --custom-metadata title:text --custom-metadata views:number).
* `--custom-metadata-schema` ` string `  
Path to a JSON file describing custom metadata fields. The file must contain an array of { "field\_name", "data\_type" } objects. Mutually exclusive with --custom-metadata.
* `--json` ` boolean ` default: false  
Return output as clean JSON

Global flags

* `--v` ` boolean ` alias: --version  
Show version number
* `--cwd` ` string `  
Run as if Wrangler was started in the specified directory instead of the current working directory
* `--config` ` string ` alias: --c  
Path to Wrangler configuration file
* `--env` ` string ` alias: --e  
Environment to use for operations, and for selecting .env and .dev.vars files
* `--env-file` ` string `  
Path to an .env file to load - can be specified multiple times - values from earlier files are overridden by values in later files
* `--experimental-provision` ` boolean ` aliases: --x-provision default: true  
Experimental: Enable automatic resource provisioning
* `--experimental-auto-create` ` boolean ` alias: --x-auto-create default: true  
Automatically provision draft bindings with new resources
* `--install-skills` ` boolean ` default: false  
Install Cloudflare agents skills, if not already present, without asking the user for confirmation

## `ai-search get`

Get details of an AI Search instance

* [  npm ](#tab-panel-6495)
* [  pnpm ](#tab-panel-6496)
* [  yarn ](#tab-panel-6497)

Terminal window

```

npx wrangler ai-search get [NAME]


```

Terminal window

```

pnpm wrangler ai-search get [NAME]


```

Terminal window

```

yarn wrangler ai-search get [NAME]


```

* `[NAME]` ` string ` required  
The name of the AI Search instance.
* `--namespace` ` string ` alias: --n default: default  
The namespace the instance belongs to.
* `--json` ` boolean ` default: false  
Return output as clean JSON

Global flags

* `--v` ` boolean ` alias: --version  
Show version number
* `--cwd` ` string `  
Run as if Wrangler was started in the specified directory instead of the current working directory
* `--config` ` string ` alias: --c  
Path to Wrangler configuration file
* `--env` ` string ` alias: --e  
Environment to use for operations, and for selecting .env and .dev.vars files
* `--env-file` ` string `  
Path to an .env file to load - can be specified multiple times - values from earlier files are overridden by values in later files
* `--experimental-provision` ` boolean ` aliases: --x-provision default: true  
Experimental: Enable automatic resource provisioning
* `--experimental-auto-create` ` boolean ` alias: --x-auto-create default: true  
Automatically provision draft bindings with new resources
* `--install-skills` ` boolean ` default: false  
Install Cloudflare agents skills, if not already present, without asking the user for confirmation

## `ai-search update`

Update an AI Search instance configuration

* [  npm ](#tab-panel-6498)
* [  pnpm ](#tab-panel-6499)
* [  yarn ](#tab-panel-6500)

Terminal window

```

npx wrangler ai-search update [NAME]


```

Terminal window

```

pnpm wrangler ai-search update [NAME]


```

Terminal window

```

yarn wrangler ai-search update [NAME]


```

* `[NAME]` ` string ` required  
The name of the AI Search instance to update.
* `--namespace` ` string ` alias: --n default: default  
The namespace the instance belongs to.
* `--embedding-model` ` string `  
Update the embedding model.
* `--generation-model` ` string `  
Update the LLM model for chat completions.
* `--chunk-size` ` number `  
Update the chunk size.
* `--chunk-overlap` ` number `  
Update the chunk overlap.
* `--max-num-results` ` number `  
Update max search results per query.
* `--reranking` ` boolean `  
Enable or disable reranking.
* `--reranking-model` ` string `  
Update the reranking model.
* `--hybrid-search` ` boolean `  
Enable or disable hybrid search.
* `--cache` ` boolean `  
Enable or disable caching.
* `--score-threshold` ` number `  
Update the minimum relevance score threshold (0-1).
* `--paused` ` boolean `  
Pause or resume the instance.
* `--json` ` boolean ` default: false  
Return output as clean JSON

Global flags

* `--v` ` boolean ` alias: --version  
Show version number
* `--cwd` ` string `  
Run as if Wrangler was started in the specified directory instead of the current working directory
* `--config` ` string ` alias: --c  
Path to Wrangler configuration file
* `--env` ` string ` alias: --e  
Environment to use for operations, and for selecting .env and .dev.vars files
* `--env-file` ` string `  
Path to an .env file to load - can be specified multiple times - values from earlier files are overridden by values in later files
* `--experimental-provision` ` boolean ` aliases: --x-provision default: true  
Experimental: Enable automatic resource provisioning
* `--experimental-auto-create` ` boolean ` alias: --x-auto-create default: true  
Automatically provision draft bindings with new resources
* `--install-skills` ` boolean ` default: false  
Install Cloudflare agents skills, if not already present, without asking the user for confirmation

## `ai-search delete`

Delete an AI Search instance

* [  npm ](#tab-panel-6501)
* [  pnpm ](#tab-panel-6502)
* [  yarn ](#tab-panel-6503)

Terminal window

```

npx wrangler ai-search delete [NAME]


```

Terminal window

```

pnpm wrangler ai-search delete [NAME]


```

Terminal window

```

yarn wrangler ai-search delete [NAME]


```

* `[NAME]` ` string ` required  
The name of the AI Search instance to delete.
* `--namespace` ` string ` alias: --n default: default  
The namespace the instance belongs to.
* `--force` ` boolean ` alias: --y default: false  
Skip confirmation

Global flags

* `--v` ` boolean ` alias: --version  
Show version number
* `--cwd` ` string `  
Run as if Wrangler was started in the specified directory instead of the current working directory
* `--config` ` string ` alias: --c  
Path to Wrangler configuration file
* `--env` ` string ` alias: --e  
Environment to use for operations, and for selecting .env and .dev.vars files
* `--env-file` ` string `  
Path to an .env file to load - can be specified multiple times - values from earlier files are overridden by values in later files
* `--experimental-provision` ` boolean ` aliases: --x-provision default: true  
Experimental: Enable automatic resource provisioning
* `--experimental-auto-create` ` boolean ` alias: --x-auto-create default: true  
Automatically provision draft bindings with new resources
* `--install-skills` ` boolean ` default: false  
Install Cloudflare agents skills, if not already present, without asking the user for confirmation

## `ai-search stats`

Get usage statistics for an AI Search instance

* [  npm ](#tab-panel-6504)
* [  pnpm ](#tab-panel-6505)
* [  yarn ](#tab-panel-6506)

Terminal window

```

npx wrangler ai-search stats [NAME]


```

Terminal window

```

pnpm wrangler ai-search stats [NAME]


```

Terminal window

```

yarn wrangler ai-search stats [NAME]


```

* `[NAME]` ` string ` required  
The name of the AI Search instance.
* `--namespace` ` string ` alias: --n default: default  
The namespace the instance belongs to.
* `--json` ` boolean ` default: false  
Return output as clean JSON

Global flags

* `--v` ` boolean ` alias: --version  
Show version number
* `--cwd` ` string `  
Run as if Wrangler was started in the specified directory instead of the current working directory
* `--config` ` string ` alias: --c  
Path to Wrangler configuration file
* `--env` ` string ` alias: --e  
Environment to use for operations, and for selecting .env and .dev.vars files
* `--env-file` ` string `  
Path to an .env file to load - can be specified multiple times - values from earlier files are overridden by values in later files
* `--experimental-provision` ` boolean ` aliases: --x-provision default: true  
Experimental: Enable automatic resource provisioning
* `--experimental-auto-create` ` boolean ` alias: --x-auto-create default: true  
Automatically provision draft bindings with new resources
* `--install-skills` ` boolean ` default: false  
Install Cloudflare agents skills, if not already present, without asking the user for confirmation

## `ai-search search`

Execute a semantic search query against an AI Search instance

* [  npm ](#tab-panel-6507)
* [  pnpm ](#tab-panel-6508)
* [  yarn ](#tab-panel-6509)

Terminal window

```

npx wrangler ai-search search [NAME]


```

Terminal window

```

pnpm wrangler ai-search search [NAME]


```

Terminal window

```

yarn wrangler ai-search search [NAME]


```

* `[NAME]` ` string ` required  
The name of the AI Search instance.
* `--namespace` ` string ` alias: --n default: default  
The namespace the instance belongs to.
* `--query` ` string ` required  
The search query text.
* `--max-num-results` ` number `  
Override maximum number of results.
* `--score-threshold` ` number `  
Override minimum relevance score (0-1).
* `--reranking` ` boolean `  
Override reranking setting.
* `--filter` ` array `  
Metadata filter as key=value (repeatable, e.g. --filter type=docs --filter lang=en).
* `--json` ` boolean ` default: false  
Return output as clean JSON

Global flags

* `--v` ` boolean ` alias: --version  
Show version number
* `--cwd` ` string `  
Run as if Wrangler was started in the specified directory instead of the current working directory
* `--config` ` string ` alias: --c  
Path to Wrangler configuration file
* `--env` ` string ` alias: --e  
Environment to use for operations, and for selecting .env and .dev.vars files
* `--env-file` ` string `  
Path to an .env file to load - can be specified multiple times - values from earlier files are overridden by values in later files
* `--experimental-provision` ` boolean ` aliases: --x-provision default: true  
Experimental: Enable automatic resource provisioning
* `--experimental-auto-create` ` boolean ` alias: --x-auto-create default: true  
Automatically provision draft bindings with new resources
* `--install-skills` ` boolean ` default: false  
Install Cloudflare agents skills, if not already present, without asking the user for confirmation

## `ai-search namespace list`

List all AI Search namespaces

* [  npm ](#tab-panel-6510)
* [  pnpm ](#tab-panel-6511)
* [  yarn ](#tab-panel-6512)

Terminal window

```

npx wrangler ai-search namespace list


```

Terminal window

```

pnpm wrangler ai-search namespace list


```

Terminal window

```

yarn wrangler ai-search namespace list


```

* `--json` ` boolean ` default: false  
Return output as clean JSON
* `--page` ` number ` default: 1  
Page number of the results, can configure page size using "per-page"
* `--per-page` ` number `  
Number of namespaces to show per page
* `--search` ` string `  
Filter namespaces whose name or description contains this string (case-insensitive).

Global flags

* `--v` ` boolean ` alias: --version  
Show version number
* `--cwd` ` string `  
Run as if Wrangler was started in the specified directory instead of the current working directory
* `--config` ` string ` alias: --c  
Path to Wrangler configuration file
* `--env` ` string ` alias: --e  
Environment to use for operations, and for selecting .env and .dev.vars files
* `--env-file` ` string `  
Path to an .env file to load - can be specified multiple times - values from earlier files are overridden by values in later files
* `--experimental-provision` ` boolean ` aliases: --x-provision default: true  
Experimental: Enable automatic resource provisioning
* `--experimental-auto-create` ` boolean ` alias: --x-auto-create default: true  
Automatically provision draft bindings with new resources
* `--install-skills` ` boolean ` default: false  
Install Cloudflare agents skills, if not already present, without asking the user for confirmation

## `ai-search namespace create`

Create a new AI Search namespace

* [  npm ](#tab-panel-6513)
* [  pnpm ](#tab-panel-6514)
* [  yarn ](#tab-panel-6515)

Terminal window

```

npx wrangler ai-search namespace create [NAME]


```

Terminal window

```

pnpm wrangler ai-search namespace create [NAME]


```

Terminal window

```

yarn wrangler ai-search namespace create [NAME]


```

* `[NAME]` ` string ` required  
The name of the AI Search namespace to create.
* `--description` ` string `  
Optional description for the namespace (max 256 chars).
* `--json` ` boolean ` default: false  
Return output as clean JSON

Global flags

* `--v` ` boolean ` alias: --version  
Show version number
* `--cwd` ` string `  
Run as if Wrangler was started in the specified directory instead of the current working directory
* `--config` ` string ` alias: --c  
Path to Wrangler configuration file
* `--env` ` string ` alias: --e  
Environment to use for operations, and for selecting .env and .dev.vars files
* `--env-file` ` string `  
Path to an .env file to load - can be specified multiple times - values from earlier files are overridden by values in later files
* `--experimental-provision` ` boolean ` aliases: --x-provision default: true  
Experimental: Enable automatic resource provisioning
* `--experimental-auto-create` ` boolean ` alias: --x-auto-create default: true  
Automatically provision draft bindings with new resources
* `--install-skills` ` boolean ` default: false  
Install Cloudflare agents skills, if not already present, without asking the user for confirmation

## `ai-search namespace get`

Get details of an AI Search namespace

* [  npm ](#tab-panel-6516)
* [  pnpm ](#tab-panel-6517)
* [  yarn ](#tab-panel-6518)

Terminal window

```

npx wrangler ai-search namespace get [NAME]


```

Terminal window

```

pnpm wrangler ai-search namespace get [NAME]


```

Terminal window

```

yarn wrangler ai-search namespace get [NAME]


```

* `[NAME]` ` string ` required  
The name of the AI Search namespace.
* `--json` ` boolean ` default: false  
Return output as clean JSON

Global flags

* `--v` ` boolean ` alias: --version  
Show version number
* `--cwd` ` string `  
Run as if Wrangler was started in the specified directory instead of the current working directory
* `--config` ` string ` alias: --c  
Path to Wrangler configuration file
* `--env` ` string ` alias: --e  
Environment to use for operations, and for selecting .env and .dev.vars files
* `--env-file` ` string `  
Path to an .env file to load - can be specified multiple times - values from earlier files are overridden by values in later files
* `--experimental-provision` ` boolean ` aliases: --x-provision default: true  
Experimental: Enable automatic resource provisioning
* `--experimental-auto-create` ` boolean ` alias: --x-auto-create default: true  
Automatically provision draft bindings with new resources
* `--install-skills` ` boolean ` default: false  
Install Cloudflare agents skills, if not already present, without asking the user for confirmation

## `ai-search namespace update`

Update an AI Search namespace

* [  npm ](#tab-panel-6519)
* [  pnpm ](#tab-panel-6520)
* [  yarn ](#tab-panel-6521)

Terminal window

```

npx wrangler ai-search namespace update [NAME]


```

Terminal window

```

pnpm wrangler ai-search namespace update [NAME]


```

Terminal window

```

yarn wrangler ai-search namespace update [NAME]


```

* `[NAME]` ` string ` required  
The name of the AI Search namespace to update.
* `--description` ` string `  
Updated description for the namespace (max 256 chars).
* `--json` ` boolean ` default: false  
Return output as clean JSON

Global flags

* `--v` ` boolean ` alias: --version  
Show version number
* `--cwd` ` string `  
Run as if Wrangler was started in the specified directory instead of the current working directory
* `--config` ` string ` alias: --c  
Path to Wrangler configuration file
* `--env` ` string ` alias: --e  
Environment to use for operations, and for selecting .env and .dev.vars files
* `--env-file` ` string `  
Path to an .env file to load - can be specified multiple times - values from earlier files are overridden by values in later files
* `--experimental-provision` ` boolean ` aliases: --x-provision default: true  
Experimental: Enable automatic resource provisioning
* `--experimental-auto-create` ` boolean ` alias: --x-auto-create default: true  
Automatically provision draft bindings with new resources
* `--install-skills` ` boolean ` default: false  
Install Cloudflare agents skills, if not already present, without asking the user for confirmation

## `ai-search namespace delete`

Delete an AI Search namespace

* [  npm ](#tab-panel-6522)
* [  pnpm ](#tab-panel-6523)
* [  yarn ](#tab-panel-6524)

Terminal window

```

npx wrangler ai-search namespace delete [NAME]


```

Terminal window

```

pnpm wrangler ai-search namespace delete [NAME]


```

Terminal window

```

yarn wrangler ai-search namespace delete [NAME]


```

* `[NAME]` ` string ` required  
The name of the AI Search namespace to delete.
* `--force` ` boolean ` alias: --y default: false  
Skip confirmation

Global flags

* `--v` ` boolean ` alias: --version  
Show version number
* `--cwd` ` string `  
Run as if Wrangler was started in the specified directory instead of the current working directory
* `--config` ` string ` alias: --c  
Path to Wrangler configuration file
* `--env` ` string ` alias: --e  
Environment to use for operations, and for selecting .env and .dev.vars files
* `--env-file` ` string `  
Path to an .env file to load - can be specified multiple times - values from earlier files are overridden by values in later files
* `--experimental-provision` ` boolean ` aliases: --x-provision default: true  
Experimental: Enable automatic resource provisioning
* `--experimental-auto-create` ` boolean ` alias: --x-auto-create default: true  
Automatically provision draft bindings with new resources
* `--install-skills` ` boolean ` default: false  
Install Cloudflare agents skills, if not already present, without asking the user for confirmation

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/wrangler-commands/","name":"Wrangler commands"}}]}
```

---

---
title: Configuration
description: Customize how your AI Search instance indexes data, retrieves results, and generates responses.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Configuration

You can customize how your AI Search instance indexes your data, retrieves results, and generates responses. Some settings can be updated after the instance is created, while others are fixed at creation time.

## Data source

| Configuration                                                                                               | Editable after creation | Description                                              |
| ----------------------------------------------------------------------------------------------------------- | ----------------------- | -------------------------------------------------------- |
| [Built-in storage](https://developers.cloudflare.com/ai-search/configuration/data-source/built-in-storage/) | n/a                     | Upload files directly to an instance                     |
| [Website](https://developers.cloudflare.com/ai-search/configuration/data-source/website/)                   | no                      | Connect a domain you own to index website pages          |
| [R2 Bucket](https://developers.cloudflare.com/ai-search/configuration/data-source/r2/)                      | no                      | Connect a Cloudflare R2 bucket to index stored documents |

## Indexing

| Configuration                                                                                              | Editable after creation | Description                                                     |
| ---------------------------------------------------------------------------------------------------------- | ----------------------- | --------------------------------------------------------------- |
| [Vector search](https://developers.cloudflare.com/ai-search/configuration/indexing/vector-search/)         | yes                     | Vector search and the built-in vector index                     |
| [Path filtering](https://developers.cloudflare.com/ai-search/configuration/indexing/path-filtering/)       | yes                     | Include or exclude specific paths from indexing                 |
| [Chunking](https://developers.cloudflare.com/ai-search/configuration/indexing/chunking/)                   | yes                     | Number of tokens per chunk and overlap between chunks           |
| [Syncing](https://developers.cloudflare.com/ai-search/configuration/indexing/syncing/)                     | yes                     | Sync jobs and indexing controls                                 |
| [Keyword search](https://developers.cloudflare.com/ai-search/configuration/indexing/keyword-search/)       | yes                     | Enable keyword (BM25) search for exact term matching            |
| [Hybrid search](https://developers.cloudflare.com/ai-search/configuration/indexing/hybrid-search/)         | yes                     | Combine vector and keyword search with configurable fusion      |
| [Metadata](https://developers.cloudflare.com/ai-search/configuration/indexing/metadata/)                   | yes                     | Custom metadata fields for filtering                            |
| [Service API token](https://developers.cloudflare.com/ai-search/configuration/indexing/service-api-token/) | yes                     | API token that grants AI Search permission to access R2 buckets |

## Retrieval

| Configuration                                                                                             | Editable after creation | Description                                                   |
| --------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------- |
| [Result filtering](https://developers.cloudflare.com/ai-search/configuration/retrieval/result-filtering/) | yes                     | Match threshold and maximum number of results                 |
| [Relevance boosting](https://developers.cloudflare.com/ai-search/configuration/retrieval/boosting/)       | yes                     | Bias results by metadata characteristics                      |
| [Reranking](https://developers.cloudflare.com/ai-search/configuration/retrieval/reranking/)               | yes                     | Reorder results by semantic relevance using a reranking model |
| [Query rewriting](https://developers.cloudflare.com/ai-search/configuration/retrieval/query-rewriting/)   | yes                     | Rewrite follow-up queries using conversation context          |
| [System prompt](https://developers.cloudflare.com/ai-search/configuration/retrieval/system-prompt/)       | yes                     | Guide query rewriting and response generation behavior        |
| [Similarity caching](https://developers.cloudflare.com/ai-search/configuration/retrieval/cache/)          | yes                     | Cache responses for similar prompts                           |
| [Public endpoint](https://developers.cloudflare.com/ai-search/configuration/retrieval/public-endpoint/)   | yes                     | Enable public access to search, chat, and MCP endpoints       |
| [UI snippets](https://developers.cloudflare.com/ai-search/configuration/retrieval/embed-search-snippets/) | yes                     | Embed pre-built search and chat components in your website    |

## Models

| Configuration                                                                              | Editable after creation | Description                                         |
| ------------------------------------------------------------------------------------------ | ----------------------- | --------------------------------------------------- |
| [Embedding model](https://developers.cloudflare.com/ai-search/configuration/models/)       | no                      | Model used to generate vector embeddings            |
| [Generation model](https://developers.cloudflare.com/ai-search/configuration/models/)      | yes                     | Model used to generate the final response           |
| [Query rewriting model](https://developers.cloudflare.com/ai-search/configuration/models/) | yes                     | Model used for query rewriting                      |
| [Reranking model](https://developers.cloudflare.com/ai-search/configuration/models/)       | yes                     | Model used to reorder results by semantic relevance |

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/configuration/","name":"Configuration"}}]}
```

---

---
title: Data source
description: Connect a website, R2 bucket, or upload files directly to your AI Search instance for indexing.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Data source

You can upload files directly to an instance or connect an external data source.

| Data Source                                                                                                 | Description                                                                       |
| ----------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| [Built-in storage](https://developers.cloudflare.com/ai-search/configuration/data-source/built-in-storage/) | Upload files directly to an instance. Available by default on every new instance. |
| [Website](https://developers.cloudflare.com/ai-search/configuration/data-source/website/)                   | Connect a domain you own to index website pages.                                  |
| [R2 Bucket](https://developers.cloudflare.com/ai-search/configuration/data-source/r2/)                      | Connect a Cloudflare R2 bucket to index stored documents.                         |

## Supported file types

AI Search can ingest a variety of file types. The following plain text files and rich format files are supported.

### Plain text file types

| Format     | File extensions                                                  | Mime Type                                                      |
| ---------- | ---------------------------------------------------------------- | -------------------------------------------------------------- |
| Text       | .txt, .rst                                                       | text/plain                                                     |
| Log        | .log                                                             | text/plain                                                     |
| Config     | .ini, .conf, .env, .properties, .gitignore, .editorconfig, .toml | text/plain, text/toml                                          |
| Markdown   | .markdown, .md, .mdx                                             | text/markdown                                                  |
| LaTeX      | .tex, .latex                                                     | application/x-tex, application/x-latex                         |
| Script     | .sh, .bat, .ps1                                                  | application/x-sh, application/x-msdos-batch, text/x-powershell |
| SGML       | .sgml                                                            | text/sgml                                                      |
| JSON       | .json                                                            | application/json                                               |
| YAML       | .yaml, .yml                                                      | application/x-yaml                                             |
| CSS        | .css                                                             | text/css                                                       |
| JavaScript | .js                                                              | application/javascript                                         |
| PHP        | .php                                                             | application/x-httpd-php                                        |
| Python     | .py                                                              | text/x-python                                                  |
| Ruby       | .rb                                                              | text/x-ruby                                                    |
| Java       | .java                                                            | text/x-java-source                                             |
| C          | .c                                                               | text/x-c                                                       |
| C++        | .cpp, .cxx                                                       | text/x-c++                                                     |
| C Header   | .h, .hpp                                                         | text/x-c-header                                                |
| Go         | .go                                                              | text/x-go                                                      |
| Rust       | .rs                                                              | text/rust                                                      |
| Swift      | .swift                                                           | text/swift                                                     |
| Dart       | .dart                                                            | text/dart                                                      |
| EMACS Lisp | .el                                                              | application/x-elisp, text/x-elisp, text/x-emacs-lisp           |

### Rich format file types

AI Search uses [Markdown Conversion](https://developers.cloudflare.com/workers-ai/features/markdown-conversion/) to convert rich format files to markdown. The following table lists the supported formats that will be converted to Markdown:

| Format                     | File extensions                       | Mime Types                                                                                                                                                                                                                                                              | |  PDF Documents | .pdf | application/pdf |
| -------------------------- | ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | ---- | --------------- |
| Images 1                   | .jpeg, .jpg, .png, .webp, .svg        | image/jpeg, image/png, image/webp, image/svg+xml                                                                                                                                                                                                                        |                  |      |                 |
| HTML Documents             | .html, .htm                           | text/html                                                                                                                                                                                                                                                               |                  |      |                 |
| XML Documents              | .xml                                  | application/xml                                                                                                                                                                                                                                                         |                  |      |                 |
| Microsoft Office Documents | .xlsx, .xlsm, .xlsb, .xls, .et, .docx | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel.sheet.macroenabled.12,application/vnd.ms-excel.sheet.binary.macroenabled.12,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.wordprocessingml.document |                  |      |                 |
| Open Document Format       | .ods, .odt                            | application/vnd.oasis.opendocument.spreadsheet,application/vnd.oasis.opendocument.text                                                                                                                                                                                  |                  |      |                 |
| CSV                        | .csv                                  | text/csv                                                                                                                                                                                                                                                                |                  |      |                 |
| Apple Documents            | .numbers                              | application/vnd.apple.numbers                                                                                                                                                                                                                                           |                  |      |                 |

1 Image conversion uses two Workers AI models for object detection and summarization. See [Workers AI pricing](https://developers.cloudflare.com/workers-ai/features/markdown-conversion/#pricing) for more details.

## File limits

AI Search has a file size limit of **up to 4 MB**.

Files that exceed this limit will not be indexed and will show up in the error logs.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/configuration/","name":"Configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/configuration/data-source/","name":"Data source"}}]}
```

---

---
title: Built-in storage
description: Upload files directly to an AI Search instance using built-in storage powered by R2 and Vectorize.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Built-in storage

Every new AI Search instance comes with built-in storage and a built-in vector index, powered by [R2](https://developers.cloudflare.com/r2/) and [Vectorize](https://developers.cloudflare.com/vectorize/). You can upload files directly to an instance without setting up either service yourself.

## Instances created after April 16, 2026

Instances created after **April 16, 2026** include built-in storage. You can upload files directly using the [Items API](https://developers.cloudflare.com/ai-search/api/items/workers-binding/) or the dashboard.

Instances created before this date do not include built-in storage and do not support the Items API. You can see which of your instances have built-in storage on the dashboard under **AI** \> **AI Search**. Select your instance and check the **Overview** tab to see if it includes built-in storage.

[ Go to **AI Search** ](https://dash.cloudflare.com/?to=/:account/ai/ai-search) 

All instances created before this date will be automatically migrated to managed infrastructure on **June 3, 2026**. For details, refer to [Limits & pricing](https://developers.cloudflare.com/ai-search/platform/limits-pricing/#previous-instances).

## Upload and manage files

Upload files to an instance using the [Items API](https://developers.cloudflare.com/ai-search/api/items/workers-binding/) (Workers binding or REST API) or the **Items** tab in the dashboard (**AI** \> **AI Search** \> your instance > **Items**). You can also list, view, and delete uploaded files through the Items API or the dashboard.

For supported file types, refer to [Supported file types](https://developers.cloudflare.com/ai-search/configuration/data-source/#supported-file-types).

## Indexing

Files uploaded to built-in storage are indexed immediately. External data sources like websites and R2 buckets are indexed on a sync schedule.

## External data sources

An instance can use built-in storage alongside an external data source. The available external data sources are:

* [Website](https://developers.cloudflare.com/ai-search/configuration/data-source/website/): crawl and index a website that you own
* [R2 Bucket](https://developers.cloudflare.com/ai-search/configuration/data-source/r2/): index documents stored in a Cloudflare R2 bucket

For example, an instance can be backed by a website for shared documentation while also accepting file uploads through the Items API for additional content.

## Limits and pricing

For instances with built-in storage, R2 storage, Vectorize, and Browser Run are included. Workers AI and AI Gateway usage is billed separately. For full details, refer to [Limits and pricing](https://developers.cloudflare.com/ai-search/platform/limits-pricing/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/configuration/","name":"Configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/configuration/data-source/","name":"Data source"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/configuration/data-source/built-in-storage/","name":"Built-in storage"}}]}
```

---

---
title: R2
description: Connect a Cloudflare R2 bucket as a data source to index stored documents with AI Search.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# R2

You can connect a [Cloudflare R2](https://developers.cloudflare.com/r2/) bucket as a data source for your AI Search instance. AI Search indexes the files stored in your bucket automatically.

## Get started

You can connect an R2 bucket when creating a new instance through the [dashboard](https://developers.cloudflare.com/ai-search/get-started/dashboard/), the [REST API](https://developers.cloudflare.com/ai-search/get-started/api/), or [Wrangler](https://developers.cloudflare.com/ai-search/get-started/wrangler/). R2 is an optional data source that you can add alongside [built-in storage](https://developers.cloudflare.com/ai-search/configuration/data-source/built-in-storage/).

If you have never created an R2-backed instance before, we recommend using the dashboard or Wrangler CLI, which will create and register a [service API token](https://developers.cloudflare.com/ai-search/configuration/indexing/service-api-token/) for you automatically. If you are using the REST API or Workers binding, you will need to create a service API token and pass the `token_id` in the create request. Refer to [Service API token](https://developers.cloudflare.com/ai-search/configuration/indexing/service-api-token/) for setup instructions.

To get started, [configure an R2 bucket](https://developers.cloudflare.com/r2/get-started/) containing your data. Files that are unsupported or exceed the size limit will be skipped during indexing and logged as errors.

## Path filtering

You can control which files get indexed by defining include and exclude rules for object paths. Use this to limit indexing to specific folders or to exclude files you do not want searchable.

For example, to index only documentation while excluding drafts:

* **Include:** `/docs/**`
* **Exclude:** `/docs/drafts/**`

Refer to [Path filtering](https://developers.cloudflare.com/ai-search/configuration/indexing/path-filtering/) for pattern syntax, filtering behavior, and more examples.

For supported file types and size limits, refer to [Data source](https://developers.cloudflare.com/ai-search/configuration/data-source/#supported-file-types).

## Custom metadata

You can attach custom metadata to R2 objects for filtering search results. AI Search reads metadata from S3-compatible custom headers (`x-amz-meta-*`).

Before metadata can be extracted, you must [define a schema](https://developers.cloudflare.com/ai-search/configuration/indexing/metadata/#define-a-schema) in your AI Search configuration.

### Set metadata when uploading

* [ Workers R2 binding ](#tab-panel-6474)
* [ AWS SDK ](#tab-panel-6475)
* [ Wrangler CLI ](#tab-panel-6476)

Use the `customMetadata` option when uploading objects with the [R2 Workers binding](https://developers.cloudflare.com/r2/api/workers/workers-api-usage/):

JavaScript

```

await env.MY_BUCKET.put("docs/document.pdf", fileContent, {

  customMetadata: {

    category: "documentation",

    version: "2.5",

    is_public: "true",

  },

});


```

Use the `Metadata` option with the [AWS SDK for JavaScript](https://developers.cloudflare.com/r2/api/s3/api/):

JavaScript

```

import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";


const client = new S3Client({

  region: "auto",

  endpoint: `https://${accountId}.r2.cloudflarestorage.com`,

  credentials: {

    accessKeyId: R2_ACCESS_KEY_ID,

    secretAccessKey: R2_SECRET_ACCESS_KEY,

  },

});


await client.send(

  new PutObjectCommand({

    Bucket: "your-bucket",

    Key: "docs/document.pdf",

    Body: fileContent,

    Metadata: {

      category: "documentation",

      version: "2.5",

      is_public: "true",

    },

  }),

);


```

Use the `--header` flag with [Wrangler](https://developers.cloudflare.com/r2/reference/wrangler-commands/) to set `x-amz-meta-*` headers:

Terminal window

```

wrangler r2 object put your-bucket/docs/document.pdf \

  --file=./document.pdf \

  --header="x-amz-meta-category:documentation" \

  --header="x-amz-meta-version:2.5" \

  --header="x-amz-meta-is_public:true"


```

### How metadata extraction works

When a file is fetched from R2 during indexing:

1. All `x-amz-meta-*` headers are read from the object.
2. The `x-amz-meta-` prefix is stripped (for example, `x-amz-meta-category` becomes `category`).
3. Field names are matched against your schema (case-insensitive).
4. Values are cast to the configured data type.
5. Invalid values (for example, a non-numeric string for a `number` type) are silently ignored.

### Unicode support

Metadata values support Unicode characters through MIME-Word encoding (RFC 2047). Most S3-compatible tools handle this encoding automatically.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/configuration/","name":"Configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/configuration/data-source/","name":"Data source"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/configuration/data-source/r2/","name":"R2"}}]}
```

---

---
title: Website
description: Connect a domain you own as a data source so AI Search can crawl and index your website pages.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Website

You can connect a website you own as a data source for your AI Search instance. AI Search crawls and indexes the pages automatically.

You can only crawl domains that you have onboarded onto the same Cloudflare account. Refer to [Onboard a domain](https://developers.cloudflare.com/fundamentals/manage-domains/add-site/) for more information on adding a domain to your Cloudflare account.

Bot protection may block crawling

If you use Cloudflare products that control or restrict bot traffic such as [Bot Management](https://developers.cloudflare.com/bots/), [Web Application Firewall (WAF)](https://developers.cloudflare.com/waf/), or [Turnstile](https://developers.cloudflare.com/turnstile/), the same rules will apply to the AI Search crawler. Make sure to configure an exception or an allow-list for the AI Search crawler in your settings.

## Get started

You can connect a website when creating a new instance through the [dashboard](https://developers.cloudflare.com/ai-search/get-started/dashboard/), the [REST API](https://developers.cloudflare.com/ai-search/get-started/api/), or [Wrangler](https://developers.cloudflare.com/ai-search/get-started/wrangler/). Website is an optional data source that you can add alongside [built-in storage](https://developers.cloudflare.com/ai-search/configuration/data-source/built-in-storage/).

## How website crawling works

When you connect a domain, the crawler looks for your website's sitemap to determine which pages to visit:

1. If you configure one or more custom sitemap URLs in the dashboard under **Parser options** \> **Specific sitemap**, AI Search crawls only those sitemap URLs.
2. Otherwise, the crawler checks `robots.txt` for listed sitemaps.
3. If no `robots.txt` is found, the crawler checks for a sitemap at `/sitemap.xml`.
4. If no sitemap is available, the domain cannot be crawled.

### Indexing order

If your sitemaps include `<priority>` attributes, AI Search reads all sitemaps and indexes pages based on each page's priority value, regardless of which sitemap the page is in.

If no `<priority>` is specified, pages are indexed in the order the sitemaps are provided, either from the configured custom sitemap URLs or from `robots.txt` from top to bottom.

AI Search supports `.gz` compressed sitemaps. Both `robots.txt` and sitemaps can use partial URLs.

### Sync and updates

During scheduled or manual [sync jobs](https://developers.cloudflare.com/ai-search/configuration/indexing/syncing/), the crawler will check for changes to the `<lastmod>` attribute in your sitemap. If it has been changed to a date occurring after the last sync date, then the page is crawled, the updated version is stored, and the page is automatically reindexed so that your search results always reflect the latest content.

If the `<lastmod>` attribute is not defined, AI Search uses the `<changefreq>` attribute to determine how often to re-crawl the URL. If neither `<lastmod>` nor `<changefreq>` is defined, AI Search automatically crawls each link once a day.

## Storage

For instances with [built-in storage](https://developers.cloudflare.com/ai-search/configuration/data-source/built-in-storage/), crawled pages are stored in managed storage automatically.

For older instances created before **April 16, 2026**, AI Search creates a dedicated R2 bucket in your account to store crawled pages. This bucket is automatically managed and is used only for content discovered by the crawler.

Note

For instances with a dedicated R2 bucket, do not modify the bucket directly as it may disrupt the indexing flow and cause content to not be updated properly.

## Configuration

### Path filtering

You can control which pages get indexed by defining include and exclude rules for URL paths. Use this to limit indexing to specific sections of your site or to exclude content you do not want searchable.

Note

Path filtering matches against the full URL, including the scheme, hostname, and subdomains. For example, a page at `https://www.example.com/blog/post` requires a pattern like `**/blog/**` to match. Using `/blog/**` alone will not match because it does not account for the hostname.

For example, to index only blog posts while excluding drafts:

* **Include:** `**/blog/**`
* **Exclude:** `**/blog/drafts/**`

Refer to [Path filtering](https://developers.cloudflare.com/ai-search/configuration/indexing/path-filtering/) for pattern syntax, filtering behavior, and more examples.

For supported file types and size limits, refer to [Data source](https://developers.cloudflare.com/ai-search/configuration/data-source/#supported-file-types).

### Parsing options

You can configure parsing options during onboarding or in your instance settings under **Parser options**.

#### Specific sitemap

By default, AI Search crawls all sitemaps listed in your `robots.txt` in the order they appear (top to bottom). If you do not want the crawler to index everything, or if your sitemap is hosted at a non-standard path, you can configure custom sitemap URLs in the dashboard under **Parser options** \> **Specific sitemap**.

When custom sitemap URLs are configured, AI Search uses those sitemap URLs instead of auto-discovering sitemaps from `robots.txt` or `/sitemap.xml`. You can add up to five sitemap URLs.

#### Rendering mode

You can choose how pages are parsed during crawling:

* **Static sites**: Downloads the raw HTML for each page.
* **Rendered sites**: Loads pages with a headless browser and downloads the fully rendered version, including dynamic JavaScript content. For instances with [built-in storage](https://developers.cloudflare.com/ai-search/configuration/data-source/built-in-storage/), Browser Run is included. For older instances, [Browser Run](https://developers.cloudflare.com/browser-run/pricing/) limits and billing apply.

### Extra headers

If your website has pages behind authentication or pages that are only visible to logged-in users, you can configure custom HTTP headers to allow the AI Search crawler to access this protected content. You can add up to five custom HTTP headers to the requests AI Search sends when crawling your site.

#### Providing access to sites protected by Cloudflare Access

To allow AI Search to crawl a site protected by [Cloudflare Access](https://developers.cloudflare.com/cloudflare-one/access-controls/), you need to create service token credentials and configure them as custom headers.

Service tokens bypass user authentication, so ensure your Access policies are configured appropriately for the content you want to index. The service token will allow the AI Search crawler to access all content covered by the Service Auth policy.

1. In the [Cloudflare dashboard ↗](https://dash.cloudflare.com/), [create a service token](https://developers.cloudflare.com/cloudflare-one/access-controls/service-credentials/service-tokens/#create-a-service-token). Once the Client ID and Client Secret are generated, save them for the next steps. For example they can look like:  
```  
CF-Access-Client-Id: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.access  
CF-Access-Client-Secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  
```
2. [Create a policy](https://developers.cloudflare.com/cloudflare-one/access-controls/policies/policy-management/#create-a-policy) with the following configuration:  
   * Add an **Include** rule with **Selector** set to **Service token**.  
   * In **Value**, select the Service Token you created in step 1.
3. [Add your self-hosted application to Access](https://developers.cloudflare.com/cloudflare-one/access-controls/applications/http-apps/self-hosted-public-app/) with the following configuration:  
   * In Access policies, click **Select existing policies**.  
   * Select the policy that you have just created and select **Confirm**.
4. In the Cloudflare dashboard, go to the **AI Search** page.  
[ Go to **AI Search** ](https://dash.cloudflare.com/?to=/:account/ai/ai-search)
5. Select **Create**.
6. Select **Website** as your data source.
7. Under **Parse options**, locate **Extra headers** and add the following two headers using your saved credentials:  
   * Header 1:  
         * **Key**: `CF-Access-Client-Id`  
         * **Value**: `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.access`  
   * Header 2:  
         * **Key**: `CF-Access-Client-Secret`  
         * **Value**: `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`
8. Complete the AI Search setup process to create your search instance.

## Custom metadata

You can attach custom metadata to web pages using HTML `<meta>` tags. AI Search extracts metadata from the `<head>` section of each crawled page.

Before custom metadata can be extracted, you must [define a schema](https://developers.cloudflare.com/ai-search/configuration/indexing/metadata/#define-a-schema) in your AI Search configuration.

### Add metadata to web pages

Add `<meta>` tags using either the `name` or `property` attribute:

```

<!DOCTYPE html>

<html>

  <head>

    <meta name="title" content="Getting Started Guide" />

    <meta name="description" content="Learn how to set up the application" />

    <meta property="og:title" content="Getting Started Guide" />

    <meta property="og:image" content="https://example.com/og-image.png" />

    <meta name="category" content="documentation" />

    <meta name="version" content="2.5" />

    <meta name="is_public" content="true" />

  </head>

  <body>

    <!-- Page content -->

  </body>

</html>


```

### Recognized fields

For the following fields, AI Search knows which meta tags to extract from. You must still define these in your schema to enable extraction.

| Field       | Source                                                        |
| ----------- | ------------------------------------------------------------- |
| title       | <meta name="title"> or <meta property="og:title">             |
| description | <meta name="description"> or <meta property="og:description"> |
| image       | <meta property="og:image">                                    |

When both a standard meta tag and an Open Graph tag are present, the standard meta tag takes precedence.

### How metadata extraction works

When the crawler fetches a page:

1. All `<meta>` tags with `name` or `property` attributes are parsed from the `<head>` section.
2. Tag names are matched against your schema (case-insensitive).
3. The `content` attribute value is cast to the configured data type.
4. Extracted metadata is stored alongside the cached HTML.
5. On subsequent processing, metadata flows into the vector index.

### Boolean value parsing

For `boolean` fields, the following values are accepted (case-insensitive):

| True values  | False values |
| ------------ | ------------ |
| true, 1, yes | false, 0, no |

Any other value is treated as invalid and the field is omitted.

## Content selectors

Content selectors let you control which parts of a crawled page are indexed. Each entry pairs a URL glob pattern with a CSS selector. When a page URL matches a glob pattern, only the elements matching the corresponding CSS selector — and their descendants — are extracted and converted to Markdown for indexing.

The list is ordered and the **first matching path wins**. If a page URL matches multiple glob patterns, only the selector from the first match is applied. Order your entries from most specific to least specific.

### Default behavior

Without content selectors, AI Search applies a default processing pipeline that removes elements such as `<header>`, `<footer>`, and `<head>` before converting the remaining content to Markdown. For more details on how HTML is processed, refer to [How HTML is processed](https://developers.cloudflare.com/workers-ai/features/markdown-conversion/how-it-works/#html).

### Configure content selectors in the dashboard

1. Go to the [AI Search ↗](https://dash.cloudflare.com/?to=/:account/ai/ai-search) page in the Cloudflare dashboard.  
[ Go to **AI Search** ](https://dash.cloudflare.com/?to=/:account/ai/ai-search)
2. Select your AI Search instance, or select **Create** to create a new one with a **Website** data source.
3. Under the data source settings, locate the **Content selectors** section.
4. Select **Add selector**.
5. In the **Path** field, enter a glob pattern to match page URLs. For example, `**/blog/**`.
6. In the **Selector** field, enter a CSS selector to extract content from matching pages. For example, `article .post-body`.
7. To add more entries, select **Add selector** again. Entries are evaluated in order from top to bottom.

### Configure content selectors via the API

Content selectors are configured in the `source_params.web_crawler.parse_options.content_selector` field when creating or updating an AI Search instance. The field accepts an array of objects, each with a `path` and `selector` property.

Terminal window

```

curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/ai-search/instances" \

  -H "Authorization: Bearer {api_token}" \

  -H "Content-Type: application/json" \

  -d '{

    "id": "my-ai-search",

    "source": "https://example.com",

    "type": "web-crawler",

    "source_params": {

      "web_crawler": {

        "parse_options": {

          "content_selector": [

            {

              "path": "**/blog/**",

              "selector": "article .post-body"

            },

            {

              "path": "**/docs/**",

              "selector": "main .content"

            }

          ]

        }

      }

    }

  }'


```

| Field    | Type   | Description                                                                                                                                                                                                                                                         |
| -------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| path     | string | Glob pattern to match against the full page URL. Uses the same glob syntax as [path filtering](https://developers.cloudflare.com/ai-search/configuration/indexing/path-filtering/) — \* matches within a segment, \*\* crosses directories. Maximum 200 characters. |
| selector | string | CSS selector to extract content from pages matching the path pattern. Supports standard CSS selectors including element, class, ID, and attribute selectors. Maximum 200 characters.                                                                                |

### Examples

#### Extract main content from blog pages

To index only the article body on blog pages and ignore navigation, sidebars, and footers:

| Path           | Selector           |
| -------------- | ------------------ |
| \*\*/blog/\*\* | article .post-body |

#### Target documentation content

To index the main content area of a documentation site:

| Path           | Selector      |
| -------------- | ------------- |
| \*\*/docs/\*\* | main .content |

#### Different selectors for different sections

You can define multiple entries to apply different selectors to different parts of your site. The first matching path wins, so place more specific patterns first:

| Path                    | Selector           |
| ----------------------- | ------------------ |
| \*\*/blog/releases/\*\* | .release-notes     |
| \*\*/blog/\*\*          | article .post-body |
| \*\*/docs/\*\*          | main .content      |

In this example, a page at `https://example.com/blog/releases/v2` matches the first pattern and uses the `.release-notes` selector. A page at `https://example.com/blog/my-post` skips the first pattern and matches the second.

Warning

If a CSS selector does not match any elements on a page, the resulting Markdown is empty and AI Search marks the item as errored. Verify that your selectors match the expected elements before applying them to a broad set of pages.

### Interaction with other features

* **Path filtering**: [Path filtering](https://developers.cloudflare.com/ai-search/configuration/indexing/path-filtering/) takes priority over content selectors. Pages excluded by path filters are never crawled, so content selectors do not apply to them.
* **Browser Run**: Content selectors apply to the HTML that AI Search receives. For sites that render content with JavaScript, turn on [Browser Run](#rendering-mode) so that selectors can target the fully rendered DOM.
* **Automatic re-indexing**: Updating content selectors triggers a new [sync job](https://developers.cloudflare.com/ai-search/configuration/indexing/) immediately, so changes are applied to all indexed pages.

### Limits

| Limit                            | Value          |
| -------------------------------- | -------------- |
| Maximum content selector entries | 10             |
| Maximum path pattern length      | 200 characters |
| Maximum selector length          | 200 characters |

## Best practices for robots.txt and sitemap

Configure your `robots.txt` and sitemap to help AI Search crawl your site efficiently.

### robots.txt

The AI Search crawler uses the user agent `Cloudflare-AI-Search`. Your `robots.txt` file should reference your sitemap and allow the crawler:

robots.txt

```

User-agent: *

Allow: /


Sitemap: https://example.com/sitemap.xml


```

You can list multiple sitemaps or use a sitemap index file:

robots.txt

```

User-agent: *

Allow: /


Sitemap: https://example.com/sitemap.xml

Sitemap: https://example.com/blog-sitemap.xml

Sitemap: https://example.com/sitemap.xml.gz


```

To block all other crawlers but allow only AI Search:

robots.txt

```

User-agent: *

Disallow: /


User-agent: Cloudflare-AI-Search

Allow: /


Sitemap: https://example.com/sitemap.xml


```

### Sitemap

Structure your sitemap to give AI Search the information it needs to crawl efficiently:

sitemap.xml

```

<?xml version="1.0" encoding="UTF-8"?>

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">

  <url>

    <loc>https://example.com/important-page</loc>

    <lastmod>2026-01-15</lastmod>

    <changefreq>weekly</changefreq>

    <priority>1.0</priority>

  </url>

  <url>

    <loc>https://example.com/other-page</loc>

    <lastmod>2026-01-10</lastmod>

    <changefreq>monthly</changefreq>

    <priority>0.5</priority>

  </url>

</urlset>


```

Use these attributes to control crawling behavior:

| Attribute    | Purpose                       | Recommendation                                                                                      |
| ------------ | ----------------------------- | --------------------------------------------------------------------------------------------------- |
| <loc>        | URL of the page               | Required. Use full or partial URLs.                                                                 |
| <lastmod>    | Last modification date        | Include to enable change detection. AI Search re-crawls pages when this date changes.               |
| <changefreq> | Expected change frequency     | Use when <lastmod> is not available. Values: always, hourly, daily, weekly, monthly, yearly, never. |
| <priority>   | Relative importance (0.0-1.0) | Set higher values for important pages. AI Search indexes pages in priority order.                   |

You can also use a Sitemap Index to bundle other domain-specific sitemaps:

sitemap-index.xml

```

<?xml version="1.0" encoding="UTF-8"?>

<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">

  <sitemap>

    <loc>https://www.example.com/sitemap-blog.xml</loc>

    <lastmod>2024-08-15T10:00:00+00:00</lastmod>

  </sitemap>

  <sitemap>

    <loc>https://www.example.com/sitemap-docs.xml</loc>

    <lastmod>2024-08-10T12:00:00+00:00</lastmod>

  </sitemap>

</sitemapindex>


```

When parsing a Sitemap Index, AI Search collects all child sitemaps and then crawls them recursively, collecting all relevant URLs present in your sitemaps.

### Recommendations

* Include `<lastmod>` on all URLs to enable efficient change detection during syncs.
* Set `<priority>` to control indexing order. Pages with higher priority are indexed first.
* Use `<changefreq>` as a fallback when `<lastmod>` is not available.
* Use sitemap index files for large sites with multiple sitemaps.
* Compress large sitemaps using `.gz` format to reduce bandwidth.
* Keep sitemaps under 50MB and 50,000 URLs per file (standard sitemap limits).

## Allow the AI Search crawler through WAF

If you have Security rules configured to block bot activity, you can add a rule to allowlist the crawler bot.

1. In the Cloudflare dashboard, go to the **Security rules** page.  
[ Go to **Security rules** ](https://dash.cloudflare.com/?to=/:account/:zone/security/security-rules)
2. To create a new empty rule, select **Create rule** \> **Custom rules**.
3. Enter a descriptive name for the rule in **Rule name**, such as `Allow AI Search`.
4. Under **When incoming requests match**, use the **Field** drop-down list to choose _Bot Detection ID_. For **Operator**, select _equals_. For **Value**, enter `122933950`.
5. Under **Then take action**, in the **Choose action** dropdown, choose _Skip_.
6. Under **Place at**, select the order of the rule in the **Select order** dropdown to be _First_. Setting the order as _First_ allows this rule to be applied before subsequent rules.
7. To save and deploy your rule, select **Deploy**.

## Limits and pricing

The regular AI Search [limits](https://developers.cloudflare.com/ai-search/platform/limits-pricing/) apply when using the Website data source.

The crawler will download and index pages only up to the maximum object limit supported for an AI Search instance, and it processes the first set of pages it visits until that limit is reached. In addition, any files that are downloaded but exceed the file size limit will not be indexed.

For instances with [built-in storage](https://developers.cloudflare.com/ai-search/configuration/data-source/built-in-storage/), Browser Run and storage are included. For older instances, [R2](https://developers.cloudflare.com/r2/pricing/), [Vectorize](https://developers.cloudflare.com/vectorize/platform/pricing/), and [Browser Run](https://developers.cloudflare.com/browser-run/pricing/) are billed separately.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/configuration/","name":"Configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/configuration/data-source/","name":"Data source"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/configuration/data-source/website/","name":"Website"}}]}
```

---

---
title: Chunking
description: Configure how AI Search splits content into chunks for embedding and retrieval.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Chunking

Chunking is the process of splitting large data into smaller segments before embedding them for search. AI Search uses **recursive chunking**, which breaks your content at natural boundaries (like paragraphs or sentences), and then further splits it if the chunks are too large.

## What is recursive chunking

Recursive chunking tries to keep chunks meaningful by:

* **Splitting at natural boundaries:** like paragraphs, then sentences.
* **Checking the size:** if a chunk is too long (based on token count), it’s split again into smaller parts.

This way, chunks are easy to embed and retrieve, without cutting off thoughts mid-sentence.

## Chunking controls

AI Search exposes two parameters to help you control chunking behavior:

* **Chunk size**: The number of tokens per chunk. The option range may vary depending on the model.
* **Chunk overlap**: The percentage of overlapping tokens between adjacent chunks.  
   * Minimum: `0%`  
   * Maximum: `30%`

These settings apply during the indexing step, before your data is embedded and stored in your search index.

## Choosing chunk size and overlap

Chunking affects both how your content is retrieved and how much context is passed into the generation model. Try out this external [chunk visualizer tool ↗](https://huggingface.co/spaces/m-ric/chunk%5Fvisualizer) to help understand how different chunk settings could look.

### Additional considerations:

* **Index size:** Smaller chunk sizes produce more chunks and more total vectors. Refer to the [AI Search limits](https://developers.cloudflare.com/ai-search/platform/limits-pricing/) to ensure your configuration stays within instance limits.
* **Generation model context window:** Generation models have a limited context window that must fit all retrieved chunks (`max_num_results` × `chunk size`), the user query, and the model's output. Be careful with large chunks or high `max_num_results` values to avoid context overflows.
* **Cost and performance:** Larger chunks and higher `max_num_results` settings result in more tokens passed to the model, which can increase latency and cost. You can monitor this usage in [AI Gateway](https://developers.cloudflare.com/ai-gateway/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/configuration/","name":"Configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/configuration/indexing/","name":"Indexing"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/configuration/indexing/chunking/","name":"Chunking"}}]}
```

---

---
title: Hybrid search
description: Combine vector and keyword search in AI Search for broader, more accurate retrieval results.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Hybrid search

Hybrid search runs vector and keyword search in parallel and merges the results. It requires [keyword search](https://developers.cloudflare.com/ai-search/configuration/indexing/keyword-search/) to be enabled. For an overview of search modes, refer to [Search modes](https://developers.cloudflare.com/ai-search/concepts/search-modes/).

## Enable hybrid search

Set both `index_method.vector` and `index_method.keyword` to `true`:

TypeScript

```

const instance = await env.AI_SEARCH.create({

  id: "my-instance",

  index_method: {

    vector: true,

    keyword: true,

  },

  fusion_method: "rrf",

});


```

To disable hybrid search, set `index_method.keyword` to `false`. The keyword index is deleted.

For each search method, you can configure the following to adjust retrieval behavior:

* **Vector search**: Configure the [embedding model](https://developers.cloudflare.com/ai-search/configuration/models/).
* **Keyword search**: Configure the [tokenizer and match mode](https://developers.cloudflare.com/ai-search/configuration/indexing/keyword-search/).

## Fusion method

The `fusion_method` field controls how vector and keyword results are merged.

| Value | Default | Description                                                                                                               |
| ----- | ------- | ------------------------------------------------------------------------------------------------------------------------- |
| rrf   | Yes     | Reciprocal Rank Fusion. Scores results based on rank position across both search methods. Recommended for most use cases. |
| max   | No      | Takes the higher of the normalized vector and keyword scores. Use when one search method is consistently more relevant.   |

## Reranking

After fusion, you can optionally apply reranking to further reorder results by semantic relevance. Reranking uses a cross-encoder model that evaluates the query and each chunk together, which can improve precision beyond what fusion alone provides.

Reranking is disabled by default. Refer to [Reranking](https://developers.cloudflare.com/ai-search/configuration/retrieval/reranking/) to enable and configure it.

## Per-request overrides

Override search settings on individual requests using `ai_search_options.retrieval`.

| Field           | Type                             | Description                                                          |
| --------------- | -------------------------------- | -------------------------------------------------------------------- |
| retrieval\_type | "vector", "keyword", or "hybrid" | Force a specific search mode. Must be compatible with index\_method. |
| fusion\_method  | "rrf" or "max"                   | Override the fusion method.                                          |

TypeScript

```

const instance = env.AI_SEARCH.get("my-instance");


const results = await instance.search({

  messages: [{ role: "user", content: "What is Cloudflare?" }],

  ai_search_options: {

    retrieval: {

      retrieval_type: "hybrid",

      fusion_method: "rrf",

    },

  },

});


```

Note

Requesting a `retrieval_type` that is not compatible with the instance `index_method` returns an error.

## Scoring details

When hybrid search is active, each chunk includes a `scoring_details` object:

| Field            | Type   | Description                                 |
| ---------------- | ------ | ------------------------------------------- |
| vector\_score    | number | Vector similarity score (0 to 1).           |
| keyword\_score   | number | Raw BM25 keyword score.                     |
| vector\_rank     | number | Rank position in the vector result set.     |
| keyword\_rank    | number | Rank position in the keyword result set.    |
| fusion\_method   | string | Fusion method used (rrf or max).            |
| reranking\_score | number | Score from the reranking model, if enabled. |

## Limits

Instances with keyword search enabled support up to 500,000 files per instance on the Workers Paid tier, compared to 1,000,000 for vector-only instances. Refer to [Limits and pricing](https://developers.cloudflare.com/ai-search/platform/limits-pricing/) for the full list of limits.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/configuration/","name":"Configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/configuration/indexing/","name":"Indexing"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/configuration/indexing/hybrid-search/","name":"Hybrid search"}}]}
```

---

---
title: Keyword search
description: Enable BM25 keyword search in AI Search to match documents containing exact query terms.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Keyword search

Enable keyword search to match chunks that contain your query terms exactly. For an overview of search modes, refer to [Search modes](https://developers.cloudflare.com/ai-search/concepts/search-modes/).

## Enable keyword search

Set `index_method.keyword` to `true` when creating or updating an instance. You can use keyword search on its own or alongside vector search for [hybrid search](https://developers.cloudflare.com/ai-search/configuration/indexing/hybrid-search/).

| Field   | Type    | Default | Description                      |
| ------- | ------- | ------- | -------------------------------- |
| vector  | boolean | true    | Enable vector (semantic) search. |
| keyword | boolean | false   | Enable keyword (BM25) search.    |

At least one of `vector` or `keyword` must be `true`. Changing `index_method` triggers a full reindex of your content.

TypeScript

```

const instance = await env.AI_SEARCH.create({

  id: "my-instance",

  index_method: {

    vector: false,

    keyword: true,

  },

});


```

## Keyword tokenizer

The `keyword_tokenizer` field (inside `indexing_options`) controls how text is split into tokens. Changing this triggers a full reindex.

| Value   | Default | Description                                                                       |
| ------- | ------- | --------------------------------------------------------------------------------- |
| porter  | Yes     | Applies Porter stemming. "running" matches "run." Best for natural language.      |
| trigram | No      | Overlapping 3-character windows. "config" matches "configuration." Best for code. |

## Keyword match mode

The `keyword_match_mode` field (inside `retrieval_options`) controls how multiple query terms are combined.

| Value | Default | Description                                                   |
| ----- | ------- | ------------------------------------------------------------- |
| and   | Yes     | All query terms must appear. Higher precision, fewer results. |
| or    | No      | Any query term can match. Higher recall, more results.        |

You can override `keyword_match_mode` per request:

TypeScript

```

const instance = env.AI_SEARCH.get("my-instance");


const results = await instance.search({

  messages: [{ role: "user", content: "What is Cloudflare?" }],

  ai_search_options: {

    retrieval: {

      keyword_match_mode: "or",

    },

  },

});


```

## Limits

Instances with keyword search enabled support up to 500,000 files per instance on the Workers Paid tier, compared to 1,000,000 for vector-only instances. Refer to [Limits and pricing](https://developers.cloudflare.com/ai-search/platform/limits-pricing/) for the full list of limits.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/configuration/","name":"Configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/configuration/indexing/","name":"Indexing"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/configuration/indexing/keyword-search/","name":"Keyword search"}}]}
```

---

---
title: Metadata
description: Use metadata attributes and custom schemas in AI Search to filter and contextualize search results.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Metadata

Use metadata to filter documents before retrieval and provide context to guide AI responses. This page covers built-in metadata attributes, custom metadata schemas, and filter syntax.

## Built-in metadata attributes

AI Search automatically extracts the following metadata attributes from your indexed documents:

| Attribute | Description                                                                                         | Example                                                                 |
| --------- | --------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| filename  | The name of the file.                                                                               | guide.pdf or docs/getting-started/guide.pdf                             |
| folder    | The folder or prefix to the object.                                                                 | For docs/getting-started/guide.pdf, the folder is docs/getting-started/ |
| timestamp | Unix timestamp (milliseconds) when the object was last modified. Comparisons round down to seconds. | 1735689600000 (2025-01-01 00:00:00 UTC)                                 |

## Custom metadata

Custom metadata allows you to define additional fields for filtering search results. You can attach structured metadata to documents and filter queries by attributes such as category, version, or any custom field.

### Supported data types

| Type     | Description                        | Example values               |
| -------- | ---------------------------------- | ---------------------------- |
| text     | String values (max 500 characters) | "documentation", "blog-post" |
| number   | Numeric values (parsed as float)   | 2.5, 100, \-3.14             |
| boolean  | Boolean values                     | true, false, 1, 0, yes, no   |
| datetime | Date and time values               | "2026-01-15T00:00:00Z"       |

### Define a schema

Before custom metadata can be extracted, define a schema in your AI Search configuration using the `custom_metadata` field. The schema specifies which fields to extract and their data types.

TypeScript

```

custom_metadata: [

  { field_name: "category", data_type: "text" },

  { field_name: "version", data_type: "number" },

  { field_name: "is_public", data_type: "boolean" },

];


```

**Schema constraints:**

* Maximum of 5 custom metadata fields per AI Search instance
* Field names are case-insensitive and stored as lowercase
* Field names cannot use reserved names: `timestamp`, `folder`, `filename`
* Text values are truncated to 500 characters
* Changing the schema triggers a full re-index of all documents

### Add custom metadata to documents

How you attach custom metadata depends on your data source:

* **R2 bucket**: Set metadata using S3-compatible custom headers (`x-amz-meta-*`). Refer to [R2 custom metadata](https://developers.cloudflare.com/ai-search/configuration/data-source/r2/#custom-metadata) for examples.
* **Website**: Add `<meta>` tags to your HTML pages. Refer to [Website custom metadata](https://developers.cloudflare.com/ai-search/configuration/data-source/website/#custom-metadata) for details.
* **Built-in storage**: Attach metadata when uploading files through the [Items API](https://developers.cloudflare.com/ai-search/api/items/workers-binding/#upload-with-metadata).

## Metadata filtering

Metadata filtering narrows down search results based on metadata, so only relevant content is retrieved. The filter is applied before retrieval, so you only query the documents that matter.

Note

If you are using the legacy AutoRAG API, refer to [Metadata filter format (legacy)](https://developers.cloudflare.com/ai-search/api/migration/autorag-filter-format/) for the filter syntax.

Here is an example of metadata filtering using the [Workers binding](https://developers.cloudflare.com/ai-search/api/search/workers-binding/):

TypeScript

```

const instance = env.AI_SEARCH.get("my-instance");


const results = await instance.search({

  messages: [{ role: "user", content: "What is Cloudflare?" }],

  ai_search_options: {

    retrieval: {

      filters: {

        folder: "docs/getting-started/",

        timestamp: { $gte: 1735689600 },

      },

    },

  },

});


```

### Filter syntax

Filters are JSON objects where keys are metadata attribute names and values specify the filter condition.

#### Supported operators

| Operator | Description                       |
| -------- | --------------------------------- |
| $eq      | Equals                            |
| $ne      | Not equals                        |
| $in      | In (matches any value in array)   |
| $nin     | Not in (excludes values in array) |
| $lt      | Less than                         |
| $lte     | Less than or equal to             |
| $gt      | Greater than                      |
| $gte     | Greater than or equal to          |

#### Implicit `$eq`

When you provide a direct value without an operator, it is treated as an equality check:

```

{

  "ai_search_options": {

    "retrieval": {

      "filters": { "folder": "docs/getting-started/" }

    }

  }

}


```

This is equivalent to:

```

{

  "ai_search_options": {

    "retrieval": {

      "filters": { "folder": { "$eq": "docs/getting-started/" } }

    }

  }

}


```

#### Range queries

Combine upper and lower bound operators to filter by ranges:

```

{

  "ai_search_options": {

    "retrieval": {

      "filters": { "timestamp": { "$gte": 1735689600, "$lt": 1735900000 } }

    }

  }

}


```

#### Multiple conditions (implicit AND)

When you specify multiple keys, all conditions must match:

```

{

  "ai_search_options": {

    "retrieval": {

      "filters": {

        "folder": "docs/getting-started/",

        "timestamp": { "$gte": 1735689600 }

      }

    }

  }

}


```

#### `$in` operator

Match any value in an array:

```

{

  "ai_search_options": {

    "retrieval": {

      "filters": { "folder": { "$in": ["docs/guides/", "docs/tutorials/"] } }

    }

  }

}


```

### "Starts with" filter for folders

Use range queries to filter for all files within a folder and its subfolders.

For example, consider this file structure:

* Directorydocs  
   * guide.pdf  
   * Directorytutorials  
         * Directorygetting-started  
                  * intro.pdf

Using `{ "folder": "docs/" }` only matches files directly in that folder (like `guide.pdf`), not files in subfolders.

To match all files starting with `docs/`, use a range query:

```

{

  "ai_search_options": {

    "retrieval": {

      "filters": { "folder": { "$gte": "docs/", "$lt": "docs0" } }

    }

  }

}


```

This works because:

* `$gte` includes all paths starting with `docs/`
* `$lt` with `docs0` excludes paths that do not start with `docs/` (since `0` comes after `/` in ASCII)

## Re-indexing behavior

When you modify the `custom_metadata` schema:

1. New fields are added to the search index.
2. Removed fields are deleted from the search index.
3. A full re-index is triggered for all documents.
4. Existing vectors are updated with the new metadata structure.

## Limitations

| Constraint                | Limit                       |
| ------------------------- | --------------------------- |
| Maximum custom fields     | 5 per AI Search instance    |
| Maximum text value length | 500 characters              |
| Reserved field names      | timestamp, folder, filename |
| Field name matching       | Case-insensitive            |

If file metadata exceeds size limits, the metadata is replaced with an error indicator:

```

{

  "file": { "error": "metadata is too large" }

}


```

To avoid this, keep individual metadata values concise.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/configuration/","name":"Configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/configuration/indexing/","name":"Indexing"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/configuration/indexing/metadata/","name":"Metadata"}}]}
```

---

---
title: Path filtering
description: Control which files or URLs AI Search indexes by defining include and exclude path patterns.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Path filtering

Path filtering allows you to control which files or URLs are indexed by defining include and exclude patterns. Use this to limit indexing to specific content or to skip files you do not want searchable.

Path filtering works with both [website](https://developers.cloudflare.com/ai-search/configuration/data-source/website/) and [R2](https://developers.cloudflare.com/ai-search/configuration/data-source/r2/) data sources.

## Configuration

You can configure path filters when creating or editing an AI Search instance. In the dashboard, open **Path Filters** and add your include or exclude rules. You can also update path filters at any time from the **Settings** page of your instance.

When using the REST API, specify `include_items` and `exclude_items` in the `source_params` of your configuration:

| Parameter      | Type       | Limit               | Description                                              |
| -------------- | ---------- | ------------------- | -------------------------------------------------------- |
| include\_items | string\[\] | Maximum 10 patterns | Only index items matching at least one of these patterns |
| exclude\_items | string\[\] | Maximum 10 patterns | Skip items matching any of these patterns                |

Both parameters are optional. If neither is specified, all items from the data source are indexed.

## Filtering behavior

### Wildcard rules

Exclude rules take precedence over include rules. Filtering is applied in this order:

1. **Exclude check**: If the item matches any exclude pattern, it is skipped.
2. **Include check**: If include patterns are defined and the item does not match any of them, it is skipped.
3. **Index**: The item proceeds to indexing.

| Scenario                    | Behavior                                                                               |
| --------------------------- | -------------------------------------------------------------------------------------- |
| No rules defined            | All items are indexed                                                                  |
| Only exclude\_items defined | All items except those matching exclude patterns are indexed                           |
| Only include\_items defined | Only items matching at least one include pattern are indexed                           |
| Both defined                | Exclude patterns are checked first, then remaining items must match an include pattern |

### Pattern syntax

Patterns use a case-sensitive wildcard syntax based on [micromatch ↗](https://github.com/micromatch/micromatch):

| Wildcard | Meaning                                              |
| -------- | ---------------------------------------------------- |
| \*       | Matches any characters except path separators (/)    |
| \*\*     | Matches any characters including path separators (/) |

Patterns can contain:

* Letters, numbers, and underscores (`a-z`, `A-Z`, `0-9`, `_`)
* Hyphens (`-`) and dots (`.`)
* Path separators (`/`)
* URL characters (`?`, `:`, `=`, `&`, `%`)
* Wildcards (`*`, `**`)

### Indexing job status

Items skipped by filtering rules are recorded in job logs with the reason:

* Exclude match: `Skipped by rule: {pattern}`
* No include match: `Skipped by Include Rules`

You can view these in the Jobs tab of your AI Search instance to verify your filters are working as expected.

### Important notes

* **Case sensitivity:** Pattern matching is case-sensitive. `/Blog/*` does not match `/blog/post.html`.
* **Full path matching:** Patterns match the entire path or URL. Use `**` at the beginning for partial matching. For example, `docs/*` matches `docs/file.pdf` but not `site/docs/file.pdf`, while `**/docs/*` matches both.
* **Single `*` does not cross directories:** Use `**` to match across path separators. For example, `docs/*` matches `docs/file.pdf` but not `docs/sub/file.pdf`, while `docs/**` matches both.
* **Trailing slashes matter:** URLs are matched as-is without normalization. `/blog/` does not match `/blog`.

## Examples

### R2 data source

| Use case                        | Pattern                                         | Indexed                            | Skipped                           |
| ------------------------------- | ----------------------------------------------- | ---------------------------------- | --------------------------------- |
| Index only PDFs in docs         | Include: /docs/\*\*/\*.pdf                      | /docs/guide.pdf, /docs/api/ref.pdf | /docs/guide.md, /images/logo.png  |
| Exclude temp and backup files   | Exclude: \*\*/\*.tmp, \*\*/\*.bak               | /docs/guide.md                     | /data/cache.tmp, /old.bak         |
| Exclude temp and backup folders | Exclude: /temp/\*\*, /backup/\*\*               | /docs/guide.md                     | /temp/file.txt, /backup/data.json |
| Index docs but exclude drafts   | Include: /docs/\*\*, Exclude: /docs/drafts/\*\* | /docs/guide.md                     | /docs/drafts/wip.md               |

### Website data source

| Use case                      | Pattern                                                 | Indexed                                            | Skipped                                        |
| ----------------------------- | ------------------------------------------------------- | -------------------------------------------------- | ---------------------------------------------- |
| Index only blog pages         | Include: \*\*/blog/\*\*                                 | example.com/blog/post, example.com/en/blog/article | example.com/about                              |
| Exclude admin pages           | Exclude: \*\*/admin/\*\*                                | example.com/blog/post                              | example.com/admin/settings                     |
| Exclude login pages           | Exclude: \*\*/login\*                                   | example.com/blog/post                              | example.com/login, example.com/auth/login-form |
| Index docs but exclude drafts | Include: \*\*/docs/\*\*, Exclude: \*\*/docs/drafts/\*\* | example.com/docs/guide                             | example.com/docs/drafts/wip                    |

### API format

When using the API, specify patterns in `source_params`:

```

{

  "source_params": {

    "include_items": ["<PATTERN_1>", "<PATTERN_2>"],

    "exclude_items": ["<PATTERN_1>", "<PATTERN_2>"]

  }

}


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/configuration/","name":"Configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/configuration/indexing/","name":"Indexing"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/configuration/indexing/path-filtering/","name":"Path filtering"}}]}
```

---

---
title: Service API token
description: Create a service API token to grant AI Search read access to R2 buckets for indexing.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Service API token

A service API token grants AI Search permission to access [R2](https://developers.cloudflare.com/r2/) buckets in your account. This token is only required if you connect an R2 bucket as a data source. If you use a website or upload files directly through the [Items API](https://developers.cloudflare.com/ai-search/api/items/workers-binding/), you do not need a service API token.

## When you need a service API token

You need a service API token when you create an AI Search instance with `type: "r2"`. The token authorizes AI Search to read objects from your R2 bucket for indexing.

## Create via the dashboard or Wrangler

The simplest way to get a service API token is to create an R2-backed AI Search instance through the [dashboard](https://developers.cloudflare.com/ai-search/get-started/dashboard/) or [Wrangler CLI](https://developers.cloudflare.com/ai-search/get-started/wrangler/) at least once. Cloudflare creates and registers a service token for you automatically during the setup flow.

Once created, the token is saved to your account and reused across all AI Search instances. You do not need to create a new token for each instance.

## Create via the API

If you need to create a service API token programmatically, follow these steps.

### 1\. Create an API token with token creation permissions

You need an [API token](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/) with permission to create other tokens.

1. In the Cloudflare dashboard, go to **My Profile** \> **API Tokens**.  
[ Go to **API Tokens** ](https://dash.cloudflare.com/profile/api-tokens)
2. Select **Create Token**.
3. Select **Create Custom Token**.
4. Enter a **Token name**, for example `Token Creator`.
5. Under **Permissions**, select **User** \> **API Tokens** \> **Edit**.
6. Select **Continue to summary**, then select **Create Token**.
7. Copy and save the token value. This is your `CREATOR_TOKEN`.

### 2\. Create the service token

Use the [Create token API](https://developers.cloudflare.com/api/resources/user/subresources/tokens/methods/create/) to create a service token with the AI Search Index Engine permission. Replace `<CREATOR_TOKEN>` with the token from step 1 and `<ACCOUNT_ID>` with your [account ID](https://developers.cloudflare.com/fundamentals/account/find-account-and-zone-ids/).

Terminal window

```

curl -X POST "https://api.cloudflare.com/client/v4/user/tokens" \

  -H "Authorization: Bearer <CREATOR_TOKEN>" \

  -H "Content-Type: application/json" \

  --data '{

    "name": "AI Search Service API Token",

    "policies": [

      {

        "effect": "allow",

        "resources": {

          "com.cloudflare.api.account.<ACCOUNT_ID>": "*"

        },

        "permission_groups": [

          { "id": "9e9b428a0bcd46fd80e580b46a69963c" }

        ]

      }

    ]

  }'


```

Save the `id` and `value` from the response:

```

{

  "result": {

    "id": "<CF_API_ID>",

    "name": "AI Search Service API Token",

    "status": "active",

    "value": "<CF_API_KEY>"

  },

  "success": true

}


```

### 3\. Register the token with AI Search

Use the [AI Search tokens API](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/tokens/methods/create/) to register the service token. Replace `<API_TOKEN>` with an API token that has AI Search Edit permissions.

Terminal window

```

curl -X POST "https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai-search/tokens" \

  -H "Authorization: Bearer <API_TOKEN>" \

  -H "Content-Type: application/json" \

  --data '{

    "cf_api_id": "<CF_API_ID>",

    "cf_api_key": "<CF_API_KEY>",

    "name": "AI Search Service Token"

  }'


```

Save the `id` from the response. This is your `token_id` to pass when creating R2-backed instances:

```

{

  "success": true,

  "result": {

    "id": "<TOKEN_ID>",

    "name": "AI Search Service Token",

    "cf_api_id": "<CF_API_ID>",

    "created_at": "2025-12-25 01:52:28",

    "enabled": true

  }

}


```

### 4\. Use the token when creating an instance

Pass the `token_id` when creating an R2-backed instance:

Terminal window

```

curl -X POST "https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai-search/instances" \

  -H "Authorization: Bearer <API_TOKEN>" \

  -H "Content-Type: application/json" \

  --data '{

    "id": "my-r2-docs",

    "type": "r2",

    "source": "<R2_BUCKET_NAME>",

    "token_id": "<TOKEN_ID>"

  }'


```

## Manage your token

Once registered, the service API token is stored securely and reused across all AI Search instances in your account.

Warning

Do not delete your service API token. If you revoke or delete the token, any R2-backed AI Search instances will lose access to their data source and stop indexing.

### Rotate your token

To create a new service API token from the dashboard:

1. Go to an existing AI Search instance in the Cloudflare dashboard.  
[ Go to **AI Search** ](https://dash.cloudflare.com/?to=/:account/ai/ai-search)
2. Select **Settings**.
3. Under **General**, find **Service API Token** and select the edit icon.
4. Select **Create a new token**.
5. Select **Save**.

To create a new token via the API, follow [steps 1 through 3](#1-create-an-api-token-with-token-creation-permissions) above.

### View registered tokens

List the service API tokens registered with AI Search in your account:

Terminal window

```

curl https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai-search/tokens \

  -H "Authorization: Bearer <API_TOKEN>"


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/configuration/","name":"Configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/configuration/indexing/","name":"Indexing"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/configuration/indexing/service-api-token/","name":"Service API token"}}]}
```

---

---
title: Syncing
description: Understand how AI Search automatically syncs and indexes content from connected data sources.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Syncing

AI Search automatically indexes your content for search. How indexing works depends on your data source.

## External data sources

For instances connected to a [website](https://developers.cloudflare.com/ai-search/configuration/data-source/website/) or [R2 bucket](https://developers.cloudflare.com/ai-search/configuration/data-source/r2/), AI Search creates jobs to sync your data source. Jobs run automatically every 6 hours and process new, modified, or deleted files to keep your search index up to date.

You can view job status and history in the **Jobs** tab in the dashboard or using the [Instances API](https://developers.cloudflare.com/ai-search/api/instances/rest-api/).

## Built-in storage

Files uploaded to [built-in storage](https://developers.cloudflare.com/ai-search/configuration/data-source/built-in-storage/) are indexed immediately. There are no sync jobs. Each file is processed individually as it is uploaded.

## Controls

| Action               | Description                                                                                                 |
| -------------------- | ----------------------------------------------------------------------------------------------------------- |
| Trigger sync         | Manually start a sync job to scan your external data source for changes. Can be triggered every 30 seconds. |
| Cancel job           | Cancel a running sync job.                                                                                  |
| Pause indexing       | Temporarily stop all scheduled sync jobs.                                                                   |
| Resume indexing      | Resume scheduled sync jobs.                                                                                 |
| Sync individual file | Re-index a specific file.                                                                                   |

You can perform these actions from the dashboard, the [REST API](https://developers.cloudflare.com/ai-search/api/instances/rest-api/), or the [Workers binding](https://developers.cloudflare.com/ai-search/api/instances/workers-binding/).

## Performance

The total time to index depends on the number and type of files. Factors that affect performance include:

* Total number of files and their sizes
* File formats (for example, images take longer than plain text)
* Latency of Workers AI models used for embedding and image processing

## Best practices

To ensure smooth and reliable indexing:

* Make sure your files are within the [size limit](https://developers.cloudflare.com/ai-search/configuration/data-source/#file-limits) and in a [supported format](https://developers.cloudflare.com/ai-search/configuration/data-source/#supported-file-types) to avoid being skipped.
* For R2-backed instances, keep your [service API token](https://developers.cloudflare.com/ai-search/configuration/indexing/service-api-token/) valid to prevent indexing failures.
* Regularly clean up outdated or unnecessary content to stay within [instance limits](https://developers.cloudflare.com/ai-search/platform/limits-pricing/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/configuration/","name":"Configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/configuration/indexing/","name":"Indexing"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/configuration/indexing/syncing/","name":"Syncing"}}]}
```

---

---
title: Vector search
description: Configure vector search in AI Search to find semantically similar content using embeddings.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Vector search

Vector search converts your query into a vector embedding and finds chunks with similar meaning. It is enabled by default on all AI Search instances. For an overview of search modes, refer to [Search modes](https://developers.cloudflare.com/ai-search/concepts/search-modes/).

## Built-in vector index

Instances created after **April 16, 2026** include a built-in vector index powered by [Vectorize](https://developers.cloudflare.com/vectorize/). The vector index stores embeddings generated from your content and is created and maintained automatically. You do not need to create or manage a Vectorize index yourself.

Instances created before this date use a Vectorize index provisioned on your account. These instances are billed separately for Vectorize usage. All instances created before this date will be automatically migrated to managed infrastructure on **June 3, 2026**. For details, refer to [Limits & pricing](https://developers.cloudflare.com/ai-search/platform/limits-pricing/#previous-instances).

## Embedding model

The [embedding model](https://developers.cloudflare.com/ai-search/configuration/models/) determines the vector dimensions for the vector index. The embedding model is set when creating an instance and cannot be changed after creation.

## Disable vector search

Vector search is the default index method for all instances. To switch to [keyword search](https://developers.cloudflare.com/ai-search/configuration/indexing/keyword-search/) only, set `index_method.vector` to `false`. At least one of `vector` or `keyword` must be `true`.

TypeScript

```

const instance = await env.AI_SEARCH.create({

  id: "my-instance",

  index_method: {

    vector: false,

    keyword: true,

  },

});


```

## Per-request overrides

You can force vector-only search on a per-request basis using `ai_search_options.retrieval.retrieval_type`, even if keyword search is also enabled on the instance.

TypeScript

```

const instance = env.AI_SEARCH.get("my-instance");


const results = await instance.search({

  messages: [{ role: "user", content: "What is Cloudflare?" }],

  ai_search_options: {

    retrieval: {

      retrieval_type: "vector",

    },

  },

});


```

## Scoring details

When using vector search, each chunk includes a `scoring_details` object:

| Field         | Type   | Description                       |
| ------------- | ------ | --------------------------------- |
| vector\_score | number | Vector similarity score (0 to 1). |
| vector\_rank  | number | Rank position in the result set.  |

## Limits

For vector index limits, refer to [Limits and pricing](https://developers.cloudflare.com/ai-search/platform/limits-pricing/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/configuration/","name":"Configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/configuration/indexing/","name":"Indexing"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/configuration/indexing/vector-search/","name":"Vector search"}}]}
```

---

---
title: Models
description: Configure which AI models AI Search uses for embedding, generation, reranking, and query rewriting.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Models

AI Search uses models at multiple stages. You can configure which models are used, or let AI Search automatically select a smart default for you.

## Models usage

AI Search leverages Workers AI models in the following stages:

* Image to markdown conversion (if images are in data source): Converts image content to Markdown using object detection and captioning models.
* Embedding: Transforms your documents and queries into vector representations for semantic search.
* Query rewriting (optional): Reformulates the user’s query to improve retrieval accuracy.
* Reranking (optional): Reorders retrieved results by semantic relevance using a cross-encoder model.
* Generation: Produces the final response from retrieved context.

## Model providers

All AI Search instances support models from [Workers AI](https://developers.cloudflare.com/workers-ai). You can use other providers (such as OpenAI or Anthropic) in AI Search by adding their API keys to an [AI Gateway](https://developers.cloudflare.com/ai-gateway) and connecting that gateway to your AI Search.

To use AI Search with other model providers:

1. Add provider keys to [AI Gateway](https://developers.cloudflare.com/ai-gateway/configuration/bring-your-own-keys/).
2. Connect the gateway to AI Search.  
   * When creating a new AI Search, select the AI Gateway with your provider keys.  
   * For an existing AI Search, go to **Settings** and switch to a gateway that has your keys under **Resources**.
3. Select models  
   * Embedding model: Only available to be changed when creating a new AI Search.  
   * Generation model: Can be selected when creating a new AI Search and can be changed at any time in **Settings**.

AI Search supports a subset of models that have been selected to provide the best experience. Refer to the list of [supported models](https://developers.cloudflare.com/ai-search/configuration/models/supported-models/).

### Smart default

If you choose **Smart Default** in your model selection, then AI Search will select a Cloudflare recommended model and will update it automatically for you over time. You can switch to explicit model configuration at any time by visiting **Settings**.

### Per-request generation model override

While the generation model can be set globally at the AI Search instance level, you can also override it on a per-request basis in the [AI Search API](https://developers.cloudflare.com/ai-search/api/search/rest-api/#chat-completions). This is useful when you need dynamic selection of generation models based on context or user preferences.

## Model deprecation

AI Search may deprecate support for a given model in order to provide support for better-performing models with improved capabilities. When a model is being deprecated, we announce the change and provide an end-of-life date after which the model will no longer be accessible. Applications that depend on AI Search may therefore require occasional updates to continue working reliably.

### Model lifecycle

AI Search models follow a defined lifecycle to ensure stability and predictable deprecation:

1. **Production:** The model is actively supported and recommended for use. It is included in Smart Defaults and receives ongoing updates and maintenance.
2. **Announcement & Transition:** The model remains available but has been marked for deprecation. An end-of-life date is communicated through documentation, release notes, and other official channels. During this phase, users are encouraged to migrate to the recommended replacement model.
3. **Automatic Upgrade (if applicable):** If you have selected the Smart Default option, AI Search will automatically upgrade requests to a recommended replacement.
4. **End of life:** The model is no longer available. Any requests to the retired model return a clear error message, and the model is removed from documentation and Smart Defaults.

Learn more about models and their lifecycle status in [supported models](https://developers.cloudflare.com/ai-search/configuration/models/supported-models/).

### Best practices

* Regularly check the [release note](https://developers.cloudflare.com/ai-search/platform/release-note/) for updates.
* Plan migration efforts according to the communicated end-of-life date.
* Migrate and test the recommended replacement models before the end-of-life date.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/configuration/","name":"Configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/configuration/models/","name":"Models"}}]}
```

---

---
title: Supported models
description: View all AI models supported by AI Search, including text generation, embedding, and reranking models.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Supported models

This page lists all models supported by AI Search and their lifecycle status.

Request model support

If you would like to use a model that is not currently supported, reach out to us on [Discord ↗](https://discord.gg/cloudflaredev) to request it.

## Production models

Production models are the actively supported and recommended models that are stable and fully available.

### Text generation

| Provider                                    | Alias                                    | Context window (tokens) |
| ------------------------------------------- | ---------------------------------------- | ----------------------- |
| **Anthropic**                               | anthropic/claude-3-7-sonnet              | 200,000                 |
| anthropic/claude-sonnet-4                   | 200,000                                  |                         |
| anthropic/claude-opus-4                     | 200,000                                  |                         |
| anthropic/claude-3-5-haiku                  | 200,000                                  |                         |
| **Cerebras**                                | cerebras/qwen-3-235b-a22b-instruct       | 64,000                  |
| cerebras/qwen-3-235b-a22b-thinking          | 65,000                                   |                         |
| cerebras/llama-3.3-70b                      | 65,000                                   |                         |
| cerebras/llama-4-maverick-17b-128e-instruct | 8,000                                    |                         |
| cerebras/llama-4-scout-17b-16e-instruct     | 8,000                                    |                         |
| cerebras/gpt-oss-120b                       | 64,000                                   |                         |
| **Google AI Studio**                        | google-ai-studio/gemini-2.5-flash        | 1,048,576               |
| google-ai-studio/gemini-2.5-pro             | 1,048,576                                |                         |
| **Grok (x.ai)**                             | grok/grok-4                              | 256,000                 |
| **Groq**                                    | groq/llama-3.3-70b-versatile             | 131,072                 |
| groq/llama-3.1-8b-instant                   | 131,072                                  |                         |
| **OpenAI**                                  | openai/gpt-5                             | 400,000                 |
| openai/gpt-5-mini                           | 400,000                                  |                         |
| openai/gpt-5-nano                           | 400,000                                  |                         |
| **Workers AI**                              | @cf/meta/llama-3.3-70b-instruct-fp8-fast | 24,000                  |
| @cf/meta/llama-3.1-8b-instruct-fast         | 60,000                                   |                         |
| @cf/meta/llama-3.1-8b-instruct-fp8          | 32,000                                   |                         |
| @cf/meta/llama-4-scout-17b-16e-instruct     | 131,000                                  |                         |
| @cf/zai-org/glm-4.7-flash                   | 131,072                                  |                         |
| @cf/qwen/qwen3-30b-a3b-fp8                  | 32,000                                   |                         |

### Embedding

| Provider                       | Alias                                 | Vector dims | Input tokens | Metric |
| ------------------------------ | ------------------------------------- | ----------- | ------------ | ------ |
| **Google AI Studio**           | google-ai-studio/gemini-embedding-001 | 1,536       | 2048         | cosine |
| **OpenAI**                     | openai/text-embedding-3-small         | 1,536       | 8192         | cosine |
| openai/text-embedding-3-large  | 1,536                                 | 8192        | cosine       |        |
| **Workers AI**                 | @cf/baai/bge-m3                       | 1,024       | 512          | cosine |
| @cf/baai/bge-large-en-v1.5     | 1,024                                 | 512         | cosine       |        |
| @cf/qwen/qwen3-embedding-0.6b  | 1,024                                 | 4,096       | cosine       |        |
| @cf/google/embeddinggemma-300m | 768                                   | 512         | cosine       |        |

### Reranking

| Provider       | Alias                      | Input tokens |
| -------------- | -------------------------- | ------------ |
| **Workers AI** | @cf/baai/bge-reranker-base | 512          |

## Transition models

There are currently no models marked for end-of-life.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/configuration/","name":"Configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/configuration/models/","name":"Models"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/configuration/models/supported-models/","name":"Supported models"}}]}
```

---

---
title: Relevance boosting
description: Bias AI Search results toward documents with specific metadata using relevance boosting.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Relevance boosting

Boosting lets you bias search results toward documents with specific metadata characteristics. For example, you can promote recent documents, surface higher-priority pages, or deprioritize drafts. Boosting re-ranks results without replacing semantic relevance.

## How it works

Boosting applies after the initial retrieval step and before [reranking](https://developers.cloudflare.com/ai-search/configuration/retrieval/reranking/) (if enabled):

1. **Search**: AI Search retrieves up to 50 candidate chunks using vector search, keyword search, or both.
2. **Boost**: Each candidate is re-scored using the metadata fields you specify in `boost_by`. The boost is additive to the original retrieval score.
3. **Rerank**: If reranking is enabled, the boosted results are reranked by a reranking model.
4. **Return**: The top `max_num_results` are returned.

Boosting can change the order of results within the candidate set, but cannot promote a chunk that the initial search step did not retrieve.

## Supported fields

You can boost by the built-in `timestamp` field or by any field defined in your [custom metadata schema](https://developers.cloudflare.com/ai-search/configuration/indexing/metadata/#define-a-schema).

| Field type | Supported directions           |
| ---------- | ------------------------------ |
| datetime   | asc, desc, exists, not\_exists |
| number     | asc, desc, exists, not\_exists |
| text       | exists, not\_exists only       |
| boolean    | exists, not\_exists only       |

### Directions

The direction controls how the field value affects the ranking of each result:

| Direction   | Effect                                                       |
| ----------- | ------------------------------------------------------------ |
| desc        | Higher field values score higher (for example, most recent). |
| asc         | Lower field values score higher (for example, lowest cost).  |
| exists      | Documents that have the field score higher.                  |
| not\_exists | Documents that do not have the field score higher.           |

If you omit `direction`, AI Search applies a default based on the field type:

| Field type                  | Default direction |
| --------------------------- | ----------------- |
| number, datetime, timestamp | asc               |
| text, boolean               | exists            |

Using `asc` or `desc` on a `text` or `boolean` field returns an error.

## Configuration

Specify `boost_by` as an array of up to 3 objects when creating or updating an instance. Each object must reference a unique field.

| Field     | Type   | Required | Description                                                                 |
| --------- | ------ | -------- | --------------------------------------------------------------------------- |
| field     | string | Yes      | Metadata field name or timestamp. Must match your schema. Case-insensitive. |
| direction | string | No       | One of asc, desc, exists, not\_exists. Defaults by type.                    |

TypeScript

```

const instance = await env.AI_SEARCH.create({

  id: "my-instance",

  retrieval_options: {

    boost_by: [

      { field: "timestamp", direction: "desc" },

      { field: "priority", direction: "desc" },

    ],

  },

});


```

To remove boosting, set `boost_by` to an empty array when updating the instance.

## Per-request overrides

You can override `boost_by` on individual requests using `ai_search_options.retrieval`. Per-request values fully replace the instance-level default.

TypeScript

```

const instance = env.AI_SEARCH.get("my-instance");


const results = await instance.search({

  messages: [{ role: "user", content: "What is Cloudflare?" }],

  ai_search_options: {

    retrieval: {

      boost_by: [{ field: "timestamp", direction: "desc" }],

    },

  },

});


```

To disable boosting for a single request, pass an empty array:

TypeScript

```

const results = await instance.search({

  messages: [{ role: "user", content: "What is Cloudflare?" }],

  ai_search_options: {

    retrieval: {

      boost_by: [],

    },

  },

});


```

## Common patterns

Here are some common ways to use relevance boosting:

| Pattern                          | Configuration                                                                                   |
| -------------------------------- | ----------------------------------------------------------------------------------------------- |
| Prioritize recent documents      | \[{ "field": "timestamp", "direction": "desc" }\]                                               |
| Promote by custom priority       | \[{ "field": "priority", "direction": "desc" }\]                                                |
| Boost lower-cost options         | \[{ "field": "cost", "direction": "asc" }\]                                                     |
| Promote documents with an author | \[{ "field": "author", "direction": "exists" }\]                                                |
| Suppress drafts                  | \[{ "field": "draft", "direction": "not\_exists" }\]                                            |
| Combine recency and priority     | \[{ "field": "timestamp", "direction": "desc" }, { "field": "priority", "direction": "desc" }\] |

## Limitations

* Maximum of 3 boost fields per request.
* Field names must match a field in your custom metadata schema or the built-in `timestamp` field.
* `text` and `boolean` fields only support `exists` and `not_exists` directions.
* Boost fields within a single request must be unique.
* Boosting re-ranks the candidate set from the initial search. It cannot surface documents that were not retrieved.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/configuration/","name":"Configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/configuration/retrieval/","name":"Retrieval"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/configuration/retrieval/boosting/","name":"Relevance boosting"}}]}
```

---

---
title: Similarity cache
description: Speed up AI Search responses by caching and reusing answers for semantically similar queries.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Similarity cache

Similarity-based caching in AI Search lets you serve responses from Cloudflare's cache for queries that are similar to previous requests, rather than creating new, unique responses for every request. This speeds up response times and cuts costs by reusing answers for questions that are close in meaning.

## How it works

Unlike with basic caching, which creates a new response with every request, this is what happens when a request is received using similarity-based caching:

1. AI Search checks if a _similar_ prompt (based on your chosen threshold) has been answered before.
2. If a match is found, it returns the cached response instantly.
3. If no match is found, it generates a new response and caches it.

To see if a response came from the cache, check the `cf-aig-cache-status` header: `HIT` for cached and `MISS` for new.

## What to consider when using similarity cache

Consider these behaviors when using similarity caching:

* **Volatile Cache**: If two similar requests hit at the same time, the first might not cache in time for the second to use it, resulting in a `MISS`.
* **30-Day Cache**: Cached responses last 30 days, then expire automatically. No custom durations for now.
* **Data Dependency**: Cached responses are tied to specific document chunks. If those chunks change or get deleted, the cache clears to keep answers fresh.

## How similarity matching works

AI Search's similarity cache uses **MinHash and Locality-Sensitive Hashing (LSH)** to find and reuse responses for prompts that are worded similarly.

Here's how it works when a new prompt comes in:

1. The prompt is split into small overlapping chunks of words (called shingles), like "what's the" or "the weather."
2. These shingles are turned into a "fingerprint" using MinHash. The more overlap two prompts have, the more similar their fingerprints will be.
3. Fingerprints are placed into LSH buckets, which help AI Search quickly find similar prompts without comparing every single one.
4. If a past prompt in the same bucket is similar enough (based on your configured threshold), AI Search reuses its cached response.

## Choose a threshold

The similarity threshold decides how close two prompts need to be to reuse a cached response. You can set the threshold at the instance level or override it per request.

| Threshold | API value               | Description                 | Example match                                                                   |
| --------- | ----------------------- | --------------------------- | ------------------------------------------------------------------------------- |
| Exact     | super\_strict\_match    | Near-identical matches only | "What's the weather like today?" matches with "What is the weather like today?" |
| Strong    | close\_enough (default) | High semantic similarity    | "What's the weather like today?" matches with "How's the weather today?"        |
| Broad     | flexible\_friend        | Moderate match, more hits   | "What's the weather like today?" matches with "Tell me today's weather"         |
| Loose     | anything\_goes          | Low similarity, max reuse   | "What's the weather like today?" matches with "Give me the forecast"            |

## Per-request cache override

You can override the instance-level cache setting on a per-request basis using the `cache` parameter in `ai_search_options`:

TypeScript

```

const instance = env.AI_SEARCH.get("my-instance");


const results = await instance.search({

  messages: [{ role: "user", content: "What is Cloudflare?" }],

  ai_search_options: {

    cache: {

      enabled: true,

      cache_threshold: "flexible_friend",

    },

  },

});


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/configuration/","name":"Configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/configuration/retrieval/","name":"Retrieval"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/configuration/retrieval/cache/","name":"Similarity cache"}}]}
```

---

---
title: UI snippets
description: Add AI Search to your website using pre-built, customizable web components for search and chat.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# UI snippets

You can add AI Search easily into your website using the [Cloudflare AI Search UI snippet library ↗](https://search.ai.cloudflare.com/), which provides production-ready, customizable web components.

The library is open source at [github.com/cloudflare/ai-search-snippet ↗](https://github.com/cloudflare/ai-search-snippet).

## Available components

The snippet library provides four web components. Each component connects to your AI Search instance using the `api-url` attribute, which should point to your public endpoint URL.

| Component              | Description                                                 |
| ---------------------- | ----------------------------------------------------------- |
| <search-bar-snippet>   | An inline search bar that displays results in a dropdown    |
| <search-modal-snippet> | A search modal that opens with Cmd/Ctrl+K keyboard shortcut |
| <chat-bubble-snippet>  | A floating chat bubble in the corner of the page            |
| <chat-page-snippet>    | A full-page chat interface with conversation history        |

For advanced styling and configuration, visit [search.ai.cloudflare.com ↗](https://search.ai.cloudflare.com/).

## Prerequisites

UI snippets connect to your AI Search instance through a public endpoint. You need to enable this endpoint before using the snippets.

1. Go to **AI Search** in the Cloudflare dashboard.  
[ Go to **AI Search** ](https://dash.cloudflare.com/?to=/:account/ai/ai-search)
2. Select your AI Search instance.
3. Go to **Settings** \> **Public Endpoint**.
4. Turn on **Enable Public Endpoint**.
5. Copy the public endpoint URL. You will use this as the `api-url` attribute in your snippets.

## Use with HTML

1. Add the script tag to your HTML file (for example, `index.html`). Replace `<INSTANCE_ID>` with your AI Search instance's public endpoint ID, which you can find in your AI Search instance's **Settings** \> **Public Endpoint**.  
```  
<script  
  type="module"  
  src="https://<INSTANCE_ID>.search.ai.cloudflare.com/assets/v0.0.25/search-snippet.es.js"  
></script>  
```
2. Add a component with your `api-url`.  
```  
<search-bar-snippet  
  api-url="https://<INSTANCE_ID>.search.ai.cloudflare.com/"  
  placeholder="Search..."  
></search-bar-snippet>  
```
3. Before testing, [configure CORS](#configure-cors-for-local-testing) to allow your local origin. Then open the HTML file in your browser to test.

### Full HTML example

The following example shows a complete HTML page with a search bar. When a user types in the search bar, results appear in a dropdown below.

```

<!doctype html>

<html>

  <head>

    <script

      type="module"

      src="https://<INSTANCE_ID>.search.ai.cloudflare.com/assets/v0.0.25/search-snippet.es.js"

    ></script>

  </head>

  <body>

    <search-bar-snippet

      api-url="https://<INSTANCE_ID>.search.ai.cloudflare.com/"

      placeholder="Search..."

      max-results="10"

    ></search-bar-snippet>

  </body>

</html>


```

## Use with a framework

* [ React ](#tab-panel-6477)
* [ Vue ](#tab-panel-6478)

1. Open your React project and install the package:  
Terminal window  
```  
npm install @cloudflare/ai-search-snippet  
```
2. In your component file (for example, `src/App.tsx`), import the package:  
```  
import "@cloudflare/ai-search-snippet";  
```
3. Add a component to your JSX:  
```  
export default function App() {  
  return (  
    <search-bar-snippet  
      api-url="https://<INSTANCE_ID>.search.ai.cloudflare.com/"  
      placeholder="Search..."  
    />  
  );  
}  
```
4. Before testing, [configure CORS](#configure-cors-for-local-testing) to allow your local origin. Then run your development server:  
Terminal window  
```  
npm run dev  
```

The package includes TypeScript types and works with React, Next.js, and other React frameworks.

1. Open your Vue project and install the package:  
Terminal window  
```  
npm install @cloudflare/ai-search-snippet  
```
2. In your component file (for example, `src/App.vue`), import the package and add the component:  
```  
<template>  
  <search-bar-snippet :api-url="apiUrl" placeholder="Search..." />  
</template>  
<script setup>  
import "@cloudflare/ai-search-snippet";  
const apiUrl = "https://<INSTANCE_ID>.search.ai.cloudflare.com/";  
</script>  
```
3. Before testing, [configure CORS](#configure-cors-for-local-testing) to allow your local origin. Then run your development server:  
Terminal window  
```  
npm run dev  
```

## Configure CORS for local testing

When testing locally (for example, `http://localhost:3000`), you need to allow your local origin in the public endpoint settings.

1. Go to **AI Search** in the Cloudflare dashboard.  
[ Go to **AI Search** ](https://dash.cloudflare.com/?to=/:account/ai/ai-search)
2. Select your AI Search instance.
3. Go to **Settings** \> **Public Endpoint**.
4. Under **Authorized hosts**, add your local URL (for example, `http://localhost:3000`) or `*` to allow all origins during testing.
5. Select **Save**.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/configuration/","name":"Configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/configuration/retrieval/","name":"Retrieval"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/configuration/retrieval/embed-search-snippets/","name":"UI snippets"}}]}
```

---

---
title: Public endpoint settings
description: Expose AI Search instances through public MCP, chat, and search endpoints without authentication.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Public endpoint settings

Configure public endpoints to expose your AI Search instance directly to users without requiring authentication. This enables you to share your AI Search functionality with external users, or to integrate it into public-facing applications.

## Available endpoints

Each AI Search instance can expose three public endpoints:

| Endpoint          | Description                                   |
| ----------------- | --------------------------------------------- |
| /mcp              | Model Context Protocol endpoint for AI agents |
| /chat/completions | OpenAI-compatible chat completion endpoint    |
| /search           | Search endpoint that returns relevant chunks  |

For details on how to use these endpoints, refer to [Public endpoint usage](https://developers.cloudflare.com/ai-search/api/search/public-endpoint/).

## Public URL format

When enabled, public endpoints are accessible at:

```

https://<hash>.search.ai.cloudflare.com/<endpoint>


```

The `<hash>` is your instance's unique public endpoint identifier.

For example:

* `https://abc123.search.ai.cloudflare.com/mcp`
* `https://abc123.search.ai.cloudflare.com/chat/completions`
* `https://abc123.search.ai.cloudflare.com/search`

## Enabling and disabling public endpoints

You can enable or disable each public endpoint independently:

1. Log in to your Cloudflare account, and go to **AI Search**.[ Go to **AI Search** ](https://dash.cloudflare.com/?to=/:account/ai/ai-search)
2. Select your AI Search instance.
3. Go to **Settings** \> **Public Endpoints**.
4. Toggle on **Public Endpoints** to enable the feature, then toggle each individual endpoint on or off as needed.

Each endpoint has its own configuration panel for granular control.

## Rate limiting

Configure rate limits to control usage across all public endpoints:

| Setting             | Description                               | Default  |
| ------------------- | ----------------------------------------- | -------- |
| Requests per period | Maximum number of requests allowed        | 120      |
| Time period         | Time window for the rate limit            | 1 minute |
| Period type         | Rate limiting technique: fixed or sliding | fixed    |

Rate limits apply across all enabled public endpoints for the AI Search instance.

## CORS configuration

Cross-Origin Resource Sharing (CORS) is enabled by default to support browser-based applications.

The default allowed origins depend on your data source type:

* **Website data sources**: The source domain is automatically added as an allowed origin.
* **Other data sources**: All origins (`*`) are allowed by default.

You can customize allowed origins in the **Public Endpoints** settings by adding specific hostnames to the CORS rules.

## Tool description

The **Tool Description** field allows you to customize how your AI Search instance is described to MCP clients. The default description is `Finds exactly what you're looking for`. This description helps AI agents understand what content is available, and when to use your search tool. A good tool description should explain what type of content is indexed, and what kinds of questions it can answer.

For example:

```

Search the Acme product documentation for information about

installation, configuration, API references, and troubleshooting

guides. Use this tool when users ask questions about how to set up

or use Acme products.


```

## Security considerations

* Public endpoints do not require authentication.
* Consider enabling rate limiting to prevent abuse.
* Use CORS rules to restrict access to specific domains.
* Monitor usage through your dashboard analytics.

## Related

* [UI snippets](https://developers.cloudflare.com/ai-search/configuration/retrieval/embed-search-snippets/) \- Add pre-built search and chat components to your website using your public endpoints.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/configuration/","name":"Configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/configuration/retrieval/","name":"Retrieval"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/configuration/retrieval/public-endpoint/","name":"Public endpoint settings"}}]}
```

---

---
title: Query rewriting
description: Improve AI Search retrieval quality by enabling query rewriting to rephrase user queries.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Query rewriting

Query rewriting is an optional step in the AI Search pipeline that improves retrieval quality for follow-up queries. It applies to both [Search](https://developers.cloudflare.com/ai-search/api/search/workers-binding/#search) and [Chat Completions](https://developers.cloudflare.com/ai-search/api/search/workers-binding/#chatcompletions) requests.

## Why use query rewriting?

The wording of a user's question may not match how your documents are written. Query rewriting helps bridge this gap by:

* Rephrasing informal or vague queries into precise, information-dense terms
* Adding synonyms or related keywords
* Removing filler words or irrelevant details
* Resolving follow-up queries that reference previous messages (for example, "tell me more about that" becomes a specific query based on conversation history)

This leads to more relevant search matches, which improves the accuracy of results and generated responses.

## How it works

Query rewriting requires the `messages` format and does not apply when using the `query` format. The first message is always used as-is. For follow-up queries, AI Search sends the conversation history, the latest user message, and the [query rewrite system prompt](https://developers.cloudflare.com/ai-search/configuration/retrieval/system-prompt/) to the configured LLM. The rewritten query is then embedded and used to perform the search.

## Example

**First message:** `What is Cloudflare Workers?`(used as-is, no rewriting)

**Follow-up message:** `How do I deploy one?` **Rewritten query:** `deploy Cloudflare Worker getting started`

The follow-up "How do I deploy one?" is vague on its own. Query rewriting uses the conversation context to understand "one" refers to a Cloudflare Worker. How the query is rewritten depends on your [query rewrite system prompt](https://developers.cloudflare.com/ai-search/configuration/retrieval/system-prompt/#query-rewriting-system-prompt).

## Considerations

Enabling query rewriting adds an extra LLM call to the query pipeline, which may increase latency.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/configuration/","name":"Configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/configuration/retrieval/","name":"Retrieval"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/configuration/retrieval/query-rewriting/","name":"Query rewriting"}}]}
```

---

---
title: Reranking
description: Enable reranking in AI Search to reorder retrieved results by semantic relevance.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Reranking

Reranking can help improve the quality of AI Search results by reordering retrieved documents based on semantic relevance to the user's query. It applies a secondary model after retrieval to rerank the top results before they are returned.

## How it works

By default, reranking is **disabled** for all AI Search instances. You can enable it during creation or later from the settings page.

When enabled, AI Search will:

1. Retrieve a set of relevant results from your index, constrained by your `max_num_results` and `score_threshold` parameters.
2. Pass those results through a [reranking model](https://developers.cloudflare.com/ai-search/configuration/models/supported-models/).
3. Return the reranked results, which the text generation model can use for answer generation.

Reranking helps improve accuracy, especially for large or noisy datasets where vector similarity alone may not produce the optimal ordering.

## Configuration

When you make a `/search` or `/chat/completions` request using the [Workers binding](https://developers.cloudflare.com/ai-search/api/search/workers-binding/) or [REST API](https://developers.cloudflare.com/ai-search/api/search/rest-api/), you can enable or disable reranking per request and specify the reranking model.

TypeScript

```

const instance = env.AI_SEARCH.get("my-instance");


const results = await instance.search({

  messages: [{ role: "user", content: "What is Cloudflare?" }],

  ai_search_options: {

    reranking: {

      enabled: true,

      model: "@cf/baai/bge-reranker-base",

    },

  },

});


```

### Considerations

Adding reranking will include an additional step to the query request. As a result, there may be an increase in the latency of the request.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/configuration/","name":"Configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/configuration/retrieval/","name":"Retrieval"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/configuration/retrieval/reranking/","name":"Reranking"}}]}
```

---

---
title: Result filtering
description: Control AI Search result count and minimum score thresholds for returned results.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Result filtering

Result filtering controls how many results are returned and the minimum score required. To filter results by metadata attributes like folder or category, refer to [Metadata](https://developers.cloudflare.com/ai-search/configuration/indexing/metadata/).

## Match threshold

The `match_threshold` sets the minimum vector similarity score that a chunk must meet to be included in the results. Threshold values range from `0` to `1`. The threshold filters on the vector similarity score, not the fused score returned in the response.

* A higher threshold means stricter filtering, returning only highly similar matches.
* A lower threshold allows broader matches, increasing recall but possibly reducing precision.

## Maximum number of results

The `max_num_results` setting controls the number of top-matching chunks returned. The maximum allowed value is 50.

* Use a higher value if you want to synthesize across multiple documents. However, providing more input to the model can increase latency and cost.
* Use a lower value if you prefer concise answers with minimal context.

## How they work together

1. Your query is embedded using the configured embedding model.
2. The search index is queried. For [hybrid search](https://developers.cloudflare.com/ai-search/configuration/indexing/hybrid-search/), vector and keyword results are fused into a single ranked list.
3. Chunks with a vector similarity score below `match_threshold` are filtered out.
4. The filtered results are limited to `max_num_results` and passed into the generation step as context.

If no results meet the threshold, AI Search will not generate a response.

If [reranking](https://developers.cloudflare.com/ai-search/configuration/retrieval/reranking/) is enabled, a separate `reranking.match_threshold` can be configured to filter chunks by their reranking score.

## Per-request override

These values can be configured at the instance level or overridden per request:

TypeScript

```

const instance = env.AI_SEARCH.get("my-instance");


const results = await instance.search({

  messages: [{ role: "user", content: "What is Cloudflare?" }],

  ai_search_options: {

    retrieval: {

      match_threshold: 0.5,

      max_num_results: 10,

    },

  },

});


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/configuration/","name":"Configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/configuration/retrieval/","name":"Retrieval"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/configuration/retrieval/result-filtering/","name":"Result filtering"}}]}
```

---

---
title: System prompt
description: Guide AI Search query rewriting and response generation behavior with custom system prompts.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# System prompt

System prompts allow you to guide the behavior of the text-generation models used by AI Search at query time. AI Search supports system prompt configuration in two steps:

* **Query rewriting**: Reformulates the original user query to improve semantic retrieval. A system prompt can guide how the model interprets and rewrites the query.
* **Generation**: Generates the final response from retrieved context. A system prompt can help define how the model should format, filter, or prioritize information when constructing the answer.

## What is a system prompt?

A system prompt is a special instruction sent to a large language model (LLM) that guides how it behaves during inference. The system prompt defines the model's role, context, or rules it should follow.

System prompts are particularly useful for:

* Enforcing specific response formats
* Constraining behavior (for example, it only responds based on the provided content)
* Applying domain-specific tone or terminology
* Encouraging consistent, high-quality output

## System prompt configuration

### Default system prompt

When configuring your AI Search instance, you can provide your own system prompts. If you do not provide a system prompt, AI Search will use the **default system prompt** provided by Cloudflare.

You can view the effective system prompt used for any AI Search's model call through AI Gateway logs, where model inputs and outputs are recorded.

### Configure via API

When you make a `/chat/completions` request using the [Workers binding](https://developers.cloudflare.com/ai-search/api/search/workers-binding/) or [REST API](https://developers.cloudflare.com/ai-search/api/search/rest-api/), you can set the system prompt programmatically.

TypeScript

```

const instance = env.AI_SEARCH.get("my-instance");


const response = await instance.chatCompletions({

  messages: [

    { role: "system", content: "You are a helpful assistant." },

    { role: "user", content: "What is Cloudflare?" },

  ],

  model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast",

});


```

## Generation system prompt

If you are using the Chat Completions endpoint, you can use the system prompt to influence how the LLM responds to the final user query using the retrieved results. At this step, the model receives:

* The user's original query
* Retrieved document chunks (with metadata)
* The generation system prompt

The model uses these inputs to generate a context-aware response.

### Example

```

You are a helpful AI assistant specialized in answering questions using retrieved documents.

Your task is to provide accurate, relevant answers based on the matched content provided.

For each query, you will receive:

User's question/query

A set of matched documents, each containing:

  - File name

  - File content


You should:

1. Analyze the relevance of matched documents

2. Synthesize information from multiple sources when applicable

3. Acknowledge if the available documents don't fully answer the query

4. Format the response in a way that maximizes readability, in Markdown format


Answer only with direct reply to the user question, be concise, omit everything which is not directly relevant, focus on answering the question directly and do not redirect the user to read the content.


If the available documents don't contain enough information to fully answer the query, explicitly state this and provide an answer based on what is available.


Important:

- Cite which document(s) you're drawing information from

- Present information in order of relevance

- If documents contradict each other, note this and explain your reasoning for the chosen answer

- Do not repeat the instructions


```

## Query rewriting system prompt

If query rewriting is enabled, you can provide a custom system prompt to control how the model rewrites user queries. In this step, the model receives:

* The query rewrite system prompt
* The original user query

The model outputs a rewritten query optimized for semantic retrieval.

### Example

```

You are a search query optimizer for vector database searches. Your task is to reformulate user queries into more effective search terms.


Given a user's search query, you must:

1. Identify the core concepts and intent

2. Add relevant synonyms and related terms

3. Remove irrelevant filler words

4. Structure the query to emphasize key terms

5. Include technical or domain-specific terminology if applicable


Provide only the optimized search query without any explanations, greetings, or additional commentary.


Example input: "how to fix a bike tire that's gone flat"

Example output: "bicycle tire repair puncture fix patch inflate maintenance flat tire inner tube replacement"


Constraints:

- Output only the enhanced search terms

- Keep focus on searchable concepts

- Include both specific and general related terms

- Maintain all important meaning from original query


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/configuration/","name":"Configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/configuration/retrieval/","name":"Retrieval"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/configuration/retrieval/system-prompt/","name":"System prompt"}}]}
```

---

# AI Search

# Namespaces

## List namespaces.

**get** `/accounts/{account_id}/ai-search/namespaces`

List namespaces.

### Path Parameters

- `account_id: string`

### Query Parameters

- `page: optional number`

  Page number (1-indexed).

- `per_page: optional number`

  Number of results per page.

- `search: optional string`

  Filter namespaces whose name or description contains this string (case-insensitive).

### Returns

- `result: array of object { created_at, name, description }`

  - `created_at: string`

  - `name: string`

  - `description: optional string`

    Optional description for the namespace. Max 256 characters.

- `result_info: object { count, page, per_page, total_count }`

  - `count: number`

  - `page: number`

  - `per_page: number`

  - `total_count: number`

- `success: true`

  - `true`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": [
    {
      "created_at": "2019-12-27T18:11:19.117Z",
      "name": "production",
      "description": "Production environment"
    }
  ],
  "result_info": {
    "count": 0,
    "page": 0,
    "per_page": 0,
    "total_count": 0
  },
  "success": true
}
```

## Create namespace.

**post** `/accounts/{account_id}/ai-search/namespaces`

Create a new namespace.

### Path Parameters

- `account_id: string`

### Body Parameters

- `name: string`

- `description: optional string`

  Optional description for the namespace. Max 256 characters.

### Returns

- `result: object { created_at, name, description }`

  - `created_at: string`

  - `name: string`

  - `description: optional string`

    Optional description for the namespace. Max 256 characters.

- `success: true`

  - `true`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
    -d '{
          "name": "name",
          "description": "Production environment"
        }'
```

#### Response

```json
{
  "result": {
    "created_at": "2019-12-27T18:11:19.117Z",
    "name": "production",
    "description": "Production environment"
  },
  "success": true
}
```

## Read namespace.

**get** `/accounts/{account_id}/ai-search/namespaces/{name}`

Read namespace.

### Path Parameters

- `account_id: string`

- `name: string`

### Returns

- `result: object { created_at, name, description }`

  - `created_at: string`

  - `name: string`

  - `description: optional string`

    Optional description for the namespace. Max 256 characters.

- `success: true`

  - `true`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": {
    "created_at": "2019-12-27T18:11:19.117Z",
    "name": "production",
    "description": "Production environment"
  },
  "success": true
}
```

## Update namespace.

**put** `/accounts/{account_id}/ai-search/namespaces/{name}`

Update namespace.

### Path Parameters

- `account_id: string`

- `name: string`

### Body Parameters

- `description: optional string`

  Optional description for the namespace. Max 256 characters.

### Returns

- `result: object { created_at, name, description }`

  - `created_at: string`

  - `name: string`

  - `description: optional string`

    Optional description for the namespace. Max 256 characters.

- `success: true`

  - `true`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME \
    -X PUT \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": {
    "created_at": "2019-12-27T18:11:19.117Z",
    "name": "production",
    "description": "Production environment"
  },
  "success": true
}
```

## Delete namespace.

**delete** `/accounts/{account_id}/ai-search/namespaces/{name}`

Delete namespace.

### Path Parameters

- `account_id: string`

- `name: string`

### Returns

- `result: unknown`

- `success: true`

  - `true`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME \
    -X DELETE \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": {},
  "success": true
}
```

## Multi-Instance Search

**post** `/accounts/{account_id}/ai-search/namespaces/{name}/search`

Multi-Instance Search

### Path Parameters

- `account_id: string`

- `name: string`

### Body Parameters

- `ai_search_options: object { instance_ids, cache, query_rewrite, 2 more }`

  - `instance_ids: array of string`

  - `cache: optional object { cache_threshold, enabled }`

    - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

      - `"super_strict_match"`

      - `"close_enough"`

      - `"flexible_friend"`

      - `"anything_goes"`

    - `enabled: optional boolean`

  - `query_rewrite: optional object { enabled, model, rewrite_prompt }`

    - `enabled: optional boolean`

    - `model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

      - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

      - `"@cf/zai-org/glm-4.7-flash"`

      - `"@cf/meta/llama-3.1-8b-instruct-fast"`

      - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

      - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

      - `"@cf/qwen/qwen3-30b-a3b-fp8"`

      - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

      - `"@cf/moonshotai/kimi-k2-instruct"`

      - `"@cf/google/gemma-3-12b-it"`

      - `"@cf/google/gemma-4-26b-a4b-it"`

      - `"@cf/moonshotai/kimi-k2.5"`

      - `"anthropic/claude-3-7-sonnet"`

      - `"anthropic/claude-sonnet-4"`

      - `"anthropic/claude-opus-4"`

      - `"anthropic/claude-3-5-haiku"`

      - `"cerebras/qwen-3-235b-a22b-instruct"`

      - `"cerebras/qwen-3-235b-a22b-thinking"`

      - `"cerebras/llama-3.3-70b"`

      - `"cerebras/llama-4-maverick-17b-128e-instruct"`

      - `"cerebras/llama-4-scout-17b-16e-instruct"`

      - `"cerebras/gpt-oss-120b"`

      - `"google-ai-studio/gemini-2.5-flash"`

      - `"google-ai-studio/gemini-2.5-pro"`

      - `"grok/grok-4"`

      - `"groq/llama-3.3-70b-versatile"`

      - `"groq/llama-3.1-8b-instant"`

      - `"openai/gpt-5"`

      - `"openai/gpt-5-mini"`

      - `"openai/gpt-5-nano"`

      - `""`

    - `rewrite_prompt: optional string`

  - `reranking: optional object { enabled, match_threshold, model }`

    - `enabled: optional boolean`

    - `match_threshold: optional number`

    - `model: optional "@cf/baai/bge-reranker-base" or ""`

      - `"@cf/baai/bge-reranker-base"`

      - `""`

  - `retrieval: optional object { boost_by, context_expansion, filters, 6 more }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Overrides the instance-level boost_by config. Direction defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `context_expansion: optional number`

    - `filters: optional map[unknown]`

    - `fusion_method: optional "max" or "rrf"`

      - `"max"`

      - `"rrf"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

    - `match_threshold: optional number`

    - `max_num_results: optional number`

    - `retrieval_type: optional "vector" or "keyword" or "hybrid"`

      - `"vector"`

      - `"keyword"`

      - `"hybrid"`

    - `return_on_failure: optional boolean`

- `messages: optional array of object { content, role }`

  - `content: string`

  - `role: "system" or "developer" or "user" or 2 more`

    - `"system"`

    - `"developer"`

    - `"user"`

    - `"assistant"`

    - `"tool"`

- `query: optional string`

  A simple text query string. Alternative to 'messages' — provide either this or 'messages', not both.

### Returns

- `result: object { chunks, search_query, errors }`

  - `chunks: array of object { id, instance_id, score, 4 more }`

    - `id: string`

    - `instance_id: string`

    - `score: number`

    - `text: string`

    - `type: string`

    - `item: optional object { key, metadata, timestamp }`

      - `key: string`

      - `metadata: optional map[unknown]`

      - `timestamp: optional number`

    - `scoring_details: optional object { fusion_method, keyword_rank, keyword_score, 3 more }`

      - `fusion_method: optional "rrf" or "max"`

        - `"rrf"`

        - `"max"`

      - `keyword_rank: optional number`

      - `keyword_score: optional number`

      - `reranking_score: optional number`

      - `vector_rank: optional number`

      - `vector_score: optional number`

  - `search_query: string`

  - `errors: optional array of object { instance_id, message }`

    - `instance_id: string`

    - `message: string`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME/search \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
    -d '{
          "ai_search_options": {
            "instance_ids": [
              "my-ai-search"
            ]
          }
        }'
```

#### Response

```json
{
  "result": {
    "chunks": [
      {
        "id": "id",
        "instance_id": "instance_id",
        "score": 0,
        "text": "text",
        "type": "type",
        "item": {
          "key": "key",
          "metadata": {
            "foo": "bar"
          },
          "timestamp": 0
        },
        "scoring_details": {
          "fusion_method": "rrf",
          "keyword_rank": 0,
          "keyword_score": 0,
          "reranking_score": 0,
          "vector_rank": 0,
          "vector_score": 0
        }
      }
    ],
    "search_query": "search_query",
    "errors": [
      {
        "instance_id": "instance_id",
        "message": "message"
      }
    ]
  },
  "success": true
}
```

## Multi-Instance Chat Completions

**post** `/accounts/{account_id}/ai-search/namespaces/{name}/chat/completions`

Performs a chat completion request against multiple AI Search instances in parallel, merging retrieved content as context for generating a response.

### Path Parameters

- `account_id: string`

- `name: string`

### Body Parameters

- `ai_search_options: object { instance_ids, cache, query_rewrite, 2 more }`

  - `instance_ids: array of string`

  - `cache: optional object { cache_threshold, enabled }`

    - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

      - `"super_strict_match"`

      - `"close_enough"`

      - `"flexible_friend"`

      - `"anything_goes"`

    - `enabled: optional boolean`

  - `query_rewrite: optional object { enabled, model, rewrite_prompt }`

    - `enabled: optional boolean`

    - `model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

      - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

      - `"@cf/zai-org/glm-4.7-flash"`

      - `"@cf/meta/llama-3.1-8b-instruct-fast"`

      - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

      - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

      - `"@cf/qwen/qwen3-30b-a3b-fp8"`

      - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

      - `"@cf/moonshotai/kimi-k2-instruct"`

      - `"@cf/google/gemma-3-12b-it"`

      - `"@cf/google/gemma-4-26b-a4b-it"`

      - `"@cf/moonshotai/kimi-k2.5"`

      - `"anthropic/claude-3-7-sonnet"`

      - `"anthropic/claude-sonnet-4"`

      - `"anthropic/claude-opus-4"`

      - `"anthropic/claude-3-5-haiku"`

      - `"cerebras/qwen-3-235b-a22b-instruct"`

      - `"cerebras/qwen-3-235b-a22b-thinking"`

      - `"cerebras/llama-3.3-70b"`

      - `"cerebras/llama-4-maverick-17b-128e-instruct"`

      - `"cerebras/llama-4-scout-17b-16e-instruct"`

      - `"cerebras/gpt-oss-120b"`

      - `"google-ai-studio/gemini-2.5-flash"`

      - `"google-ai-studio/gemini-2.5-pro"`

      - `"grok/grok-4"`

      - `"groq/llama-3.3-70b-versatile"`

      - `"groq/llama-3.1-8b-instant"`

      - `"openai/gpt-5"`

      - `"openai/gpt-5-mini"`

      - `"openai/gpt-5-nano"`

      - `""`

    - `rewrite_prompt: optional string`

  - `reranking: optional object { enabled, match_threshold, model }`

    - `enabled: optional boolean`

    - `match_threshold: optional number`

    - `model: optional "@cf/baai/bge-reranker-base" or ""`

      - `"@cf/baai/bge-reranker-base"`

      - `""`

  - `retrieval: optional object { boost_by, context_expansion, filters, 6 more }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Overrides the instance-level boost_by config. Direction defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `context_expansion: optional number`

    - `filters: optional map[unknown]`

    - `fusion_method: optional "max" or "rrf"`

      - `"max"`

      - `"rrf"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

    - `match_threshold: optional number`

    - `max_num_results: optional number`

    - `retrieval_type: optional "vector" or "keyword" or "hybrid"`

      - `"vector"`

      - `"keyword"`

      - `"hybrid"`

    - `return_on_failure: optional boolean`

- `messages: array of object { content, role }`

  - `content: string`

  - `role: "system" or "developer" or "user" or 2 more`

    - `"system"`

    - `"developer"`

    - `"user"`

    - `"assistant"`

    - `"tool"`

- `model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

  - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

  - `"@cf/zai-org/glm-4.7-flash"`

  - `"@cf/meta/llama-3.1-8b-instruct-fast"`

  - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

  - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

  - `"@cf/qwen/qwen3-30b-a3b-fp8"`

  - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

  - `"@cf/moonshotai/kimi-k2-instruct"`

  - `"@cf/google/gemma-3-12b-it"`

  - `"@cf/google/gemma-4-26b-a4b-it"`

  - `"@cf/moonshotai/kimi-k2.5"`

  - `"anthropic/claude-3-7-sonnet"`

  - `"anthropic/claude-sonnet-4"`

  - `"anthropic/claude-opus-4"`

  - `"anthropic/claude-3-5-haiku"`

  - `"cerebras/qwen-3-235b-a22b-instruct"`

  - `"cerebras/qwen-3-235b-a22b-thinking"`

  - `"cerebras/llama-3.3-70b"`

  - `"cerebras/llama-4-maverick-17b-128e-instruct"`

  - `"cerebras/llama-4-scout-17b-16e-instruct"`

  - `"cerebras/gpt-oss-120b"`

  - `"google-ai-studio/gemini-2.5-flash"`

  - `"google-ai-studio/gemini-2.5-pro"`

  - `"grok/grok-4"`

  - `"groq/llama-3.3-70b-versatile"`

  - `"groq/llama-3.1-8b-instant"`

  - `"openai/gpt-5"`

  - `"openai/gpt-5-mini"`

  - `"openai/gpt-5-nano"`

  - `""`

- `stream: optional boolean`

### Returns

- `choices: array of object { message, index }`

  - `message: object { content, role }`

    - `content: string`

    - `role: "system" or "developer" or "user" or 2 more`

      - `"system"`

      - `"developer"`

      - `"user"`

      - `"assistant"`

      - `"tool"`

  - `index: optional number`

- `chunks: array of object { id, instance_id, score, 4 more }`

  - `id: string`

  - `instance_id: string`

  - `score: number`

  - `text: string`

  - `type: string`

  - `item: optional object { key, metadata, timestamp }`

    - `key: string`

    - `metadata: optional map[unknown]`

    - `timestamp: optional number`

  - `scoring_details: optional object { fusion_method, keyword_rank, keyword_score, 3 more }`

    - `fusion_method: optional "rrf" or "max"`

      - `"rrf"`

      - `"max"`

    - `keyword_rank: optional number`

    - `keyword_score: optional number`

    - `reranking_score: optional number`

    - `vector_rank: optional number`

    - `vector_score: optional number`

- `id: optional string`

- `errors: optional array of object { instance_id, message }`

  - `instance_id: string`

  - `message: string`

- `model: optional string`

- `object: optional string`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME/chat/completions \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
    -d '{
          "ai_search_options": {
            "instance_ids": [
              "my-ai-search"
            ]
          },
          "messages": [
            {
              "content": "content",
              "role": "system"
            }
          ]
        }'
```

#### Response

```json
{
  "choices": [
    {
      "message": {
        "content": "content",
        "role": "system"
      },
      "index": 0
    }
  ],
  "chunks": [
    {
      "id": "id",
      "instance_id": "instance_id",
      "score": 0,
      "text": "text",
      "type": "type",
      "item": {
        "key": "key",
        "metadata": {
          "foo": "bar"
        },
        "timestamp": 0
      },
      "scoring_details": {
        "fusion_method": "rrf",
        "keyword_rank": 0,
        "keyword_score": 0,
        "reranking_score": 0,
        "vector_rank": 0,
        "vector_score": 0
      }
    }
  ],
  "id": "id",
  "errors": [
    {
      "instance_id": "instance_id",
      "message": "message"
    }
  ],
  "model": "model",
  "object": "object"
}
```

## Domain Types

### Namespace List Response

- `NamespaceListResponse object { created_at, name, description }`

  - `created_at: string`

  - `name: string`

  - `description: optional string`

    Optional description for the namespace. Max 256 characters.

### Namespace Create Response

- `NamespaceCreateResponse object { created_at, name, description }`

  - `created_at: string`

  - `name: string`

  - `description: optional string`

    Optional description for the namespace. Max 256 characters.

### Namespace Read Response

- `NamespaceReadResponse object { created_at, name, description }`

  - `created_at: string`

  - `name: string`

  - `description: optional string`

    Optional description for the namespace. Max 256 characters.

### Namespace Update Response

- `NamespaceUpdateResponse object { created_at, name, description }`

  - `created_at: string`

  - `name: string`

  - `description: optional string`

    Optional description for the namespace. Max 256 characters.

### Namespace Delete Response

- `NamespaceDeleteResponse = unknown`

### Namespace Search Response

- `NamespaceSearchResponse object { chunks, search_query, errors }`

  - `chunks: array of object { id, instance_id, score, 4 more }`

    - `id: string`

    - `instance_id: string`

    - `score: number`

    - `text: string`

    - `type: string`

    - `item: optional object { key, metadata, timestamp }`

      - `key: string`

      - `metadata: optional map[unknown]`

      - `timestamp: optional number`

    - `scoring_details: optional object { fusion_method, keyword_rank, keyword_score, 3 more }`

      - `fusion_method: optional "rrf" or "max"`

        - `"rrf"`

        - `"max"`

      - `keyword_rank: optional number`

      - `keyword_score: optional number`

      - `reranking_score: optional number`

      - `vector_rank: optional number`

      - `vector_score: optional number`

  - `search_query: string`

  - `errors: optional array of object { instance_id, message }`

    - `instance_id: string`

    - `message: string`

### Namespace Chat Completions Response

- `NamespaceChatCompletionsResponse object { choices, chunks, id, 3 more }`

  - `choices: array of object { message, index }`

    - `message: object { content, role }`

      - `content: string`

      - `role: "system" or "developer" or "user" or 2 more`

        - `"system"`

        - `"developer"`

        - `"user"`

        - `"assistant"`

        - `"tool"`

    - `index: optional number`

  - `chunks: array of object { id, instance_id, score, 4 more }`

    - `id: string`

    - `instance_id: string`

    - `score: number`

    - `text: string`

    - `type: string`

    - `item: optional object { key, metadata, timestamp }`

      - `key: string`

      - `metadata: optional map[unknown]`

      - `timestamp: optional number`

    - `scoring_details: optional object { fusion_method, keyword_rank, keyword_score, 3 more }`

      - `fusion_method: optional "rrf" or "max"`

        - `"rrf"`

        - `"max"`

      - `keyword_rank: optional number`

      - `keyword_score: optional number`

      - `reranking_score: optional number`

      - `vector_rank: optional number`

      - `vector_score: optional number`

  - `id: optional string`

  - `errors: optional array of object { instance_id, message }`

    - `instance_id: string`

    - `message: string`

  - `model: optional string`

  - `object: optional string`

# Instances

## List instances.

**get** `/accounts/{account_id}/ai-search/namespaces/{name}/instances`

List instances.

### Path Parameters

- `account_id: string`

- `name: string`

### Query Parameters

- `namespace: optional string`

  Filter by namespace.

- `order_by: optional "created_at"`

  Field to order results by.

  - `"created_at"`

- `order_by_direction: optional "asc" or "desc"`

  Order direction.

  - `"asc"`

  - `"desc"`

- `page: optional number`

  Page number (1-indexed).

- `per_page: optional number`

  Number of results per page.

- `search: optional string`

  Filter instances whose id contains this string (case-insensitive).

### Returns

- `result: array of object { id, created_at, modified_at, 36 more }`

  - `id: string`

    AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

  - `created_at: string`

  - `modified_at: string`

  - `ai_gateway_id: optional string`

  - `ai_search_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `cache: optional boolean`

  - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

    - `"super_strict_match"`

    - `"close_enough"`

    - `"flexible_friend"`

    - `"anything_goes"`

  - `cache_ttl: optional 600 or 1800 or 3600 or 7 more`

    Cache entry TTL in seconds. Allowed values: 600 (10min), 1800 (30min), 3600 (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d).

    - `600`

    - `1800`

    - `3600`

    - `7200`

    - `21600`

    - `43200`

    - `86400`

    - `172800`

    - `259200`

    - `518400`

  - `chunk_overlap: optional number`

  - `chunk_size: optional number`

  - `created_by: optional string`

  - `custom_metadata: optional array of object { data_type, field_name }`

    - `data_type: "text" or "number" or "boolean" or "datetime"`

      - `"text"`

      - `"number"`

      - `"boolean"`

      - `"datetime"`

    - `field_name: string`

  - `embedding_model: optional "@cf/qwen/qwen3-embedding-0.6b" or "@cf/baai/bge-m3" or "@cf/baai/bge-large-en-v1.5" or 6 more`

    - `"@cf/qwen/qwen3-embedding-0.6b"`

    - `"@cf/baai/bge-m3"`

    - `"@cf/baai/bge-large-en-v1.5"`

    - `"@cf/google/embeddinggemma-300m"`

    - `"google-ai-studio/gemini-embedding-001"`

    - `"google-ai-studio/gemini-embedding-2-preview"`

    - `"openai/text-embedding-3-small"`

    - `"openai/text-embedding-3-large"`

    - `""`

  - `enable: optional boolean`

  - `engine_version: optional number`

  - `fusion_method: optional "max" or "rrf"`

    - `"max"`

    - `"rrf"`

  - `hybrid_search_enabled: optional boolean`

    Deprecated — use index_method instead.

  - `index_method: optional object { keyword, vector }`

    Controls which storage backends are used during indexing. Defaults to vector-only.

    - `keyword: boolean`

      Enable keyword (BM25) storage backend.

    - `vector: boolean`

      Enable vector (embedding) storage backend.

  - `indexing_options: optional object { keyword_tokenizer }`

    - `keyword_tokenizer: optional "porter" or "trigram"`

      Tokenizer used for keyword search indexing. porter provides word-level tokenization with Porter stemming (good for natural language queries). trigram enables character-level substring matching (good for partial matches, code, identifiers). Changing this triggers a full re-index. Defaults to porter.

      - `"porter"`

      - `"trigram"`

  - `last_activity: optional string`

  - `max_num_results: optional number`

  - `metadata: optional object { created_from_aisearch_wizard, worker_domain }`

    - `created_from_aisearch_wizard: optional boolean`

    - `worker_domain: optional string`

  - `modified_by: optional string`

  - `namespace: optional string`

  - `paused: optional boolean`

  - `public_endpoint_id: optional string`

  - `public_endpoint_params: optional object { authorized_hosts, chat_completions_endpoint, enabled, 3 more }`

    - `authorized_hosts: optional array of string`

    - `chat_completions_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable chat completions endpoint for this public endpoint

    - `enabled: optional boolean`

    - `mcp: optional object { description, disabled }`

      - `description: optional string`

      - `disabled: optional boolean`

        Disable MCP endpoint for this public endpoint

    - `rate_limit: optional object { period_ms, requests, technique }`

      - `period_ms: optional number`

      - `requests: optional number`

      - `technique: optional "fixed" or "sliding"`

        - `"fixed"`

        - `"sliding"`

    - `search_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable search endpoint for this public endpoint

  - `reranking: optional boolean`

  - `reranking_model: optional "@cf/baai/bge-reranker-base" or ""`

    - `"@cf/baai/bge-reranker-base"`

    - `""`

  - `retrieval_options: optional object { boost_by, keyword_match_mode }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Each entry specifies a metadata field and an optional direction. Direction defaults to 'asc' for numeric/datetime fields and 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

  - `rewrite_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `rewrite_query: optional boolean`

  - `score_threshold: optional number`

  - `source: optional string`

  - `source_params: optional object { exclude_items, include_items, prefix, 2 more }`

    - `exclude_items: optional array of string`

      List of path patterns to exclude. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and /admin/settings/advanced)

    - `include_items: optional array of string`

      List of path patterns to include. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post)

    - `prefix: optional string`

    - `r2_jurisdiction: optional string`

    - `web_crawler: optional object { crawl_options, parse_options, parse_type, store_options }`

      - `crawl_options: optional object { depth, include_external_links, include_subdomains, 2 more }`

        - `depth: optional number`

        - `include_external_links: optional boolean`

        - `include_subdomains: optional boolean`

        - `max_age: optional number`

        - `source: optional "all" or "sitemaps" or "links"`

          - `"all"`

          - `"sitemaps"`

          - `"links"`

      - `parse_options: optional object { content_selector, include_headers, include_images, 2 more }`

        - `content_selector: optional array of object { path, selector }`

          List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first matching path wins. Only the matched HTML fragment is stored and indexed. Omit the field to disable content selection — empty arrays are rejected.

          - `path: string`

            Glob pattern to match against the page URL path. Uses standard glob syntax: * matches within a segment, ** crosses directories.

          - `selector: string`

            CSS selector to extract content from pages matching the path pattern. Must not contain disallowed characters (;, `, $, {, }, ). Must target a single element; if multiple elements match, the selector is ignored and the full page is used.

        - `include_headers: optional map[string]`

          Up to 5 custom HTTP headers sent with each crawl request. Names must be RFC-7230 token characters (no spaces, colons, or control characters); values must be HTAB + printable ASCII (no CR/LF).

        - `include_images: optional boolean`

        - `specific_sitemaps: optional array of string`

          List of specific sitemap URLs to use for crawling. Only valid when parse_type is 'sitemap'.

        - `use_browser_rendering: optional boolean`

      - `parse_type: optional "sitemap" or "feed-rss" or "crawl"`

        - `"sitemap"`

        - `"feed-rss"`

        - `"crawl"`

      - `store_options: optional object { storage_id, r2_jurisdiction, storage_type }`

        - `storage_id: string`

        - `r2_jurisdiction: optional string`

        - `storage_type: optional Provider`

          - `"r2"`

  - `status: optional string`

  - `sync_interval: optional 900 or 1800 or 3600 or 5 more`

    Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h).

    - `900`

    - `1800`

    - `3600`

    - `7200`

    - `14400`

    - `21600`

    - `43200`

    - `86400`

  - `token_id: optional string`

  - `type: optional "r2" or "web-crawler"`

    - `"r2"`

    - `"web-crawler"`

- `result_info: object { count, page, per_page, total_count }`

  - `count: number`

  - `page: number`

  - `per_page: number`

  - `total_count: number`

- `success: true`

  - `true`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME/instances \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": [
    {
      "id": "my-ai-search",
      "created_at": "2019-12-27T18:11:19.117Z",
      "modified_at": "2019-12-27T18:11:19.117Z",
      "ai_gateway_id": "ai_gateway_id",
      "ai_search_model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
      "cache": true,
      "cache_threshold": "super_strict_match",
      "cache_ttl": 600,
      "chunk_overlap": 0,
      "chunk_size": 64,
      "created_by": "created_by",
      "custom_metadata": [
        {
          "data_type": "text",
          "field_name": "x"
        }
      ],
      "embedding_model": "@cf/qwen/qwen3-embedding-0.6b",
      "enable": true,
      "engine_version": 0,
      "fusion_method": "max",
      "hybrid_search_enabled": true,
      "index_method": {
        "keyword": true,
        "vector": true
      },
      "indexing_options": {
        "keyword_tokenizer": "porter"
      },
      "last_activity": "2019-12-27T18:11:19.117Z",
      "max_num_results": 1,
      "metadata": {
        "created_from_aisearch_wizard": true,
        "worker_domain": "worker_domain"
      },
      "modified_by": "modified_by",
      "namespace": "namespace",
      "paused": true,
      "public_endpoint_id": "public_endpoint_id",
      "public_endpoint_params": {
        "authorized_hosts": [
          "string"
        ],
        "chat_completions_endpoint": {
          "disabled": true
        },
        "enabled": true,
        "mcp": {
          "description": "description",
          "disabled": true
        },
        "rate_limit": {
          "period_ms": 60000,
          "requests": 1,
          "technique": "fixed"
        },
        "search_endpoint": {
          "disabled": true
        }
      },
      "reranking": true,
      "reranking_model": "@cf/baai/bge-reranker-base",
      "retrieval_options": {
        "boost_by": [
          {
            "field": "timestamp",
            "direction": "desc"
          }
        ],
        "keyword_match_mode": "and"
      },
      "rewrite_model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
      "rewrite_query": true,
      "score_threshold": 0,
      "source": "source",
      "source_params": {
        "exclude_items": [
          "/admin/**",
          "/private/**",
          "**\\temp\\**"
        ],
        "include_items": [
          "/blog/**",
          "/docs/**/*.html",
          "**\\blog\\**.html"
        ],
        "prefix": "prefix",
        "r2_jurisdiction": "r2_jurisdiction",
        "web_crawler": {
          "crawl_options": {
            "depth": 1,
            "include_external_links": true,
            "include_subdomains": true,
            "max_age": 0,
            "source": "all"
          },
          "parse_options": {
            "content_selector": [
              {
                "path": "**/blog/**",
                "selector": "article div.post-body"
              },
              {
                "path": "**/docs/**",
                "selector": "main"
              }
            ],
            "include_headers": {
              "cache-control": "no-cache, no-store"
            },
            "include_images": true,
            "specific_sitemaps": [
              "https://example.com/sitemap.xml",
              "https://example.com/blog-sitemap.xml"
            ],
            "use_browser_rendering": true
          },
          "parse_type": "sitemap",
          "store_options": {
            "storage_id": "storage_id",
            "r2_jurisdiction": "r2_jurisdiction",
            "storage_type": "r2"
          }
        }
      },
      "status": "status",
      "sync_interval": 900,
      "token_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
      "type": "r2"
    }
  ],
  "result_info": {
    "count": 0,
    "page": 0,
    "per_page": 0,
    "total_count": 0
  },
  "success": true
}
```

## Create new instance.

**post** `/accounts/{account_id}/ai-search/namespaces/{name}/instances`

Create a new instance.

### Path Parameters

- `account_id: string`

- `name: string`

### Body Parameters

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

- `ai_gateway_id: optional string`

- `ai_search_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

  - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

  - `"@cf/zai-org/glm-4.7-flash"`

  - `"@cf/meta/llama-3.1-8b-instruct-fast"`

  - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

  - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

  - `"@cf/qwen/qwen3-30b-a3b-fp8"`

  - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

  - `"@cf/moonshotai/kimi-k2-instruct"`

  - `"@cf/google/gemma-3-12b-it"`

  - `"@cf/google/gemma-4-26b-a4b-it"`

  - `"@cf/moonshotai/kimi-k2.5"`

  - `"anthropic/claude-3-7-sonnet"`

  - `"anthropic/claude-sonnet-4"`

  - `"anthropic/claude-opus-4"`

  - `"anthropic/claude-3-5-haiku"`

  - `"cerebras/qwen-3-235b-a22b-instruct"`

  - `"cerebras/qwen-3-235b-a22b-thinking"`

  - `"cerebras/llama-3.3-70b"`

  - `"cerebras/llama-4-maverick-17b-128e-instruct"`

  - `"cerebras/llama-4-scout-17b-16e-instruct"`

  - `"cerebras/gpt-oss-120b"`

  - `"google-ai-studio/gemini-2.5-flash"`

  - `"google-ai-studio/gemini-2.5-pro"`

  - `"grok/grok-4"`

  - `"groq/llama-3.3-70b-versatile"`

  - `"groq/llama-3.1-8b-instant"`

  - `"openai/gpt-5"`

  - `"openai/gpt-5-mini"`

  - `"openai/gpt-5-nano"`

  - `""`

- `cache: optional boolean`

- `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

  - `"super_strict_match"`

  - `"close_enough"`

  - `"flexible_friend"`

  - `"anything_goes"`

- `cache_ttl: optional 600 or 1800 or 3600 or 7 more`

  Cache entry TTL in seconds. Allowed values: 600 (10min), 1800 (30min), 3600 (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d).

  - `600`

  - `1800`

  - `3600`

  - `7200`

  - `21600`

  - `43200`

  - `86400`

  - `172800`

  - `259200`

  - `518400`

- `chunk: optional boolean`

- `chunk_overlap: optional number`

- `chunk_size: optional number`

- `custom_metadata: optional array of object { data_type, field_name }`

  - `data_type: "text" or "number" or "boolean" or "datetime"`

    - `"text"`

    - `"number"`

    - `"boolean"`

    - `"datetime"`

  - `field_name: string`

- `embedding_model: optional "@cf/qwen/qwen3-embedding-0.6b" or "@cf/baai/bge-m3" or "@cf/baai/bge-large-en-v1.5" or 6 more`

  - `"@cf/qwen/qwen3-embedding-0.6b"`

  - `"@cf/baai/bge-m3"`

  - `"@cf/baai/bge-large-en-v1.5"`

  - `"@cf/google/embeddinggemma-300m"`

  - `"google-ai-studio/gemini-embedding-001"`

  - `"google-ai-studio/gemini-embedding-2-preview"`

  - `"openai/text-embedding-3-small"`

  - `"openai/text-embedding-3-large"`

  - `""`

- `fusion_method: optional "max" or "rrf"`

  - `"max"`

  - `"rrf"`

- `hybrid_search_enabled: optional boolean`

  Deprecated — use index_method instead.

- `index_method: optional object { keyword, vector }`

  Controls which storage backends are used during indexing. Defaults to vector-only.

  - `keyword: boolean`

    Enable keyword (BM25) storage backend.

  - `vector: boolean`

    Enable vector (embedding) storage backend.

- `indexing_options: optional object { keyword_tokenizer }`

  - `keyword_tokenizer: optional "porter" or "trigram"`

    Tokenizer used for keyword search indexing. porter provides word-level tokenization with Porter stemming (good for natural language queries). trigram enables character-level substring matching (good for partial matches, code, identifiers). Changing this triggers a full re-index. Defaults to porter.

    - `"porter"`

    - `"trigram"`

- `max_num_results: optional number`

- `metadata: optional object { created_from_aisearch_wizard, worker_domain }`

  - `created_from_aisearch_wizard: optional boolean`

  - `worker_domain: optional string`

- `public_endpoint_params: optional object { authorized_hosts, chat_completions_endpoint, enabled, 3 more }`

  - `authorized_hosts: optional array of string`

  - `chat_completions_endpoint: optional object { disabled }`

    - `disabled: optional boolean`

      Disable chat completions endpoint for this public endpoint

  - `enabled: optional boolean`

  - `mcp: optional object { description, disabled }`

    - `description: optional string`

    - `disabled: optional boolean`

      Disable MCP endpoint for this public endpoint

  - `rate_limit: optional object { period_ms, requests, technique }`

    - `period_ms: optional number`

    - `requests: optional number`

    - `technique: optional "fixed" or "sliding"`

      - `"fixed"`

      - `"sliding"`

  - `search_endpoint: optional object { disabled }`

    - `disabled: optional boolean`

      Disable search endpoint for this public endpoint

- `reranking: optional boolean`

- `reranking_model: optional "@cf/baai/bge-reranker-base" or ""`

  - `"@cf/baai/bge-reranker-base"`

  - `""`

- `retrieval_options: optional object { boost_by, keyword_match_mode }`

  - `boost_by: optional array of object { field, direction }`

    Metadata fields to boost search results by. Each entry specifies a metadata field and an optional direction. Direction defaults to 'asc' for numeric/datetime fields and 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

    - `field: string`

      Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

    - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

      Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

      - `"asc"`

      - `"desc"`

      - `"exists"`

      - `"not_exists"`

  - `keyword_match_mode: optional "and" or "or"`

    Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

    - `"and"`

    - `"or"`

- `rewrite_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

  - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

  - `"@cf/zai-org/glm-4.7-flash"`

  - `"@cf/meta/llama-3.1-8b-instruct-fast"`

  - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

  - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

  - `"@cf/qwen/qwen3-30b-a3b-fp8"`

  - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

  - `"@cf/moonshotai/kimi-k2-instruct"`

  - `"@cf/google/gemma-3-12b-it"`

  - `"@cf/google/gemma-4-26b-a4b-it"`

  - `"@cf/moonshotai/kimi-k2.5"`

  - `"anthropic/claude-3-7-sonnet"`

  - `"anthropic/claude-sonnet-4"`

  - `"anthropic/claude-opus-4"`

  - `"anthropic/claude-3-5-haiku"`

  - `"cerebras/qwen-3-235b-a22b-instruct"`

  - `"cerebras/qwen-3-235b-a22b-thinking"`

  - `"cerebras/llama-3.3-70b"`

  - `"cerebras/llama-4-maverick-17b-128e-instruct"`

  - `"cerebras/llama-4-scout-17b-16e-instruct"`

  - `"cerebras/gpt-oss-120b"`

  - `"google-ai-studio/gemini-2.5-flash"`

  - `"google-ai-studio/gemini-2.5-pro"`

  - `"grok/grok-4"`

  - `"groq/llama-3.3-70b-versatile"`

  - `"groq/llama-3.1-8b-instant"`

  - `"openai/gpt-5"`

  - `"openai/gpt-5-mini"`

  - `"openai/gpt-5-nano"`

  - `""`

- `rewrite_query: optional boolean`

- `score_threshold: optional number`

- `source: optional string`

- `source_params: optional object { exclude_items, include_items, prefix, 2 more }`

  - `exclude_items: optional array of string`

    List of path patterns to exclude. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and /admin/settings/advanced)

  - `include_items: optional array of string`

    List of path patterns to include. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post)

  - `prefix: optional string`

  - `r2_jurisdiction: optional string`

  - `web_crawler: optional object { crawl_options, parse_options, parse_type, store_options }`

    - `crawl_options: optional object { depth, include_external_links, include_subdomains, 2 more }`

      - `depth: optional number`

      - `include_external_links: optional boolean`

      - `include_subdomains: optional boolean`

      - `max_age: optional number`

      - `source: optional "all" or "sitemaps" or "links"`

        - `"all"`

        - `"sitemaps"`

        - `"links"`

    - `parse_options: optional object { content_selector, include_headers, include_images, 2 more }`

      - `content_selector: optional array of object { path, selector }`

        List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first matching path wins. Only the matched HTML fragment is stored and indexed. Omit the field to disable content selection — empty arrays are rejected.

        - `path: string`

          Glob pattern to match against the page URL path. Uses standard glob syntax: * matches within a segment, ** crosses directories.

        - `selector: string`

          CSS selector to extract content from pages matching the path pattern. Must not contain disallowed characters (;, `, $, {, }, ). Must target a single element; if multiple elements match, the selector is ignored and the full page is used.

      - `include_headers: optional map[string]`

        Up to 5 custom HTTP headers sent with each crawl request. Names must be RFC-7230 token characters (no spaces, colons, or control characters); values must be HTAB + printable ASCII (no CR/LF).

      - `include_images: optional boolean`

      - `specific_sitemaps: optional array of string`

        List of specific sitemap URLs to use for crawling. Only valid when parse_type is 'sitemap'.

      - `use_browser_rendering: optional boolean`

    - `parse_type: optional "sitemap" or "feed-rss" or "crawl"`

      - `"sitemap"`

      - `"feed-rss"`

      - `"crawl"`

    - `store_options: optional object { storage_id, r2_jurisdiction, storage_type }`

      - `storage_id: string`

      - `r2_jurisdiction: optional string`

      - `storage_type: optional Provider`

        - `"r2"`

- `sync_interval: optional 900 or 1800 or 3600 or 5 more`

  Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h).

  - `900`

  - `1800`

  - `3600`

  - `7200`

  - `14400`

  - `21600`

  - `43200`

  - `86400`

- `token_id: optional string`

- `type: optional "r2" or "web-crawler"`

  - `"r2"`

  - `"web-crawler"`

### Returns

- `result: object { id, created_at, modified_at, 36 more }`

  - `id: string`

    AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

  - `created_at: string`

  - `modified_at: string`

  - `ai_gateway_id: optional string`

  - `ai_search_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `cache: optional boolean`

  - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

    - `"super_strict_match"`

    - `"close_enough"`

    - `"flexible_friend"`

    - `"anything_goes"`

  - `cache_ttl: optional 600 or 1800 or 3600 or 7 more`

    Cache entry TTL in seconds. Allowed values: 600 (10min), 1800 (30min), 3600 (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d).

    - `600`

    - `1800`

    - `3600`

    - `7200`

    - `21600`

    - `43200`

    - `86400`

    - `172800`

    - `259200`

    - `518400`

  - `chunk_overlap: optional number`

  - `chunk_size: optional number`

  - `created_by: optional string`

  - `custom_metadata: optional array of object { data_type, field_name }`

    - `data_type: "text" or "number" or "boolean" or "datetime"`

      - `"text"`

      - `"number"`

      - `"boolean"`

      - `"datetime"`

    - `field_name: string`

  - `embedding_model: optional "@cf/qwen/qwen3-embedding-0.6b" or "@cf/baai/bge-m3" or "@cf/baai/bge-large-en-v1.5" or 6 more`

    - `"@cf/qwen/qwen3-embedding-0.6b"`

    - `"@cf/baai/bge-m3"`

    - `"@cf/baai/bge-large-en-v1.5"`

    - `"@cf/google/embeddinggemma-300m"`

    - `"google-ai-studio/gemini-embedding-001"`

    - `"google-ai-studio/gemini-embedding-2-preview"`

    - `"openai/text-embedding-3-small"`

    - `"openai/text-embedding-3-large"`

    - `""`

  - `enable: optional boolean`

  - `engine_version: optional number`

  - `fusion_method: optional "max" or "rrf"`

    - `"max"`

    - `"rrf"`

  - `hybrid_search_enabled: optional boolean`

    Deprecated — use index_method instead.

  - `index_method: optional object { keyword, vector }`

    Controls which storage backends are used during indexing. Defaults to vector-only.

    - `keyword: boolean`

      Enable keyword (BM25) storage backend.

    - `vector: boolean`

      Enable vector (embedding) storage backend.

  - `indexing_options: optional object { keyword_tokenizer }`

    - `keyword_tokenizer: optional "porter" or "trigram"`

      Tokenizer used for keyword search indexing. porter provides word-level tokenization with Porter stemming (good for natural language queries). trigram enables character-level substring matching (good for partial matches, code, identifiers). Changing this triggers a full re-index. Defaults to porter.

      - `"porter"`

      - `"trigram"`

  - `last_activity: optional string`

  - `max_num_results: optional number`

  - `metadata: optional object { created_from_aisearch_wizard, worker_domain }`

    - `created_from_aisearch_wizard: optional boolean`

    - `worker_domain: optional string`

  - `modified_by: optional string`

  - `namespace: optional string`

  - `paused: optional boolean`

  - `public_endpoint_id: optional string`

  - `public_endpoint_params: optional object { authorized_hosts, chat_completions_endpoint, enabled, 3 more }`

    - `authorized_hosts: optional array of string`

    - `chat_completions_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable chat completions endpoint for this public endpoint

    - `enabled: optional boolean`

    - `mcp: optional object { description, disabled }`

      - `description: optional string`

      - `disabled: optional boolean`

        Disable MCP endpoint for this public endpoint

    - `rate_limit: optional object { period_ms, requests, technique }`

      - `period_ms: optional number`

      - `requests: optional number`

      - `technique: optional "fixed" or "sliding"`

        - `"fixed"`

        - `"sliding"`

    - `search_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable search endpoint for this public endpoint

  - `reranking: optional boolean`

  - `reranking_model: optional "@cf/baai/bge-reranker-base" or ""`

    - `"@cf/baai/bge-reranker-base"`

    - `""`

  - `retrieval_options: optional object { boost_by, keyword_match_mode }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Each entry specifies a metadata field and an optional direction. Direction defaults to 'asc' for numeric/datetime fields and 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

  - `rewrite_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `rewrite_query: optional boolean`

  - `score_threshold: optional number`

  - `source: optional string`

  - `source_params: optional object { exclude_items, include_items, prefix, 2 more }`

    - `exclude_items: optional array of string`

      List of path patterns to exclude. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and /admin/settings/advanced)

    - `include_items: optional array of string`

      List of path patterns to include. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post)

    - `prefix: optional string`

    - `r2_jurisdiction: optional string`

    - `web_crawler: optional object { crawl_options, parse_options, parse_type, store_options }`

      - `crawl_options: optional object { depth, include_external_links, include_subdomains, 2 more }`

        - `depth: optional number`

        - `include_external_links: optional boolean`

        - `include_subdomains: optional boolean`

        - `max_age: optional number`

        - `source: optional "all" or "sitemaps" or "links"`

          - `"all"`

          - `"sitemaps"`

          - `"links"`

      - `parse_options: optional object { content_selector, include_headers, include_images, 2 more }`

        - `content_selector: optional array of object { path, selector }`

          List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first matching path wins. Only the matched HTML fragment is stored and indexed. Omit the field to disable content selection — empty arrays are rejected.

          - `path: string`

            Glob pattern to match against the page URL path. Uses standard glob syntax: * matches within a segment, ** crosses directories.

          - `selector: string`

            CSS selector to extract content from pages matching the path pattern. Must not contain disallowed characters (;, `, $, {, }, ). Must target a single element; if multiple elements match, the selector is ignored and the full page is used.

        - `include_headers: optional map[string]`

          Up to 5 custom HTTP headers sent with each crawl request. Names must be RFC-7230 token characters (no spaces, colons, or control characters); values must be HTAB + printable ASCII (no CR/LF).

        - `include_images: optional boolean`

        - `specific_sitemaps: optional array of string`

          List of specific sitemap URLs to use for crawling. Only valid when parse_type is 'sitemap'.

        - `use_browser_rendering: optional boolean`

      - `parse_type: optional "sitemap" or "feed-rss" or "crawl"`

        - `"sitemap"`

        - `"feed-rss"`

        - `"crawl"`

      - `store_options: optional object { storage_id, r2_jurisdiction, storage_type }`

        - `storage_id: string`

        - `r2_jurisdiction: optional string`

        - `storage_type: optional Provider`

          - `"r2"`

  - `status: optional string`

  - `sync_interval: optional 900 or 1800 or 3600 or 5 more`

    Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h).

    - `900`

    - `1800`

    - `3600`

    - `7200`

    - `14400`

    - `21600`

    - `43200`

    - `86400`

  - `token_id: optional string`

  - `type: optional "r2" or "web-crawler"`

    - `"r2"`

    - `"web-crawler"`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME/instances \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
    -d '{
          "id": "my-ai-search"
        }'
```

#### Response

```json
{
  "result": {
    "id": "my-ai-search",
    "created_at": "2019-12-27T18:11:19.117Z",
    "modified_at": "2019-12-27T18:11:19.117Z",
    "ai_gateway_id": "ai_gateway_id",
    "ai_search_model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
    "cache": true,
    "cache_threshold": "super_strict_match",
    "cache_ttl": 600,
    "chunk_overlap": 0,
    "chunk_size": 64,
    "created_by": "created_by",
    "custom_metadata": [
      {
        "data_type": "text",
        "field_name": "x"
      }
    ],
    "embedding_model": "@cf/qwen/qwen3-embedding-0.6b",
    "enable": true,
    "engine_version": 0,
    "fusion_method": "max",
    "hybrid_search_enabled": true,
    "index_method": {
      "keyword": true,
      "vector": true
    },
    "indexing_options": {
      "keyword_tokenizer": "porter"
    },
    "last_activity": "2019-12-27T18:11:19.117Z",
    "max_num_results": 1,
    "metadata": {
      "created_from_aisearch_wizard": true,
      "worker_domain": "worker_domain"
    },
    "modified_by": "modified_by",
    "namespace": "namespace",
    "paused": true,
    "public_endpoint_id": "public_endpoint_id",
    "public_endpoint_params": {
      "authorized_hosts": [
        "string"
      ],
      "chat_completions_endpoint": {
        "disabled": true
      },
      "enabled": true,
      "mcp": {
        "description": "description",
        "disabled": true
      },
      "rate_limit": {
        "period_ms": 60000,
        "requests": 1,
        "technique": "fixed"
      },
      "search_endpoint": {
        "disabled": true
      }
    },
    "reranking": true,
    "reranking_model": "@cf/baai/bge-reranker-base",
    "retrieval_options": {
      "boost_by": [
        {
          "field": "timestamp",
          "direction": "desc"
        }
      ],
      "keyword_match_mode": "and"
    },
    "rewrite_model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
    "rewrite_query": true,
    "score_threshold": 0,
    "source": "source",
    "source_params": {
      "exclude_items": [
        "/admin/**",
        "/private/**",
        "**\\temp\\**"
      ],
      "include_items": [
        "/blog/**",
        "/docs/**/*.html",
        "**\\blog\\**.html"
      ],
      "prefix": "prefix",
      "r2_jurisdiction": "r2_jurisdiction",
      "web_crawler": {
        "crawl_options": {
          "depth": 1,
          "include_external_links": true,
          "include_subdomains": true,
          "max_age": 0,
          "source": "all"
        },
        "parse_options": {
          "content_selector": [
            {
              "path": "**/blog/**",
              "selector": "article div.post-body"
            },
            {
              "path": "**/docs/**",
              "selector": "main"
            }
          ],
          "include_headers": {
            "cache-control": "no-cache, no-store"
          },
          "include_images": true,
          "specific_sitemaps": [
            "https://example.com/sitemap.xml",
            "https://example.com/blog-sitemap.xml"
          ],
          "use_browser_rendering": true
        },
        "parse_type": "sitemap",
        "store_options": {
          "storage_id": "storage_id",
          "r2_jurisdiction": "r2_jurisdiction",
          "storage_type": "r2"
        }
      }
    },
    "status": "status",
    "sync_interval": 900,
    "token_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
    "type": "r2"
  },
  "success": true
}
```

## Read instance.

**get** `/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}`

Read instance.

### Path Parameters

- `account_id: string`

- `name: string`

- `id: string`

### Returns

- `result: object { id, created_at, modified_at, 36 more }`

  - `id: string`

    AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

  - `created_at: string`

  - `modified_at: string`

  - `ai_gateway_id: optional string`

  - `ai_search_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `cache: optional boolean`

  - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

    - `"super_strict_match"`

    - `"close_enough"`

    - `"flexible_friend"`

    - `"anything_goes"`

  - `cache_ttl: optional 600 or 1800 or 3600 or 7 more`

    Cache entry TTL in seconds. Allowed values: 600 (10min), 1800 (30min), 3600 (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d).

    - `600`

    - `1800`

    - `3600`

    - `7200`

    - `21600`

    - `43200`

    - `86400`

    - `172800`

    - `259200`

    - `518400`

  - `chunk_overlap: optional number`

  - `chunk_size: optional number`

  - `created_by: optional string`

  - `custom_metadata: optional array of object { data_type, field_name }`

    - `data_type: "text" or "number" or "boolean" or "datetime"`

      - `"text"`

      - `"number"`

      - `"boolean"`

      - `"datetime"`

    - `field_name: string`

  - `embedding_model: optional "@cf/qwen/qwen3-embedding-0.6b" or "@cf/baai/bge-m3" or "@cf/baai/bge-large-en-v1.5" or 6 more`

    - `"@cf/qwen/qwen3-embedding-0.6b"`

    - `"@cf/baai/bge-m3"`

    - `"@cf/baai/bge-large-en-v1.5"`

    - `"@cf/google/embeddinggemma-300m"`

    - `"google-ai-studio/gemini-embedding-001"`

    - `"google-ai-studio/gemini-embedding-2-preview"`

    - `"openai/text-embedding-3-small"`

    - `"openai/text-embedding-3-large"`

    - `""`

  - `enable: optional boolean`

  - `engine_version: optional number`

  - `fusion_method: optional "max" or "rrf"`

    - `"max"`

    - `"rrf"`

  - `hybrid_search_enabled: optional boolean`

    Deprecated — use index_method instead.

  - `index_method: optional object { keyword, vector }`

    Controls which storage backends are used during indexing. Defaults to vector-only.

    - `keyword: boolean`

      Enable keyword (BM25) storage backend.

    - `vector: boolean`

      Enable vector (embedding) storage backend.

  - `indexing_options: optional object { keyword_tokenizer }`

    - `keyword_tokenizer: optional "porter" or "trigram"`

      Tokenizer used for keyword search indexing. porter provides word-level tokenization with Porter stemming (good for natural language queries). trigram enables character-level substring matching (good for partial matches, code, identifiers). Changing this triggers a full re-index. Defaults to porter.

      - `"porter"`

      - `"trigram"`

  - `last_activity: optional string`

  - `max_num_results: optional number`

  - `metadata: optional object { created_from_aisearch_wizard, worker_domain }`

    - `created_from_aisearch_wizard: optional boolean`

    - `worker_domain: optional string`

  - `modified_by: optional string`

  - `namespace: optional string`

  - `paused: optional boolean`

  - `public_endpoint_id: optional string`

  - `public_endpoint_params: optional object { authorized_hosts, chat_completions_endpoint, enabled, 3 more }`

    - `authorized_hosts: optional array of string`

    - `chat_completions_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable chat completions endpoint for this public endpoint

    - `enabled: optional boolean`

    - `mcp: optional object { description, disabled }`

      - `description: optional string`

      - `disabled: optional boolean`

        Disable MCP endpoint for this public endpoint

    - `rate_limit: optional object { period_ms, requests, technique }`

      - `period_ms: optional number`

      - `requests: optional number`

      - `technique: optional "fixed" or "sliding"`

        - `"fixed"`

        - `"sliding"`

    - `search_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable search endpoint for this public endpoint

  - `reranking: optional boolean`

  - `reranking_model: optional "@cf/baai/bge-reranker-base" or ""`

    - `"@cf/baai/bge-reranker-base"`

    - `""`

  - `retrieval_options: optional object { boost_by, keyword_match_mode }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Each entry specifies a metadata field and an optional direction. Direction defaults to 'asc' for numeric/datetime fields and 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

  - `rewrite_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `rewrite_query: optional boolean`

  - `score_threshold: optional number`

  - `source: optional string`

  - `source_params: optional object { exclude_items, include_items, prefix, 2 more }`

    - `exclude_items: optional array of string`

      List of path patterns to exclude. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and /admin/settings/advanced)

    - `include_items: optional array of string`

      List of path patterns to include. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post)

    - `prefix: optional string`

    - `r2_jurisdiction: optional string`

    - `web_crawler: optional object { crawl_options, parse_options, parse_type, store_options }`

      - `crawl_options: optional object { depth, include_external_links, include_subdomains, 2 more }`

        - `depth: optional number`

        - `include_external_links: optional boolean`

        - `include_subdomains: optional boolean`

        - `max_age: optional number`

        - `source: optional "all" or "sitemaps" or "links"`

          - `"all"`

          - `"sitemaps"`

          - `"links"`

      - `parse_options: optional object { content_selector, include_headers, include_images, 2 more }`

        - `content_selector: optional array of object { path, selector }`

          List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first matching path wins. Only the matched HTML fragment is stored and indexed. Omit the field to disable content selection — empty arrays are rejected.

          - `path: string`

            Glob pattern to match against the page URL path. Uses standard glob syntax: * matches within a segment, ** crosses directories.

          - `selector: string`

            CSS selector to extract content from pages matching the path pattern. Must not contain disallowed characters (;, `, $, {, }, ). Must target a single element; if multiple elements match, the selector is ignored and the full page is used.

        - `include_headers: optional map[string]`

          Up to 5 custom HTTP headers sent with each crawl request. Names must be RFC-7230 token characters (no spaces, colons, or control characters); values must be HTAB + printable ASCII (no CR/LF).

        - `include_images: optional boolean`

        - `specific_sitemaps: optional array of string`

          List of specific sitemap URLs to use for crawling. Only valid when parse_type is 'sitemap'.

        - `use_browser_rendering: optional boolean`

      - `parse_type: optional "sitemap" or "feed-rss" or "crawl"`

        - `"sitemap"`

        - `"feed-rss"`

        - `"crawl"`

      - `store_options: optional object { storage_id, r2_jurisdiction, storage_type }`

        - `storage_id: string`

        - `r2_jurisdiction: optional string`

        - `storage_type: optional Provider`

          - `"r2"`

  - `status: optional string`

  - `sync_interval: optional 900 or 1800 or 3600 or 5 more`

    Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h).

    - `900`

    - `1800`

    - `3600`

    - `7200`

    - `14400`

    - `21600`

    - `43200`

    - `86400`

  - `token_id: optional string`

  - `type: optional "r2" or "web-crawler"`

    - `"r2"`

    - `"web-crawler"`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME/instances/$ID \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": {
    "id": "my-ai-search",
    "created_at": "2019-12-27T18:11:19.117Z",
    "modified_at": "2019-12-27T18:11:19.117Z",
    "ai_gateway_id": "ai_gateway_id",
    "ai_search_model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
    "cache": true,
    "cache_threshold": "super_strict_match",
    "cache_ttl": 600,
    "chunk_overlap": 0,
    "chunk_size": 64,
    "created_by": "created_by",
    "custom_metadata": [
      {
        "data_type": "text",
        "field_name": "x"
      }
    ],
    "embedding_model": "@cf/qwen/qwen3-embedding-0.6b",
    "enable": true,
    "engine_version": 0,
    "fusion_method": "max",
    "hybrid_search_enabled": true,
    "index_method": {
      "keyword": true,
      "vector": true
    },
    "indexing_options": {
      "keyword_tokenizer": "porter"
    },
    "last_activity": "2019-12-27T18:11:19.117Z",
    "max_num_results": 1,
    "metadata": {
      "created_from_aisearch_wizard": true,
      "worker_domain": "worker_domain"
    },
    "modified_by": "modified_by",
    "namespace": "namespace",
    "paused": true,
    "public_endpoint_id": "public_endpoint_id",
    "public_endpoint_params": {
      "authorized_hosts": [
        "string"
      ],
      "chat_completions_endpoint": {
        "disabled": true
      },
      "enabled": true,
      "mcp": {
        "description": "description",
        "disabled": true
      },
      "rate_limit": {
        "period_ms": 60000,
        "requests": 1,
        "technique": "fixed"
      },
      "search_endpoint": {
        "disabled": true
      }
    },
    "reranking": true,
    "reranking_model": "@cf/baai/bge-reranker-base",
    "retrieval_options": {
      "boost_by": [
        {
          "field": "timestamp",
          "direction": "desc"
        }
      ],
      "keyword_match_mode": "and"
    },
    "rewrite_model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
    "rewrite_query": true,
    "score_threshold": 0,
    "source": "source",
    "source_params": {
      "exclude_items": [
        "/admin/**",
        "/private/**",
        "**\\temp\\**"
      ],
      "include_items": [
        "/blog/**",
        "/docs/**/*.html",
        "**\\blog\\**.html"
      ],
      "prefix": "prefix",
      "r2_jurisdiction": "r2_jurisdiction",
      "web_crawler": {
        "crawl_options": {
          "depth": 1,
          "include_external_links": true,
          "include_subdomains": true,
          "max_age": 0,
          "source": "all"
        },
        "parse_options": {
          "content_selector": [
            {
              "path": "**/blog/**",
              "selector": "article div.post-body"
            },
            {
              "path": "**/docs/**",
              "selector": "main"
            }
          ],
          "include_headers": {
            "cache-control": "no-cache, no-store"
          },
          "include_images": true,
          "specific_sitemaps": [
            "https://example.com/sitemap.xml",
            "https://example.com/blog-sitemap.xml"
          ],
          "use_browser_rendering": true
        },
        "parse_type": "sitemap",
        "store_options": {
          "storage_id": "storage_id",
          "r2_jurisdiction": "r2_jurisdiction",
          "storage_type": "r2"
        }
      }
    },
    "status": "status",
    "sync_interval": 900,
    "token_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
    "type": "r2"
  },
  "success": true
}
```

## Update instance.

**put** `/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}`

Update instance.

### Path Parameters

- `account_id: string`

- `name: string`

- `id: string`

### Body Parameters

- `ai_gateway_id: optional string`

- `ai_search_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

  - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

  - `"@cf/zai-org/glm-4.7-flash"`

  - `"@cf/meta/llama-3.1-8b-instruct-fast"`

  - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

  - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

  - `"@cf/qwen/qwen3-30b-a3b-fp8"`

  - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

  - `"@cf/moonshotai/kimi-k2-instruct"`

  - `"@cf/google/gemma-3-12b-it"`

  - `"@cf/google/gemma-4-26b-a4b-it"`

  - `"@cf/moonshotai/kimi-k2.5"`

  - `"anthropic/claude-3-7-sonnet"`

  - `"anthropic/claude-sonnet-4"`

  - `"anthropic/claude-opus-4"`

  - `"anthropic/claude-3-5-haiku"`

  - `"cerebras/qwen-3-235b-a22b-instruct"`

  - `"cerebras/qwen-3-235b-a22b-thinking"`

  - `"cerebras/llama-3.3-70b"`

  - `"cerebras/llama-4-maverick-17b-128e-instruct"`

  - `"cerebras/llama-4-scout-17b-16e-instruct"`

  - `"cerebras/gpt-oss-120b"`

  - `"google-ai-studio/gemini-2.5-flash"`

  - `"google-ai-studio/gemini-2.5-pro"`

  - `"grok/grok-4"`

  - `"groq/llama-3.3-70b-versatile"`

  - `"groq/llama-3.1-8b-instant"`

  - `"openai/gpt-5"`

  - `"openai/gpt-5-mini"`

  - `"openai/gpt-5-nano"`

  - `""`

- `cache: optional boolean`

- `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

  - `"super_strict_match"`

  - `"close_enough"`

  - `"flexible_friend"`

  - `"anything_goes"`

- `cache_ttl: optional 600 or 1800 or 3600 or 7 more`

  Cache entry TTL in seconds. Allowed values: 600 (10min), 1800 (30min), 3600 (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d).

  - `600`

  - `1800`

  - `3600`

  - `7200`

  - `21600`

  - `43200`

  - `86400`

  - `172800`

  - `259200`

  - `518400`

- `chunk: optional boolean`

- `chunk_overlap: optional number`

- `chunk_size: optional number`

- `custom_metadata: optional array of object { data_type, field_name }`

  - `data_type: "text" or "number" or "boolean" or "datetime"`

    - `"text"`

    - `"number"`

    - `"boolean"`

    - `"datetime"`

  - `field_name: string`

- `embedding_model: optional "@cf/qwen/qwen3-embedding-0.6b" or "@cf/baai/bge-m3" or "@cf/baai/bge-large-en-v1.5" or 6 more`

  - `"@cf/qwen/qwen3-embedding-0.6b"`

  - `"@cf/baai/bge-m3"`

  - `"@cf/baai/bge-large-en-v1.5"`

  - `"@cf/google/embeddinggemma-300m"`

  - `"google-ai-studio/gemini-embedding-001"`

  - `"google-ai-studio/gemini-embedding-2-preview"`

  - `"openai/text-embedding-3-small"`

  - `"openai/text-embedding-3-large"`

  - `""`

- `fusion_method: optional "max" or "rrf"`

  - `"max"`

  - `"rrf"`

- `index_method: optional object { keyword, vector }`

  Controls which storage backends are used during indexing. Defaults to vector-only.

  - `keyword: boolean`

    Enable keyword (BM25) storage backend.

  - `vector: boolean`

    Enable vector (embedding) storage backend.

- `indexing_options: optional object { keyword_tokenizer }`

  - `keyword_tokenizer: optional "porter" or "trigram"`

    Tokenizer used for keyword search indexing. porter provides word-level tokenization with Porter stemming (good for natural language queries). trigram enables character-level substring matching (good for partial matches, code, identifiers). Changing this triggers a full re-index. Defaults to porter.

    - `"porter"`

    - `"trigram"`

- `max_num_results: optional number`

- `metadata: optional object { created_from_aisearch_wizard, worker_domain }`

  - `created_from_aisearch_wizard: optional boolean`

  - `worker_domain: optional string`

- `paused: optional boolean`

- `public_endpoint_params: optional object { authorized_hosts, chat_completions_endpoint, enabled, 3 more }`

  - `authorized_hosts: optional array of string`

  - `chat_completions_endpoint: optional object { disabled }`

    - `disabled: optional boolean`

      Disable chat completions endpoint for this public endpoint

  - `enabled: optional boolean`

  - `mcp: optional object { description, disabled }`

    - `description: optional string`

    - `disabled: optional boolean`

      Disable MCP endpoint for this public endpoint

  - `rate_limit: optional object { period_ms, requests, technique }`

    - `period_ms: optional number`

    - `requests: optional number`

    - `technique: optional "fixed" or "sliding"`

      - `"fixed"`

      - `"sliding"`

  - `search_endpoint: optional object { disabled }`

    - `disabled: optional boolean`

      Disable search endpoint for this public endpoint

- `reranking: optional boolean`

- `reranking_model: optional "@cf/baai/bge-reranker-base" or ""`

  - `"@cf/baai/bge-reranker-base"`

  - `""`

- `retrieval_options: optional object { boost_by, keyword_match_mode }`

  - `boost_by: optional array of object { field, direction }`

    Metadata fields to boost search results by. Each entry specifies a metadata field and an optional direction. Direction defaults to 'asc' for numeric/datetime fields and 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

    - `field: string`

      Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

    - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

      Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

      - `"asc"`

      - `"desc"`

      - `"exists"`

      - `"not_exists"`

  - `keyword_match_mode: optional "and" or "or"`

    Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

    - `"and"`

    - `"or"`

- `rewrite_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

  - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

  - `"@cf/zai-org/glm-4.7-flash"`

  - `"@cf/meta/llama-3.1-8b-instruct-fast"`

  - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

  - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

  - `"@cf/qwen/qwen3-30b-a3b-fp8"`

  - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

  - `"@cf/moonshotai/kimi-k2-instruct"`

  - `"@cf/google/gemma-3-12b-it"`

  - `"@cf/google/gemma-4-26b-a4b-it"`

  - `"@cf/moonshotai/kimi-k2.5"`

  - `"anthropic/claude-3-7-sonnet"`

  - `"anthropic/claude-sonnet-4"`

  - `"anthropic/claude-opus-4"`

  - `"anthropic/claude-3-5-haiku"`

  - `"cerebras/qwen-3-235b-a22b-instruct"`

  - `"cerebras/qwen-3-235b-a22b-thinking"`

  - `"cerebras/llama-3.3-70b"`

  - `"cerebras/llama-4-maverick-17b-128e-instruct"`

  - `"cerebras/llama-4-scout-17b-16e-instruct"`

  - `"cerebras/gpt-oss-120b"`

  - `"google-ai-studio/gemini-2.5-flash"`

  - `"google-ai-studio/gemini-2.5-pro"`

  - `"grok/grok-4"`

  - `"groq/llama-3.3-70b-versatile"`

  - `"groq/llama-3.1-8b-instant"`

  - `"openai/gpt-5"`

  - `"openai/gpt-5-mini"`

  - `"openai/gpt-5-nano"`

  - `""`

- `rewrite_query: optional boolean`

- `score_threshold: optional number`

- `source_params: optional object { exclude_items, include_items, prefix, 2 more }`

  - `exclude_items: optional array of string`

    List of path patterns to exclude. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and /admin/settings/advanced)

  - `include_items: optional array of string`

    List of path patterns to include. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post)

  - `prefix: optional string`

  - `r2_jurisdiction: optional string`

  - `web_crawler: optional object { crawl_options, parse_options, parse_type, store_options }`

    - `crawl_options: optional object { depth, include_external_links, include_subdomains, 2 more }`

      - `depth: optional number`

      - `include_external_links: optional boolean`

      - `include_subdomains: optional boolean`

      - `max_age: optional number`

      - `source: optional "all" or "sitemaps" or "links"`

        - `"all"`

        - `"sitemaps"`

        - `"links"`

    - `parse_options: optional object { content_selector, include_headers, include_images, 2 more }`

      - `content_selector: optional array of object { path, selector }`

        List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first matching path wins. Only the matched HTML fragment is stored and indexed. Omit the field to disable content selection — empty arrays are rejected.

        - `path: string`

          Glob pattern to match against the page URL path. Uses standard glob syntax: * matches within a segment, ** crosses directories.

        - `selector: string`

          CSS selector to extract content from pages matching the path pattern. Must not contain disallowed characters (;, `, $, {, }, ). Must target a single element; if multiple elements match, the selector is ignored and the full page is used.

      - `include_headers: optional map[string]`

        Up to 5 custom HTTP headers sent with each crawl request. Names must be RFC-7230 token characters (no spaces, colons, or control characters); values must be HTAB + printable ASCII (no CR/LF).

      - `include_images: optional boolean`

      - `specific_sitemaps: optional array of string`

        List of specific sitemap URLs to use for crawling. Only valid when parse_type is 'sitemap'.

      - `use_browser_rendering: optional boolean`

    - `parse_type: optional "sitemap" or "feed-rss" or "crawl"`

      - `"sitemap"`

      - `"feed-rss"`

      - `"crawl"`

    - `store_options: optional object { storage_id, r2_jurisdiction, storage_type }`

      - `storage_id: string`

      - `r2_jurisdiction: optional string`

      - `storage_type: optional Provider`

        - `"r2"`

- `summarization: optional boolean`

- `summarization_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

  - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

  - `"@cf/zai-org/glm-4.7-flash"`

  - `"@cf/meta/llama-3.1-8b-instruct-fast"`

  - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

  - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

  - `"@cf/qwen/qwen3-30b-a3b-fp8"`

  - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

  - `"@cf/moonshotai/kimi-k2-instruct"`

  - `"@cf/google/gemma-3-12b-it"`

  - `"@cf/google/gemma-4-26b-a4b-it"`

  - `"@cf/moonshotai/kimi-k2.5"`

  - `"anthropic/claude-3-7-sonnet"`

  - `"anthropic/claude-sonnet-4"`

  - `"anthropic/claude-opus-4"`

  - `"anthropic/claude-3-5-haiku"`

  - `"cerebras/qwen-3-235b-a22b-instruct"`

  - `"cerebras/qwen-3-235b-a22b-thinking"`

  - `"cerebras/llama-3.3-70b"`

  - `"cerebras/llama-4-maverick-17b-128e-instruct"`

  - `"cerebras/llama-4-scout-17b-16e-instruct"`

  - `"cerebras/gpt-oss-120b"`

  - `"google-ai-studio/gemini-2.5-flash"`

  - `"google-ai-studio/gemini-2.5-pro"`

  - `"grok/grok-4"`

  - `"groq/llama-3.3-70b-versatile"`

  - `"groq/llama-3.1-8b-instant"`

  - `"openai/gpt-5"`

  - `"openai/gpt-5-mini"`

  - `"openai/gpt-5-nano"`

  - `""`

- `sync_interval: optional 900 or 1800 or 3600 or 5 more`

  Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h).

  - `900`

  - `1800`

  - `3600`

  - `7200`

  - `14400`

  - `21600`

  - `43200`

  - `86400`

- `system_prompt_ai_search: optional string`

- `system_prompt_index_summarization: optional string`

- `system_prompt_rewrite_query: optional string`

- `token_id: optional string`

### Returns

- `result: object { id, created_at, modified_at, 36 more }`

  - `id: string`

    AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

  - `created_at: string`

  - `modified_at: string`

  - `ai_gateway_id: optional string`

  - `ai_search_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `cache: optional boolean`

  - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

    - `"super_strict_match"`

    - `"close_enough"`

    - `"flexible_friend"`

    - `"anything_goes"`

  - `cache_ttl: optional 600 or 1800 or 3600 or 7 more`

    Cache entry TTL in seconds. Allowed values: 600 (10min), 1800 (30min), 3600 (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d).

    - `600`

    - `1800`

    - `3600`

    - `7200`

    - `21600`

    - `43200`

    - `86400`

    - `172800`

    - `259200`

    - `518400`

  - `chunk_overlap: optional number`

  - `chunk_size: optional number`

  - `created_by: optional string`

  - `custom_metadata: optional array of object { data_type, field_name }`

    - `data_type: "text" or "number" or "boolean" or "datetime"`

      - `"text"`

      - `"number"`

      - `"boolean"`

      - `"datetime"`

    - `field_name: string`

  - `embedding_model: optional "@cf/qwen/qwen3-embedding-0.6b" or "@cf/baai/bge-m3" or "@cf/baai/bge-large-en-v1.5" or 6 more`

    - `"@cf/qwen/qwen3-embedding-0.6b"`

    - `"@cf/baai/bge-m3"`

    - `"@cf/baai/bge-large-en-v1.5"`

    - `"@cf/google/embeddinggemma-300m"`

    - `"google-ai-studio/gemini-embedding-001"`

    - `"google-ai-studio/gemini-embedding-2-preview"`

    - `"openai/text-embedding-3-small"`

    - `"openai/text-embedding-3-large"`

    - `""`

  - `enable: optional boolean`

  - `engine_version: optional number`

  - `fusion_method: optional "max" or "rrf"`

    - `"max"`

    - `"rrf"`

  - `hybrid_search_enabled: optional boolean`

    Deprecated — use index_method instead.

  - `index_method: optional object { keyword, vector }`

    Controls which storage backends are used during indexing. Defaults to vector-only.

    - `keyword: boolean`

      Enable keyword (BM25) storage backend.

    - `vector: boolean`

      Enable vector (embedding) storage backend.

  - `indexing_options: optional object { keyword_tokenizer }`

    - `keyword_tokenizer: optional "porter" or "trigram"`

      Tokenizer used for keyword search indexing. porter provides word-level tokenization with Porter stemming (good for natural language queries). trigram enables character-level substring matching (good for partial matches, code, identifiers). Changing this triggers a full re-index. Defaults to porter.

      - `"porter"`

      - `"trigram"`

  - `last_activity: optional string`

  - `max_num_results: optional number`

  - `metadata: optional object { created_from_aisearch_wizard, worker_domain }`

    - `created_from_aisearch_wizard: optional boolean`

    - `worker_domain: optional string`

  - `modified_by: optional string`

  - `namespace: optional string`

  - `paused: optional boolean`

  - `public_endpoint_id: optional string`

  - `public_endpoint_params: optional object { authorized_hosts, chat_completions_endpoint, enabled, 3 more }`

    - `authorized_hosts: optional array of string`

    - `chat_completions_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable chat completions endpoint for this public endpoint

    - `enabled: optional boolean`

    - `mcp: optional object { description, disabled }`

      - `description: optional string`

      - `disabled: optional boolean`

        Disable MCP endpoint for this public endpoint

    - `rate_limit: optional object { period_ms, requests, technique }`

      - `period_ms: optional number`

      - `requests: optional number`

      - `technique: optional "fixed" or "sliding"`

        - `"fixed"`

        - `"sliding"`

    - `search_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable search endpoint for this public endpoint

  - `reranking: optional boolean`

  - `reranking_model: optional "@cf/baai/bge-reranker-base" or ""`

    - `"@cf/baai/bge-reranker-base"`

    - `""`

  - `retrieval_options: optional object { boost_by, keyword_match_mode }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Each entry specifies a metadata field and an optional direction. Direction defaults to 'asc' for numeric/datetime fields and 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

  - `rewrite_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `rewrite_query: optional boolean`

  - `score_threshold: optional number`

  - `source: optional string`

  - `source_params: optional object { exclude_items, include_items, prefix, 2 more }`

    - `exclude_items: optional array of string`

      List of path patterns to exclude. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and /admin/settings/advanced)

    - `include_items: optional array of string`

      List of path patterns to include. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post)

    - `prefix: optional string`

    - `r2_jurisdiction: optional string`

    - `web_crawler: optional object { crawl_options, parse_options, parse_type, store_options }`

      - `crawl_options: optional object { depth, include_external_links, include_subdomains, 2 more }`

        - `depth: optional number`

        - `include_external_links: optional boolean`

        - `include_subdomains: optional boolean`

        - `max_age: optional number`

        - `source: optional "all" or "sitemaps" or "links"`

          - `"all"`

          - `"sitemaps"`

          - `"links"`

      - `parse_options: optional object { content_selector, include_headers, include_images, 2 more }`

        - `content_selector: optional array of object { path, selector }`

          List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first matching path wins. Only the matched HTML fragment is stored and indexed. Omit the field to disable content selection — empty arrays are rejected.

          - `path: string`

            Glob pattern to match against the page URL path. Uses standard glob syntax: * matches within a segment, ** crosses directories.

          - `selector: string`

            CSS selector to extract content from pages matching the path pattern. Must not contain disallowed characters (;, `, $, {, }, ). Must target a single element; if multiple elements match, the selector is ignored and the full page is used.

        - `include_headers: optional map[string]`

          Up to 5 custom HTTP headers sent with each crawl request. Names must be RFC-7230 token characters (no spaces, colons, or control characters); values must be HTAB + printable ASCII (no CR/LF).

        - `include_images: optional boolean`

        - `specific_sitemaps: optional array of string`

          List of specific sitemap URLs to use for crawling. Only valid when parse_type is 'sitemap'.

        - `use_browser_rendering: optional boolean`

      - `parse_type: optional "sitemap" or "feed-rss" or "crawl"`

        - `"sitemap"`

        - `"feed-rss"`

        - `"crawl"`

      - `store_options: optional object { storage_id, r2_jurisdiction, storage_type }`

        - `storage_id: string`

        - `r2_jurisdiction: optional string`

        - `storage_type: optional Provider`

          - `"r2"`

  - `status: optional string`

  - `sync_interval: optional 900 or 1800 or 3600 or 5 more`

    Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h).

    - `900`

    - `1800`

    - `3600`

    - `7200`

    - `14400`

    - `21600`

    - `43200`

    - `86400`

  - `token_id: optional string`

  - `type: optional "r2" or "web-crawler"`

    - `"r2"`

    - `"web-crawler"`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME/instances/$ID \
    -X PUT \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": {
    "id": "my-ai-search",
    "created_at": "2019-12-27T18:11:19.117Z",
    "modified_at": "2019-12-27T18:11:19.117Z",
    "ai_gateway_id": "ai_gateway_id",
    "ai_search_model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
    "cache": true,
    "cache_threshold": "super_strict_match",
    "cache_ttl": 600,
    "chunk_overlap": 0,
    "chunk_size": 64,
    "created_by": "created_by",
    "custom_metadata": [
      {
        "data_type": "text",
        "field_name": "x"
      }
    ],
    "embedding_model": "@cf/qwen/qwen3-embedding-0.6b",
    "enable": true,
    "engine_version": 0,
    "fusion_method": "max",
    "hybrid_search_enabled": true,
    "index_method": {
      "keyword": true,
      "vector": true
    },
    "indexing_options": {
      "keyword_tokenizer": "porter"
    },
    "last_activity": "2019-12-27T18:11:19.117Z",
    "max_num_results": 1,
    "metadata": {
      "created_from_aisearch_wizard": true,
      "worker_domain": "worker_domain"
    },
    "modified_by": "modified_by",
    "namespace": "namespace",
    "paused": true,
    "public_endpoint_id": "public_endpoint_id",
    "public_endpoint_params": {
      "authorized_hosts": [
        "string"
      ],
      "chat_completions_endpoint": {
        "disabled": true
      },
      "enabled": true,
      "mcp": {
        "description": "description",
        "disabled": true
      },
      "rate_limit": {
        "period_ms": 60000,
        "requests": 1,
        "technique": "fixed"
      },
      "search_endpoint": {
        "disabled": true
      }
    },
    "reranking": true,
    "reranking_model": "@cf/baai/bge-reranker-base",
    "retrieval_options": {
      "boost_by": [
        {
          "field": "timestamp",
          "direction": "desc"
        }
      ],
      "keyword_match_mode": "and"
    },
    "rewrite_model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
    "rewrite_query": true,
    "score_threshold": 0,
    "source": "source",
    "source_params": {
      "exclude_items": [
        "/admin/**",
        "/private/**",
        "**\\temp\\**"
      ],
      "include_items": [
        "/blog/**",
        "/docs/**/*.html",
        "**\\blog\\**.html"
      ],
      "prefix": "prefix",
      "r2_jurisdiction": "r2_jurisdiction",
      "web_crawler": {
        "crawl_options": {
          "depth": 1,
          "include_external_links": true,
          "include_subdomains": true,
          "max_age": 0,
          "source": "all"
        },
        "parse_options": {
          "content_selector": [
            {
              "path": "**/blog/**",
              "selector": "article div.post-body"
            },
            {
              "path": "**/docs/**",
              "selector": "main"
            }
          ],
          "include_headers": {
            "cache-control": "no-cache, no-store"
          },
          "include_images": true,
          "specific_sitemaps": [
            "https://example.com/sitemap.xml",
            "https://example.com/blog-sitemap.xml"
          ],
          "use_browser_rendering": true
        },
        "parse_type": "sitemap",
        "store_options": {
          "storage_id": "storage_id",
          "r2_jurisdiction": "r2_jurisdiction",
          "storage_type": "r2"
        }
      }
    },
    "status": "status",
    "sync_interval": 900,
    "token_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
    "type": "r2"
  },
  "success": true
}
```

## Delete instance.

**delete** `/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}`

Delete instance.

### Path Parameters

- `account_id: string`

- `name: string`

- `id: string`

### Returns

- `result: object { id, created_at, modified_at, 36 more }`

  - `id: string`

    AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

  - `created_at: string`

  - `modified_at: string`

  - `ai_gateway_id: optional string`

  - `ai_search_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `cache: optional boolean`

  - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

    - `"super_strict_match"`

    - `"close_enough"`

    - `"flexible_friend"`

    - `"anything_goes"`

  - `cache_ttl: optional 600 or 1800 or 3600 or 7 more`

    Cache entry TTL in seconds. Allowed values: 600 (10min), 1800 (30min), 3600 (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d).

    - `600`

    - `1800`

    - `3600`

    - `7200`

    - `21600`

    - `43200`

    - `86400`

    - `172800`

    - `259200`

    - `518400`

  - `chunk_overlap: optional number`

  - `chunk_size: optional number`

  - `created_by: optional string`

  - `custom_metadata: optional array of object { data_type, field_name }`

    - `data_type: "text" or "number" or "boolean" or "datetime"`

      - `"text"`

      - `"number"`

      - `"boolean"`

      - `"datetime"`

    - `field_name: string`

  - `embedding_model: optional "@cf/qwen/qwen3-embedding-0.6b" or "@cf/baai/bge-m3" or "@cf/baai/bge-large-en-v1.5" or 6 more`

    - `"@cf/qwen/qwen3-embedding-0.6b"`

    - `"@cf/baai/bge-m3"`

    - `"@cf/baai/bge-large-en-v1.5"`

    - `"@cf/google/embeddinggemma-300m"`

    - `"google-ai-studio/gemini-embedding-001"`

    - `"google-ai-studio/gemini-embedding-2-preview"`

    - `"openai/text-embedding-3-small"`

    - `"openai/text-embedding-3-large"`

    - `""`

  - `enable: optional boolean`

  - `engine_version: optional number`

  - `fusion_method: optional "max" or "rrf"`

    - `"max"`

    - `"rrf"`

  - `hybrid_search_enabled: optional boolean`

    Deprecated — use index_method instead.

  - `index_method: optional object { keyword, vector }`

    Controls which storage backends are used during indexing. Defaults to vector-only.

    - `keyword: boolean`

      Enable keyword (BM25) storage backend.

    - `vector: boolean`

      Enable vector (embedding) storage backend.

  - `indexing_options: optional object { keyword_tokenizer }`

    - `keyword_tokenizer: optional "porter" or "trigram"`

      Tokenizer used for keyword search indexing. porter provides word-level tokenization with Porter stemming (good for natural language queries). trigram enables character-level substring matching (good for partial matches, code, identifiers). Changing this triggers a full re-index. Defaults to porter.

      - `"porter"`

      - `"trigram"`

  - `last_activity: optional string`

  - `max_num_results: optional number`

  - `metadata: optional object { created_from_aisearch_wizard, worker_domain }`

    - `created_from_aisearch_wizard: optional boolean`

    - `worker_domain: optional string`

  - `modified_by: optional string`

  - `namespace: optional string`

  - `paused: optional boolean`

  - `public_endpoint_id: optional string`

  - `public_endpoint_params: optional object { authorized_hosts, chat_completions_endpoint, enabled, 3 more }`

    - `authorized_hosts: optional array of string`

    - `chat_completions_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable chat completions endpoint for this public endpoint

    - `enabled: optional boolean`

    - `mcp: optional object { description, disabled }`

      - `description: optional string`

      - `disabled: optional boolean`

        Disable MCP endpoint for this public endpoint

    - `rate_limit: optional object { period_ms, requests, technique }`

      - `period_ms: optional number`

      - `requests: optional number`

      - `technique: optional "fixed" or "sliding"`

        - `"fixed"`

        - `"sliding"`

    - `search_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable search endpoint for this public endpoint

  - `reranking: optional boolean`

  - `reranking_model: optional "@cf/baai/bge-reranker-base" or ""`

    - `"@cf/baai/bge-reranker-base"`

    - `""`

  - `retrieval_options: optional object { boost_by, keyword_match_mode }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Each entry specifies a metadata field and an optional direction. Direction defaults to 'asc' for numeric/datetime fields and 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

  - `rewrite_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `rewrite_query: optional boolean`

  - `score_threshold: optional number`

  - `source: optional string`

  - `source_params: optional object { exclude_items, include_items, prefix, 2 more }`

    - `exclude_items: optional array of string`

      List of path patterns to exclude. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and /admin/settings/advanced)

    - `include_items: optional array of string`

      List of path patterns to include. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post)

    - `prefix: optional string`

    - `r2_jurisdiction: optional string`

    - `web_crawler: optional object { crawl_options, parse_options, parse_type, store_options }`

      - `crawl_options: optional object { depth, include_external_links, include_subdomains, 2 more }`

        - `depth: optional number`

        - `include_external_links: optional boolean`

        - `include_subdomains: optional boolean`

        - `max_age: optional number`

        - `source: optional "all" or "sitemaps" or "links"`

          - `"all"`

          - `"sitemaps"`

          - `"links"`

      - `parse_options: optional object { content_selector, include_headers, include_images, 2 more }`

        - `content_selector: optional array of object { path, selector }`

          List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first matching path wins. Only the matched HTML fragment is stored and indexed. Omit the field to disable content selection — empty arrays are rejected.

          - `path: string`

            Glob pattern to match against the page URL path. Uses standard glob syntax: * matches within a segment, ** crosses directories.

          - `selector: string`

            CSS selector to extract content from pages matching the path pattern. Must not contain disallowed characters (;, `, $, {, }, ). Must target a single element; if multiple elements match, the selector is ignored and the full page is used.

        - `include_headers: optional map[string]`

          Up to 5 custom HTTP headers sent with each crawl request. Names must be RFC-7230 token characters (no spaces, colons, or control characters); values must be HTAB + printable ASCII (no CR/LF).

        - `include_images: optional boolean`

        - `specific_sitemaps: optional array of string`

          List of specific sitemap URLs to use for crawling. Only valid when parse_type is 'sitemap'.

        - `use_browser_rendering: optional boolean`

      - `parse_type: optional "sitemap" or "feed-rss" or "crawl"`

        - `"sitemap"`

        - `"feed-rss"`

        - `"crawl"`

      - `store_options: optional object { storage_id, r2_jurisdiction, storage_type }`

        - `storage_id: string`

        - `r2_jurisdiction: optional string`

        - `storage_type: optional Provider`

          - `"r2"`

  - `status: optional string`

  - `sync_interval: optional 900 or 1800 or 3600 or 5 more`

    Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h).

    - `900`

    - `1800`

    - `3600`

    - `7200`

    - `14400`

    - `21600`

    - `43200`

    - `86400`

  - `token_id: optional string`

  - `type: optional "r2" or "web-crawler"`

    - `"r2"`

    - `"web-crawler"`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME/instances/$ID \
    -X DELETE \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": {
    "id": "my-ai-search",
    "created_at": "2019-12-27T18:11:19.117Z",
    "modified_at": "2019-12-27T18:11:19.117Z",
    "ai_gateway_id": "ai_gateway_id",
    "ai_search_model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
    "cache": true,
    "cache_threshold": "super_strict_match",
    "cache_ttl": 600,
    "chunk_overlap": 0,
    "chunk_size": 64,
    "created_by": "created_by",
    "custom_metadata": [
      {
        "data_type": "text",
        "field_name": "x"
      }
    ],
    "embedding_model": "@cf/qwen/qwen3-embedding-0.6b",
    "enable": true,
    "engine_version": 0,
    "fusion_method": "max",
    "hybrid_search_enabled": true,
    "index_method": {
      "keyword": true,
      "vector": true
    },
    "indexing_options": {
      "keyword_tokenizer": "porter"
    },
    "last_activity": "2019-12-27T18:11:19.117Z",
    "max_num_results": 1,
    "metadata": {
      "created_from_aisearch_wizard": true,
      "worker_domain": "worker_domain"
    },
    "modified_by": "modified_by",
    "namespace": "namespace",
    "paused": true,
    "public_endpoint_id": "public_endpoint_id",
    "public_endpoint_params": {
      "authorized_hosts": [
        "string"
      ],
      "chat_completions_endpoint": {
        "disabled": true
      },
      "enabled": true,
      "mcp": {
        "description": "description",
        "disabled": true
      },
      "rate_limit": {
        "period_ms": 60000,
        "requests": 1,
        "technique": "fixed"
      },
      "search_endpoint": {
        "disabled": true
      }
    },
    "reranking": true,
    "reranking_model": "@cf/baai/bge-reranker-base",
    "retrieval_options": {
      "boost_by": [
        {
          "field": "timestamp",
          "direction": "desc"
        }
      ],
      "keyword_match_mode": "and"
    },
    "rewrite_model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
    "rewrite_query": true,
    "score_threshold": 0,
    "source": "source",
    "source_params": {
      "exclude_items": [
        "/admin/**",
        "/private/**",
        "**\\temp\\**"
      ],
      "include_items": [
        "/blog/**",
        "/docs/**/*.html",
        "**\\blog\\**.html"
      ],
      "prefix": "prefix",
      "r2_jurisdiction": "r2_jurisdiction",
      "web_crawler": {
        "crawl_options": {
          "depth": 1,
          "include_external_links": true,
          "include_subdomains": true,
          "max_age": 0,
          "source": "all"
        },
        "parse_options": {
          "content_selector": [
            {
              "path": "**/blog/**",
              "selector": "article div.post-body"
            },
            {
              "path": "**/docs/**",
              "selector": "main"
            }
          ],
          "include_headers": {
            "cache-control": "no-cache, no-store"
          },
          "include_images": true,
          "specific_sitemaps": [
            "https://example.com/sitemap.xml",
            "https://example.com/blog-sitemap.xml"
          ],
          "use_browser_rendering": true
        },
        "parse_type": "sitemap",
        "store_options": {
          "storage_id": "storage_id",
          "r2_jurisdiction": "r2_jurisdiction",
          "storage_type": "r2"
        }
      }
    },
    "status": "status",
    "sync_interval": 900,
    "token_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
    "type": "r2"
  },
  "success": true
}
```

## Stats

**get** `/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/stats`

Retrieves usage statistics for AI Search instances.

### Path Parameters

- `account_id: string`

- `name: string`

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

### Returns

- `result: object { completed, degraded, engine, 8 more }`

  - `completed: optional number`

  - `degraded: optional boolean`

    True when status counts are unavailable (e.g. legacy stats query exceeded D1 statement-size limit). Counts are omitted in this case.

  - `engine: optional object { r2, vectorize }`

    Engine-specific metadata. Present only for managed (v3) instances.

    - `r2: optional object { metadataSizeBytes, objectCount, payloadSizeBytes }`

      R2 bucket storage usage in bytes.

      - `metadataSizeBytes: number`

      - `objectCount: number`

      - `payloadSizeBytes: number`

    - `vectorize: optional object { dimensions, vectorsCount }`

      Vectorize index metadata (dimensions, vector count).

      - `dimensions: number`

      - `vectorsCount: number`

  - `error: optional number`

  - `file_embed_errors: optional map[unknown]`

  - `index_source_errors: optional map[unknown]`

  - `last_activity: optional string`

  - `outdated: optional number`

  - `queued: optional number`

  - `running: optional number`

  - `skipped: optional number`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME/instances/$ID/stats \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": {
    "completed": 0,
    "degraded": true,
    "engine": {
      "r2": {
        "metadataSizeBytes": 0,
        "objectCount": 0,
        "payloadSizeBytes": 0
      },
      "vectorize": {
        "dimensions": 0,
        "vectorsCount": 0
      }
    },
    "error": 0,
    "file_embed_errors": {
      "foo": "bar"
    },
    "index_source_errors": {
      "foo": "bar"
    },
    "last_activity": "2019-12-27T18:11:19.117Z",
    "outdated": 0,
    "queued": 0,
    "running": 0,
    "skipped": 0
  },
  "success": true
}
```

## Search

**post** `/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/search`

Executes a semantic search query against an AI Search instance to find relevant indexed content.

### Path Parameters

- `account_id: string`

- `name: string`

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

### Body Parameters

- `ai_search_options: optional object { cache, query_rewrite, reranking, retrieval }`

  - `cache: optional object { cache_threshold, enabled }`

    - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

      - `"super_strict_match"`

      - `"close_enough"`

      - `"flexible_friend"`

      - `"anything_goes"`

    - `enabled: optional boolean`

  - `query_rewrite: optional object { enabled, model, rewrite_prompt }`

    - `enabled: optional boolean`

    - `model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

      - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

      - `"@cf/zai-org/glm-4.7-flash"`

      - `"@cf/meta/llama-3.1-8b-instruct-fast"`

      - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

      - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

      - `"@cf/qwen/qwen3-30b-a3b-fp8"`

      - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

      - `"@cf/moonshotai/kimi-k2-instruct"`

      - `"@cf/google/gemma-3-12b-it"`

      - `"@cf/google/gemma-4-26b-a4b-it"`

      - `"@cf/moonshotai/kimi-k2.5"`

      - `"anthropic/claude-3-7-sonnet"`

      - `"anthropic/claude-sonnet-4"`

      - `"anthropic/claude-opus-4"`

      - `"anthropic/claude-3-5-haiku"`

      - `"cerebras/qwen-3-235b-a22b-instruct"`

      - `"cerebras/qwen-3-235b-a22b-thinking"`

      - `"cerebras/llama-3.3-70b"`

      - `"cerebras/llama-4-maverick-17b-128e-instruct"`

      - `"cerebras/llama-4-scout-17b-16e-instruct"`

      - `"cerebras/gpt-oss-120b"`

      - `"google-ai-studio/gemini-2.5-flash"`

      - `"google-ai-studio/gemini-2.5-pro"`

      - `"grok/grok-4"`

      - `"groq/llama-3.3-70b-versatile"`

      - `"groq/llama-3.1-8b-instant"`

      - `"openai/gpt-5"`

      - `"openai/gpt-5-mini"`

      - `"openai/gpt-5-nano"`

      - `""`

    - `rewrite_prompt: optional string`

  - `reranking: optional object { enabled, match_threshold, model }`

    - `enabled: optional boolean`

    - `match_threshold: optional number`

    - `model: optional "@cf/baai/bge-reranker-base" or ""`

      - `"@cf/baai/bge-reranker-base"`

      - `""`

  - `retrieval: optional object { boost_by, context_expansion, filters, 6 more }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Overrides the instance-level boost_by config. Direction defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `context_expansion: optional number`

    - `filters: optional map[unknown]`

    - `fusion_method: optional "max" or "rrf"`

      - `"max"`

      - `"rrf"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

    - `match_threshold: optional number`

    - `max_num_results: optional number`

    - `retrieval_type: optional "vector" or "keyword" or "hybrid"`

      - `"vector"`

      - `"keyword"`

      - `"hybrid"`

    - `return_on_failure: optional boolean`

- `messages: optional array of object { content, role }`

  - `content: string`

  - `role: "system" or "developer" or "user" or 2 more`

    - `"system"`

    - `"developer"`

    - `"user"`

    - `"assistant"`

    - `"tool"`

- `query: optional string`

  A simple text query string. Alternative to 'messages' — provide either this or 'messages', not both.

### Returns

- `result: object { chunks, search_query }`

  - `chunks: array of object { id, score, text, 3 more }`

    - `id: string`

    - `score: number`

    - `text: string`

    - `type: string`

    - `item: optional object { key, metadata, timestamp }`

      - `key: string`

      - `metadata: optional map[unknown]`

      - `timestamp: optional number`

    - `scoring_details: optional object { fusion_method, keyword_rank, keyword_score, 3 more }`

      - `fusion_method: optional "rrf" or "max"`

        - `"rrf"`

        - `"max"`

      - `keyword_rank: optional number`

      - `keyword_score: optional number`

      - `reranking_score: optional number`

      - `vector_rank: optional number`

      - `vector_score: optional number`

  - `search_query: string`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME/instances/$ID/search \
    -X POST \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": {
    "chunks": [
      {
        "id": "id",
        "score": 0,
        "text": "text",
        "type": "type",
        "item": {
          "key": "key",
          "metadata": {
            "foo": "bar"
          },
          "timestamp": 0
        },
        "scoring_details": {
          "fusion_method": "rrf",
          "keyword_rank": 0,
          "keyword_score": 0,
          "reranking_score": 0,
          "vector_rank": 0,
          "vector_score": 0
        }
      }
    ],
    "search_query": "search_query"
  },
  "success": true
}
```

## Chat Completions

**post** `/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/chat/completions`

Performs a chat completion request against an AI Search instance, using indexed content as context for generating responses.

### Path Parameters

- `account_id: string`

- `name: string`

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

### Body Parameters

- `messages: array of object { content, role }`

  - `content: string`

  - `role: "system" or "developer" or "user" or 2 more`

    - `"system"`

    - `"developer"`

    - `"user"`

    - `"assistant"`

    - `"tool"`

- `ai_search_options: optional object { cache, query_rewrite, reranking, retrieval }`

  - `cache: optional object { cache_threshold, enabled }`

    - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

      - `"super_strict_match"`

      - `"close_enough"`

      - `"flexible_friend"`

      - `"anything_goes"`

    - `enabled: optional boolean`

  - `query_rewrite: optional object { enabled, model, rewrite_prompt }`

    - `enabled: optional boolean`

    - `model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

      - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

      - `"@cf/zai-org/glm-4.7-flash"`

      - `"@cf/meta/llama-3.1-8b-instruct-fast"`

      - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

      - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

      - `"@cf/qwen/qwen3-30b-a3b-fp8"`

      - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

      - `"@cf/moonshotai/kimi-k2-instruct"`

      - `"@cf/google/gemma-3-12b-it"`

      - `"@cf/google/gemma-4-26b-a4b-it"`

      - `"@cf/moonshotai/kimi-k2.5"`

      - `"anthropic/claude-3-7-sonnet"`

      - `"anthropic/claude-sonnet-4"`

      - `"anthropic/claude-opus-4"`

      - `"anthropic/claude-3-5-haiku"`

      - `"cerebras/qwen-3-235b-a22b-instruct"`

      - `"cerebras/qwen-3-235b-a22b-thinking"`

      - `"cerebras/llama-3.3-70b"`

      - `"cerebras/llama-4-maverick-17b-128e-instruct"`

      - `"cerebras/llama-4-scout-17b-16e-instruct"`

      - `"cerebras/gpt-oss-120b"`

      - `"google-ai-studio/gemini-2.5-flash"`

      - `"google-ai-studio/gemini-2.5-pro"`

      - `"grok/grok-4"`

      - `"groq/llama-3.3-70b-versatile"`

      - `"groq/llama-3.1-8b-instant"`

      - `"openai/gpt-5"`

      - `"openai/gpt-5-mini"`

      - `"openai/gpt-5-nano"`

      - `""`

    - `rewrite_prompt: optional string`

  - `reranking: optional object { enabled, match_threshold, model }`

    - `enabled: optional boolean`

    - `match_threshold: optional number`

    - `model: optional "@cf/baai/bge-reranker-base" or ""`

      - `"@cf/baai/bge-reranker-base"`

      - `""`

  - `retrieval: optional object { boost_by, context_expansion, filters, 6 more }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Overrides the instance-level boost_by config. Direction defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `context_expansion: optional number`

    - `filters: optional map[unknown]`

    - `fusion_method: optional "max" or "rrf"`

      - `"max"`

      - `"rrf"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

    - `match_threshold: optional number`

    - `max_num_results: optional number`

    - `retrieval_type: optional "vector" or "keyword" or "hybrid"`

      - `"vector"`

      - `"keyword"`

      - `"hybrid"`

    - `return_on_failure: optional boolean`

- `model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

  - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

  - `"@cf/zai-org/glm-4.7-flash"`

  - `"@cf/meta/llama-3.1-8b-instruct-fast"`

  - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

  - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

  - `"@cf/qwen/qwen3-30b-a3b-fp8"`

  - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

  - `"@cf/moonshotai/kimi-k2-instruct"`

  - `"@cf/google/gemma-3-12b-it"`

  - `"@cf/google/gemma-4-26b-a4b-it"`

  - `"@cf/moonshotai/kimi-k2.5"`

  - `"anthropic/claude-3-7-sonnet"`

  - `"anthropic/claude-sonnet-4"`

  - `"anthropic/claude-opus-4"`

  - `"anthropic/claude-3-5-haiku"`

  - `"cerebras/qwen-3-235b-a22b-instruct"`

  - `"cerebras/qwen-3-235b-a22b-thinking"`

  - `"cerebras/llama-3.3-70b"`

  - `"cerebras/llama-4-maverick-17b-128e-instruct"`

  - `"cerebras/llama-4-scout-17b-16e-instruct"`

  - `"cerebras/gpt-oss-120b"`

  - `"google-ai-studio/gemini-2.5-flash"`

  - `"google-ai-studio/gemini-2.5-pro"`

  - `"grok/grok-4"`

  - `"groq/llama-3.3-70b-versatile"`

  - `"groq/llama-3.1-8b-instant"`

  - `"openai/gpt-5"`

  - `"openai/gpt-5-mini"`

  - `"openai/gpt-5-nano"`

  - `""`

- `stream: optional boolean`

### Returns

- `choices: array of object { message, index }`

  - `message: object { content, role }`

    - `content: string`

    - `role: "system" or "developer" or "user" or 2 more`

      - `"system"`

      - `"developer"`

      - `"user"`

      - `"assistant"`

      - `"tool"`

  - `index: optional number`

- `chunks: array of object { id, score, text, 3 more }`

  - `id: string`

  - `score: number`

  - `text: string`

  - `type: string`

  - `item: optional object { key, metadata, timestamp }`

    - `key: string`

    - `metadata: optional map[unknown]`

    - `timestamp: optional number`

  - `scoring_details: optional object { fusion_method, keyword_rank, keyword_score, 3 more }`

    - `fusion_method: optional "rrf" or "max"`

      - `"rrf"`

      - `"max"`

    - `keyword_rank: optional number`

    - `keyword_score: optional number`

    - `reranking_score: optional number`

    - `vector_rank: optional number`

    - `vector_score: optional number`

- `id: optional string`

- `model: optional string`

- `object: optional string`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME/instances/$ID/chat/completions \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
    -d '{
          "messages": [
            {
              "content": "content",
              "role": "system"
            }
          ]
        }'
```

#### Response

```json
{
  "choices": [
    {
      "message": {
        "content": "content",
        "role": "system"
      },
      "index": 0
    }
  ],
  "chunks": [
    {
      "id": "id",
      "score": 0,
      "text": "text",
      "type": "type",
      "item": {
        "key": "key",
        "metadata": {
          "foo": "bar"
        },
        "timestamp": 0
      },
      "scoring_details": {
        "fusion_method": "rrf",
        "keyword_rank": 0,
        "keyword_score": 0,
        "reranking_score": 0,
        "vector_rank": 0,
        "vector_score": 0
      }
    }
  ],
  "id": "id",
  "model": "model",
  "object": "object"
}
```

## Domain Types

### Instance List Response

- `InstanceListResponse object { id, created_at, modified_at, 36 more }`

  - `id: string`

    AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

  - `created_at: string`

  - `modified_at: string`

  - `ai_gateway_id: optional string`

  - `ai_search_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `cache: optional boolean`

  - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

    - `"super_strict_match"`

    - `"close_enough"`

    - `"flexible_friend"`

    - `"anything_goes"`

  - `cache_ttl: optional 600 or 1800 or 3600 or 7 more`

    Cache entry TTL in seconds. Allowed values: 600 (10min), 1800 (30min), 3600 (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d).

    - `600`

    - `1800`

    - `3600`

    - `7200`

    - `21600`

    - `43200`

    - `86400`

    - `172800`

    - `259200`

    - `518400`

  - `chunk_overlap: optional number`

  - `chunk_size: optional number`

  - `created_by: optional string`

  - `custom_metadata: optional array of object { data_type, field_name }`

    - `data_type: "text" or "number" or "boolean" or "datetime"`

      - `"text"`

      - `"number"`

      - `"boolean"`

      - `"datetime"`

    - `field_name: string`

  - `embedding_model: optional "@cf/qwen/qwen3-embedding-0.6b" or "@cf/baai/bge-m3" or "@cf/baai/bge-large-en-v1.5" or 6 more`

    - `"@cf/qwen/qwen3-embedding-0.6b"`

    - `"@cf/baai/bge-m3"`

    - `"@cf/baai/bge-large-en-v1.5"`

    - `"@cf/google/embeddinggemma-300m"`

    - `"google-ai-studio/gemini-embedding-001"`

    - `"google-ai-studio/gemini-embedding-2-preview"`

    - `"openai/text-embedding-3-small"`

    - `"openai/text-embedding-3-large"`

    - `""`

  - `enable: optional boolean`

  - `engine_version: optional number`

  - `fusion_method: optional "max" or "rrf"`

    - `"max"`

    - `"rrf"`

  - `hybrid_search_enabled: optional boolean`

    Deprecated — use index_method instead.

  - `index_method: optional object { keyword, vector }`

    Controls which storage backends are used during indexing. Defaults to vector-only.

    - `keyword: boolean`

      Enable keyword (BM25) storage backend.

    - `vector: boolean`

      Enable vector (embedding) storage backend.

  - `indexing_options: optional object { keyword_tokenizer }`

    - `keyword_tokenizer: optional "porter" or "trigram"`

      Tokenizer used for keyword search indexing. porter provides word-level tokenization with Porter stemming (good for natural language queries). trigram enables character-level substring matching (good for partial matches, code, identifiers). Changing this triggers a full re-index. Defaults to porter.

      - `"porter"`

      - `"trigram"`

  - `last_activity: optional string`

  - `max_num_results: optional number`

  - `metadata: optional object { created_from_aisearch_wizard, worker_domain }`

    - `created_from_aisearch_wizard: optional boolean`

    - `worker_domain: optional string`

  - `modified_by: optional string`

  - `namespace: optional string`

  - `paused: optional boolean`

  - `public_endpoint_id: optional string`

  - `public_endpoint_params: optional object { authorized_hosts, chat_completions_endpoint, enabled, 3 more }`

    - `authorized_hosts: optional array of string`

    - `chat_completions_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable chat completions endpoint for this public endpoint

    - `enabled: optional boolean`

    - `mcp: optional object { description, disabled }`

      - `description: optional string`

      - `disabled: optional boolean`

        Disable MCP endpoint for this public endpoint

    - `rate_limit: optional object { period_ms, requests, technique }`

      - `period_ms: optional number`

      - `requests: optional number`

      - `technique: optional "fixed" or "sliding"`

        - `"fixed"`

        - `"sliding"`

    - `search_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable search endpoint for this public endpoint

  - `reranking: optional boolean`

  - `reranking_model: optional "@cf/baai/bge-reranker-base" or ""`

    - `"@cf/baai/bge-reranker-base"`

    - `""`

  - `retrieval_options: optional object { boost_by, keyword_match_mode }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Each entry specifies a metadata field and an optional direction. Direction defaults to 'asc' for numeric/datetime fields and 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

  - `rewrite_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `rewrite_query: optional boolean`

  - `score_threshold: optional number`

  - `source: optional string`

  - `source_params: optional object { exclude_items, include_items, prefix, 2 more }`

    - `exclude_items: optional array of string`

      List of path patterns to exclude. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and /admin/settings/advanced)

    - `include_items: optional array of string`

      List of path patterns to include. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post)

    - `prefix: optional string`

    - `r2_jurisdiction: optional string`

    - `web_crawler: optional object { crawl_options, parse_options, parse_type, store_options }`

      - `crawl_options: optional object { depth, include_external_links, include_subdomains, 2 more }`

        - `depth: optional number`

        - `include_external_links: optional boolean`

        - `include_subdomains: optional boolean`

        - `max_age: optional number`

        - `source: optional "all" or "sitemaps" or "links"`

          - `"all"`

          - `"sitemaps"`

          - `"links"`

      - `parse_options: optional object { content_selector, include_headers, include_images, 2 more }`

        - `content_selector: optional array of object { path, selector }`

          List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first matching path wins. Only the matched HTML fragment is stored and indexed. Omit the field to disable content selection — empty arrays are rejected.

          - `path: string`

            Glob pattern to match against the page URL path. Uses standard glob syntax: * matches within a segment, ** crosses directories.

          - `selector: string`

            CSS selector to extract content from pages matching the path pattern. Must not contain disallowed characters (;, `, $, {, }, ). Must target a single element; if multiple elements match, the selector is ignored and the full page is used.

        - `include_headers: optional map[string]`

          Up to 5 custom HTTP headers sent with each crawl request. Names must be RFC-7230 token characters (no spaces, colons, or control characters); values must be HTAB + printable ASCII (no CR/LF).

        - `include_images: optional boolean`

        - `specific_sitemaps: optional array of string`

          List of specific sitemap URLs to use for crawling. Only valid when parse_type is 'sitemap'.

        - `use_browser_rendering: optional boolean`

      - `parse_type: optional "sitemap" or "feed-rss" or "crawl"`

        - `"sitemap"`

        - `"feed-rss"`

        - `"crawl"`

      - `store_options: optional object { storage_id, r2_jurisdiction, storage_type }`

        - `storage_id: string`

        - `r2_jurisdiction: optional string`

        - `storage_type: optional Provider`

          - `"r2"`

  - `status: optional string`

  - `sync_interval: optional 900 or 1800 or 3600 or 5 more`

    Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h).

    - `900`

    - `1800`

    - `3600`

    - `7200`

    - `14400`

    - `21600`

    - `43200`

    - `86400`

  - `token_id: optional string`

  - `type: optional "r2" or "web-crawler"`

    - `"r2"`

    - `"web-crawler"`

### Instance Create Response

- `InstanceCreateResponse object { id, created_at, modified_at, 36 more }`

  - `id: string`

    AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

  - `created_at: string`

  - `modified_at: string`

  - `ai_gateway_id: optional string`

  - `ai_search_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `cache: optional boolean`

  - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

    - `"super_strict_match"`

    - `"close_enough"`

    - `"flexible_friend"`

    - `"anything_goes"`

  - `cache_ttl: optional 600 or 1800 or 3600 or 7 more`

    Cache entry TTL in seconds. Allowed values: 600 (10min), 1800 (30min), 3600 (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d).

    - `600`

    - `1800`

    - `3600`

    - `7200`

    - `21600`

    - `43200`

    - `86400`

    - `172800`

    - `259200`

    - `518400`

  - `chunk_overlap: optional number`

  - `chunk_size: optional number`

  - `created_by: optional string`

  - `custom_metadata: optional array of object { data_type, field_name }`

    - `data_type: "text" or "number" or "boolean" or "datetime"`

      - `"text"`

      - `"number"`

      - `"boolean"`

      - `"datetime"`

    - `field_name: string`

  - `embedding_model: optional "@cf/qwen/qwen3-embedding-0.6b" or "@cf/baai/bge-m3" or "@cf/baai/bge-large-en-v1.5" or 6 more`

    - `"@cf/qwen/qwen3-embedding-0.6b"`

    - `"@cf/baai/bge-m3"`

    - `"@cf/baai/bge-large-en-v1.5"`

    - `"@cf/google/embeddinggemma-300m"`

    - `"google-ai-studio/gemini-embedding-001"`

    - `"google-ai-studio/gemini-embedding-2-preview"`

    - `"openai/text-embedding-3-small"`

    - `"openai/text-embedding-3-large"`

    - `""`

  - `enable: optional boolean`

  - `engine_version: optional number`

  - `fusion_method: optional "max" or "rrf"`

    - `"max"`

    - `"rrf"`

  - `hybrid_search_enabled: optional boolean`

    Deprecated — use index_method instead.

  - `index_method: optional object { keyword, vector }`

    Controls which storage backends are used during indexing. Defaults to vector-only.

    - `keyword: boolean`

      Enable keyword (BM25) storage backend.

    - `vector: boolean`

      Enable vector (embedding) storage backend.

  - `indexing_options: optional object { keyword_tokenizer }`

    - `keyword_tokenizer: optional "porter" or "trigram"`

      Tokenizer used for keyword search indexing. porter provides word-level tokenization with Porter stemming (good for natural language queries). trigram enables character-level substring matching (good for partial matches, code, identifiers). Changing this triggers a full re-index. Defaults to porter.

      - `"porter"`

      - `"trigram"`

  - `last_activity: optional string`

  - `max_num_results: optional number`

  - `metadata: optional object { created_from_aisearch_wizard, worker_domain }`

    - `created_from_aisearch_wizard: optional boolean`

    - `worker_domain: optional string`

  - `modified_by: optional string`

  - `namespace: optional string`

  - `paused: optional boolean`

  - `public_endpoint_id: optional string`

  - `public_endpoint_params: optional object { authorized_hosts, chat_completions_endpoint, enabled, 3 more }`

    - `authorized_hosts: optional array of string`

    - `chat_completions_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable chat completions endpoint for this public endpoint

    - `enabled: optional boolean`

    - `mcp: optional object { description, disabled }`

      - `description: optional string`

      - `disabled: optional boolean`

        Disable MCP endpoint for this public endpoint

    - `rate_limit: optional object { period_ms, requests, technique }`

      - `period_ms: optional number`

      - `requests: optional number`

      - `technique: optional "fixed" or "sliding"`

        - `"fixed"`

        - `"sliding"`

    - `search_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable search endpoint for this public endpoint

  - `reranking: optional boolean`

  - `reranking_model: optional "@cf/baai/bge-reranker-base" or ""`

    - `"@cf/baai/bge-reranker-base"`

    - `""`

  - `retrieval_options: optional object { boost_by, keyword_match_mode }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Each entry specifies a metadata field and an optional direction. Direction defaults to 'asc' for numeric/datetime fields and 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

  - `rewrite_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `rewrite_query: optional boolean`

  - `score_threshold: optional number`

  - `source: optional string`

  - `source_params: optional object { exclude_items, include_items, prefix, 2 more }`

    - `exclude_items: optional array of string`

      List of path patterns to exclude. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and /admin/settings/advanced)

    - `include_items: optional array of string`

      List of path patterns to include. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post)

    - `prefix: optional string`

    - `r2_jurisdiction: optional string`

    - `web_crawler: optional object { crawl_options, parse_options, parse_type, store_options }`

      - `crawl_options: optional object { depth, include_external_links, include_subdomains, 2 more }`

        - `depth: optional number`

        - `include_external_links: optional boolean`

        - `include_subdomains: optional boolean`

        - `max_age: optional number`

        - `source: optional "all" or "sitemaps" or "links"`

          - `"all"`

          - `"sitemaps"`

          - `"links"`

      - `parse_options: optional object { content_selector, include_headers, include_images, 2 more }`

        - `content_selector: optional array of object { path, selector }`

          List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first matching path wins. Only the matched HTML fragment is stored and indexed. Omit the field to disable content selection — empty arrays are rejected.

          - `path: string`

            Glob pattern to match against the page URL path. Uses standard glob syntax: * matches within a segment, ** crosses directories.

          - `selector: string`

            CSS selector to extract content from pages matching the path pattern. Must not contain disallowed characters (;, `, $, {, }, ). Must target a single element; if multiple elements match, the selector is ignored and the full page is used.

        - `include_headers: optional map[string]`

          Up to 5 custom HTTP headers sent with each crawl request. Names must be RFC-7230 token characters (no spaces, colons, or control characters); values must be HTAB + printable ASCII (no CR/LF).

        - `include_images: optional boolean`

        - `specific_sitemaps: optional array of string`

          List of specific sitemap URLs to use for crawling. Only valid when parse_type is 'sitemap'.

        - `use_browser_rendering: optional boolean`

      - `parse_type: optional "sitemap" or "feed-rss" or "crawl"`

        - `"sitemap"`

        - `"feed-rss"`

        - `"crawl"`

      - `store_options: optional object { storage_id, r2_jurisdiction, storage_type }`

        - `storage_id: string`

        - `r2_jurisdiction: optional string`

        - `storage_type: optional Provider`

          - `"r2"`

  - `status: optional string`

  - `sync_interval: optional 900 or 1800 or 3600 or 5 more`

    Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h).

    - `900`

    - `1800`

    - `3600`

    - `7200`

    - `14400`

    - `21600`

    - `43200`

    - `86400`

  - `token_id: optional string`

  - `type: optional "r2" or "web-crawler"`

    - `"r2"`

    - `"web-crawler"`

### Instance Read Response

- `InstanceReadResponse object { id, created_at, modified_at, 36 more }`

  - `id: string`

    AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

  - `created_at: string`

  - `modified_at: string`

  - `ai_gateway_id: optional string`

  - `ai_search_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `cache: optional boolean`

  - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

    - `"super_strict_match"`

    - `"close_enough"`

    - `"flexible_friend"`

    - `"anything_goes"`

  - `cache_ttl: optional 600 or 1800 or 3600 or 7 more`

    Cache entry TTL in seconds. Allowed values: 600 (10min), 1800 (30min), 3600 (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d).

    - `600`

    - `1800`

    - `3600`

    - `7200`

    - `21600`

    - `43200`

    - `86400`

    - `172800`

    - `259200`

    - `518400`

  - `chunk_overlap: optional number`

  - `chunk_size: optional number`

  - `created_by: optional string`

  - `custom_metadata: optional array of object { data_type, field_name }`

    - `data_type: "text" or "number" or "boolean" or "datetime"`

      - `"text"`

      - `"number"`

      - `"boolean"`

      - `"datetime"`

    - `field_name: string`

  - `embedding_model: optional "@cf/qwen/qwen3-embedding-0.6b" or "@cf/baai/bge-m3" or "@cf/baai/bge-large-en-v1.5" or 6 more`

    - `"@cf/qwen/qwen3-embedding-0.6b"`

    - `"@cf/baai/bge-m3"`

    - `"@cf/baai/bge-large-en-v1.5"`

    - `"@cf/google/embeddinggemma-300m"`

    - `"google-ai-studio/gemini-embedding-001"`

    - `"google-ai-studio/gemini-embedding-2-preview"`

    - `"openai/text-embedding-3-small"`

    - `"openai/text-embedding-3-large"`

    - `""`

  - `enable: optional boolean`

  - `engine_version: optional number`

  - `fusion_method: optional "max" or "rrf"`

    - `"max"`

    - `"rrf"`

  - `hybrid_search_enabled: optional boolean`

    Deprecated — use index_method instead.

  - `index_method: optional object { keyword, vector }`

    Controls which storage backends are used during indexing. Defaults to vector-only.

    - `keyword: boolean`

      Enable keyword (BM25) storage backend.

    - `vector: boolean`

      Enable vector (embedding) storage backend.

  - `indexing_options: optional object { keyword_tokenizer }`

    - `keyword_tokenizer: optional "porter" or "trigram"`

      Tokenizer used for keyword search indexing. porter provides word-level tokenization with Porter stemming (good for natural language queries). trigram enables character-level substring matching (good for partial matches, code, identifiers). Changing this triggers a full re-index. Defaults to porter.

      - `"porter"`

      - `"trigram"`

  - `last_activity: optional string`

  - `max_num_results: optional number`

  - `metadata: optional object { created_from_aisearch_wizard, worker_domain }`

    - `created_from_aisearch_wizard: optional boolean`

    - `worker_domain: optional string`

  - `modified_by: optional string`

  - `namespace: optional string`

  - `paused: optional boolean`

  - `public_endpoint_id: optional string`

  - `public_endpoint_params: optional object { authorized_hosts, chat_completions_endpoint, enabled, 3 more }`

    - `authorized_hosts: optional array of string`

    - `chat_completions_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable chat completions endpoint for this public endpoint

    - `enabled: optional boolean`

    - `mcp: optional object { description, disabled }`

      - `description: optional string`

      - `disabled: optional boolean`

        Disable MCP endpoint for this public endpoint

    - `rate_limit: optional object { period_ms, requests, technique }`

      - `period_ms: optional number`

      - `requests: optional number`

      - `technique: optional "fixed" or "sliding"`

        - `"fixed"`

        - `"sliding"`

    - `search_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable search endpoint for this public endpoint

  - `reranking: optional boolean`

  - `reranking_model: optional "@cf/baai/bge-reranker-base" or ""`

    - `"@cf/baai/bge-reranker-base"`

    - `""`

  - `retrieval_options: optional object { boost_by, keyword_match_mode }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Each entry specifies a metadata field and an optional direction. Direction defaults to 'asc' for numeric/datetime fields and 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

  - `rewrite_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `rewrite_query: optional boolean`

  - `score_threshold: optional number`

  - `source: optional string`

  - `source_params: optional object { exclude_items, include_items, prefix, 2 more }`

    - `exclude_items: optional array of string`

      List of path patterns to exclude. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and /admin/settings/advanced)

    - `include_items: optional array of string`

      List of path patterns to include. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post)

    - `prefix: optional string`

    - `r2_jurisdiction: optional string`

    - `web_crawler: optional object { crawl_options, parse_options, parse_type, store_options }`

      - `crawl_options: optional object { depth, include_external_links, include_subdomains, 2 more }`

        - `depth: optional number`

        - `include_external_links: optional boolean`

        - `include_subdomains: optional boolean`

        - `max_age: optional number`

        - `source: optional "all" or "sitemaps" or "links"`

          - `"all"`

          - `"sitemaps"`

          - `"links"`

      - `parse_options: optional object { content_selector, include_headers, include_images, 2 more }`

        - `content_selector: optional array of object { path, selector }`

          List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first matching path wins. Only the matched HTML fragment is stored and indexed. Omit the field to disable content selection — empty arrays are rejected.

          - `path: string`

            Glob pattern to match against the page URL path. Uses standard glob syntax: * matches within a segment, ** crosses directories.

          - `selector: string`

            CSS selector to extract content from pages matching the path pattern. Must not contain disallowed characters (;, `, $, {, }, ). Must target a single element; if multiple elements match, the selector is ignored and the full page is used.

        - `include_headers: optional map[string]`

          Up to 5 custom HTTP headers sent with each crawl request. Names must be RFC-7230 token characters (no spaces, colons, or control characters); values must be HTAB + printable ASCII (no CR/LF).

        - `include_images: optional boolean`

        - `specific_sitemaps: optional array of string`

          List of specific sitemap URLs to use for crawling. Only valid when parse_type is 'sitemap'.

        - `use_browser_rendering: optional boolean`

      - `parse_type: optional "sitemap" or "feed-rss" or "crawl"`

        - `"sitemap"`

        - `"feed-rss"`

        - `"crawl"`

      - `store_options: optional object { storage_id, r2_jurisdiction, storage_type }`

        - `storage_id: string`

        - `r2_jurisdiction: optional string`

        - `storage_type: optional Provider`

          - `"r2"`

  - `status: optional string`

  - `sync_interval: optional 900 or 1800 or 3600 or 5 more`

    Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h).

    - `900`

    - `1800`

    - `3600`

    - `7200`

    - `14400`

    - `21600`

    - `43200`

    - `86400`

  - `token_id: optional string`

  - `type: optional "r2" or "web-crawler"`

    - `"r2"`

    - `"web-crawler"`

### Instance Update Response

- `InstanceUpdateResponse object { id, created_at, modified_at, 36 more }`

  - `id: string`

    AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

  - `created_at: string`

  - `modified_at: string`

  - `ai_gateway_id: optional string`

  - `ai_search_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `cache: optional boolean`

  - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

    - `"super_strict_match"`

    - `"close_enough"`

    - `"flexible_friend"`

    - `"anything_goes"`

  - `cache_ttl: optional 600 or 1800 or 3600 or 7 more`

    Cache entry TTL in seconds. Allowed values: 600 (10min), 1800 (30min), 3600 (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d).

    - `600`

    - `1800`

    - `3600`

    - `7200`

    - `21600`

    - `43200`

    - `86400`

    - `172800`

    - `259200`

    - `518400`

  - `chunk_overlap: optional number`

  - `chunk_size: optional number`

  - `created_by: optional string`

  - `custom_metadata: optional array of object { data_type, field_name }`

    - `data_type: "text" or "number" or "boolean" or "datetime"`

      - `"text"`

      - `"number"`

      - `"boolean"`

      - `"datetime"`

    - `field_name: string`

  - `embedding_model: optional "@cf/qwen/qwen3-embedding-0.6b" or "@cf/baai/bge-m3" or "@cf/baai/bge-large-en-v1.5" or 6 more`

    - `"@cf/qwen/qwen3-embedding-0.6b"`

    - `"@cf/baai/bge-m3"`

    - `"@cf/baai/bge-large-en-v1.5"`

    - `"@cf/google/embeddinggemma-300m"`

    - `"google-ai-studio/gemini-embedding-001"`

    - `"google-ai-studio/gemini-embedding-2-preview"`

    - `"openai/text-embedding-3-small"`

    - `"openai/text-embedding-3-large"`

    - `""`

  - `enable: optional boolean`

  - `engine_version: optional number`

  - `fusion_method: optional "max" or "rrf"`

    - `"max"`

    - `"rrf"`

  - `hybrid_search_enabled: optional boolean`

    Deprecated — use index_method instead.

  - `index_method: optional object { keyword, vector }`

    Controls which storage backends are used during indexing. Defaults to vector-only.

    - `keyword: boolean`

      Enable keyword (BM25) storage backend.

    - `vector: boolean`

      Enable vector (embedding) storage backend.

  - `indexing_options: optional object { keyword_tokenizer }`

    - `keyword_tokenizer: optional "porter" or "trigram"`

      Tokenizer used for keyword search indexing. porter provides word-level tokenization with Porter stemming (good for natural language queries). trigram enables character-level substring matching (good for partial matches, code, identifiers). Changing this triggers a full re-index. Defaults to porter.

      - `"porter"`

      - `"trigram"`

  - `last_activity: optional string`

  - `max_num_results: optional number`

  - `metadata: optional object { created_from_aisearch_wizard, worker_domain }`

    - `created_from_aisearch_wizard: optional boolean`

    - `worker_domain: optional string`

  - `modified_by: optional string`

  - `namespace: optional string`

  - `paused: optional boolean`

  - `public_endpoint_id: optional string`

  - `public_endpoint_params: optional object { authorized_hosts, chat_completions_endpoint, enabled, 3 more }`

    - `authorized_hosts: optional array of string`

    - `chat_completions_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable chat completions endpoint for this public endpoint

    - `enabled: optional boolean`

    - `mcp: optional object { description, disabled }`

      - `description: optional string`

      - `disabled: optional boolean`

        Disable MCP endpoint for this public endpoint

    - `rate_limit: optional object { period_ms, requests, technique }`

      - `period_ms: optional number`

      - `requests: optional number`

      - `technique: optional "fixed" or "sliding"`

        - `"fixed"`

        - `"sliding"`

    - `search_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable search endpoint for this public endpoint

  - `reranking: optional boolean`

  - `reranking_model: optional "@cf/baai/bge-reranker-base" or ""`

    - `"@cf/baai/bge-reranker-base"`

    - `""`

  - `retrieval_options: optional object { boost_by, keyword_match_mode }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Each entry specifies a metadata field and an optional direction. Direction defaults to 'asc' for numeric/datetime fields and 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

  - `rewrite_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `rewrite_query: optional boolean`

  - `score_threshold: optional number`

  - `source: optional string`

  - `source_params: optional object { exclude_items, include_items, prefix, 2 more }`

    - `exclude_items: optional array of string`

      List of path patterns to exclude. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and /admin/settings/advanced)

    - `include_items: optional array of string`

      List of path patterns to include. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post)

    - `prefix: optional string`

    - `r2_jurisdiction: optional string`

    - `web_crawler: optional object { crawl_options, parse_options, parse_type, store_options }`

      - `crawl_options: optional object { depth, include_external_links, include_subdomains, 2 more }`

        - `depth: optional number`

        - `include_external_links: optional boolean`

        - `include_subdomains: optional boolean`

        - `max_age: optional number`

        - `source: optional "all" or "sitemaps" or "links"`

          - `"all"`

          - `"sitemaps"`

          - `"links"`

      - `parse_options: optional object { content_selector, include_headers, include_images, 2 more }`

        - `content_selector: optional array of object { path, selector }`

          List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first matching path wins. Only the matched HTML fragment is stored and indexed. Omit the field to disable content selection — empty arrays are rejected.

          - `path: string`

            Glob pattern to match against the page URL path. Uses standard glob syntax: * matches within a segment, ** crosses directories.

          - `selector: string`

            CSS selector to extract content from pages matching the path pattern. Must not contain disallowed characters (;, `, $, {, }, ). Must target a single element; if multiple elements match, the selector is ignored and the full page is used.

        - `include_headers: optional map[string]`

          Up to 5 custom HTTP headers sent with each crawl request. Names must be RFC-7230 token characters (no spaces, colons, or control characters); values must be HTAB + printable ASCII (no CR/LF).

        - `include_images: optional boolean`

        - `specific_sitemaps: optional array of string`

          List of specific sitemap URLs to use for crawling. Only valid when parse_type is 'sitemap'.

        - `use_browser_rendering: optional boolean`

      - `parse_type: optional "sitemap" or "feed-rss" or "crawl"`

        - `"sitemap"`

        - `"feed-rss"`

        - `"crawl"`

      - `store_options: optional object { storage_id, r2_jurisdiction, storage_type }`

        - `storage_id: string`

        - `r2_jurisdiction: optional string`

        - `storage_type: optional Provider`

          - `"r2"`

  - `status: optional string`

  - `sync_interval: optional 900 or 1800 or 3600 or 5 more`

    Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h).

    - `900`

    - `1800`

    - `3600`

    - `7200`

    - `14400`

    - `21600`

    - `43200`

    - `86400`

  - `token_id: optional string`

  - `type: optional "r2" or "web-crawler"`

    - `"r2"`

    - `"web-crawler"`

### Instance Delete Response

- `InstanceDeleteResponse object { id, created_at, modified_at, 36 more }`

  - `id: string`

    AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

  - `created_at: string`

  - `modified_at: string`

  - `ai_gateway_id: optional string`

  - `ai_search_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `cache: optional boolean`

  - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

    - `"super_strict_match"`

    - `"close_enough"`

    - `"flexible_friend"`

    - `"anything_goes"`

  - `cache_ttl: optional 600 or 1800 or 3600 or 7 more`

    Cache entry TTL in seconds. Allowed values: 600 (10min), 1800 (30min), 3600 (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d).

    - `600`

    - `1800`

    - `3600`

    - `7200`

    - `21600`

    - `43200`

    - `86400`

    - `172800`

    - `259200`

    - `518400`

  - `chunk_overlap: optional number`

  - `chunk_size: optional number`

  - `created_by: optional string`

  - `custom_metadata: optional array of object { data_type, field_name }`

    - `data_type: "text" or "number" or "boolean" or "datetime"`

      - `"text"`

      - `"number"`

      - `"boolean"`

      - `"datetime"`

    - `field_name: string`

  - `embedding_model: optional "@cf/qwen/qwen3-embedding-0.6b" or "@cf/baai/bge-m3" or "@cf/baai/bge-large-en-v1.5" or 6 more`

    - `"@cf/qwen/qwen3-embedding-0.6b"`

    - `"@cf/baai/bge-m3"`

    - `"@cf/baai/bge-large-en-v1.5"`

    - `"@cf/google/embeddinggemma-300m"`

    - `"google-ai-studio/gemini-embedding-001"`

    - `"google-ai-studio/gemini-embedding-2-preview"`

    - `"openai/text-embedding-3-small"`

    - `"openai/text-embedding-3-large"`

    - `""`

  - `enable: optional boolean`

  - `engine_version: optional number`

  - `fusion_method: optional "max" or "rrf"`

    - `"max"`

    - `"rrf"`

  - `hybrid_search_enabled: optional boolean`

    Deprecated — use index_method instead.

  - `index_method: optional object { keyword, vector }`

    Controls which storage backends are used during indexing. Defaults to vector-only.

    - `keyword: boolean`

      Enable keyword (BM25) storage backend.

    - `vector: boolean`

      Enable vector (embedding) storage backend.

  - `indexing_options: optional object { keyword_tokenizer }`

    - `keyword_tokenizer: optional "porter" or "trigram"`

      Tokenizer used for keyword search indexing. porter provides word-level tokenization with Porter stemming (good for natural language queries). trigram enables character-level substring matching (good for partial matches, code, identifiers). Changing this triggers a full re-index. Defaults to porter.

      - `"porter"`

      - `"trigram"`

  - `last_activity: optional string`

  - `max_num_results: optional number`

  - `metadata: optional object { created_from_aisearch_wizard, worker_domain }`

    - `created_from_aisearch_wizard: optional boolean`

    - `worker_domain: optional string`

  - `modified_by: optional string`

  - `namespace: optional string`

  - `paused: optional boolean`

  - `public_endpoint_id: optional string`

  - `public_endpoint_params: optional object { authorized_hosts, chat_completions_endpoint, enabled, 3 more }`

    - `authorized_hosts: optional array of string`

    - `chat_completions_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable chat completions endpoint for this public endpoint

    - `enabled: optional boolean`

    - `mcp: optional object { description, disabled }`

      - `description: optional string`

      - `disabled: optional boolean`

        Disable MCP endpoint for this public endpoint

    - `rate_limit: optional object { period_ms, requests, technique }`

      - `period_ms: optional number`

      - `requests: optional number`

      - `technique: optional "fixed" or "sliding"`

        - `"fixed"`

        - `"sliding"`

    - `search_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable search endpoint for this public endpoint

  - `reranking: optional boolean`

  - `reranking_model: optional "@cf/baai/bge-reranker-base" or ""`

    - `"@cf/baai/bge-reranker-base"`

    - `""`

  - `retrieval_options: optional object { boost_by, keyword_match_mode }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Each entry specifies a metadata field and an optional direction. Direction defaults to 'asc' for numeric/datetime fields and 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

  - `rewrite_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `rewrite_query: optional boolean`

  - `score_threshold: optional number`

  - `source: optional string`

  - `source_params: optional object { exclude_items, include_items, prefix, 2 more }`

    - `exclude_items: optional array of string`

      List of path patterns to exclude. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and /admin/settings/advanced)

    - `include_items: optional array of string`

      List of path patterns to include. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post)

    - `prefix: optional string`

    - `r2_jurisdiction: optional string`

    - `web_crawler: optional object { crawl_options, parse_options, parse_type, store_options }`

      - `crawl_options: optional object { depth, include_external_links, include_subdomains, 2 more }`

        - `depth: optional number`

        - `include_external_links: optional boolean`

        - `include_subdomains: optional boolean`

        - `max_age: optional number`

        - `source: optional "all" or "sitemaps" or "links"`

          - `"all"`

          - `"sitemaps"`

          - `"links"`

      - `parse_options: optional object { content_selector, include_headers, include_images, 2 more }`

        - `content_selector: optional array of object { path, selector }`

          List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first matching path wins. Only the matched HTML fragment is stored and indexed. Omit the field to disable content selection — empty arrays are rejected.

          - `path: string`

            Glob pattern to match against the page URL path. Uses standard glob syntax: * matches within a segment, ** crosses directories.

          - `selector: string`

            CSS selector to extract content from pages matching the path pattern. Must not contain disallowed characters (;, `, $, {, }, ). Must target a single element; if multiple elements match, the selector is ignored and the full page is used.

        - `include_headers: optional map[string]`

          Up to 5 custom HTTP headers sent with each crawl request. Names must be RFC-7230 token characters (no spaces, colons, or control characters); values must be HTAB + printable ASCII (no CR/LF).

        - `include_images: optional boolean`

        - `specific_sitemaps: optional array of string`

          List of specific sitemap URLs to use for crawling. Only valid when parse_type is 'sitemap'.

        - `use_browser_rendering: optional boolean`

      - `parse_type: optional "sitemap" or "feed-rss" or "crawl"`

        - `"sitemap"`

        - `"feed-rss"`

        - `"crawl"`

      - `store_options: optional object { storage_id, r2_jurisdiction, storage_type }`

        - `storage_id: string`

        - `r2_jurisdiction: optional string`

        - `storage_type: optional Provider`

          - `"r2"`

  - `status: optional string`

  - `sync_interval: optional 900 or 1800 or 3600 or 5 more`

    Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h).

    - `900`

    - `1800`

    - `3600`

    - `7200`

    - `14400`

    - `21600`

    - `43200`

    - `86400`

  - `token_id: optional string`

  - `type: optional "r2" or "web-crawler"`

    - `"r2"`

    - `"web-crawler"`

### Instance Stats Response

- `InstanceStatsResponse object { completed, degraded, engine, 8 more }`

  - `completed: optional number`

  - `degraded: optional boolean`

    True when status counts are unavailable (e.g. legacy stats query exceeded D1 statement-size limit). Counts are omitted in this case.

  - `engine: optional object { r2, vectorize }`

    Engine-specific metadata. Present only for managed (v3) instances.

    - `r2: optional object { metadataSizeBytes, objectCount, payloadSizeBytes }`

      R2 bucket storage usage in bytes.

      - `metadataSizeBytes: number`

      - `objectCount: number`

      - `payloadSizeBytes: number`

    - `vectorize: optional object { dimensions, vectorsCount }`

      Vectorize index metadata (dimensions, vector count).

      - `dimensions: number`

      - `vectorsCount: number`

  - `error: optional number`

  - `file_embed_errors: optional map[unknown]`

  - `index_source_errors: optional map[unknown]`

  - `last_activity: optional string`

  - `outdated: optional number`

  - `queued: optional number`

  - `running: optional number`

  - `skipped: optional number`

### Instance Search Response

- `InstanceSearchResponse object { chunks, search_query }`

  - `chunks: array of object { id, score, text, 3 more }`

    - `id: string`

    - `score: number`

    - `text: string`

    - `type: string`

    - `item: optional object { key, metadata, timestamp }`

      - `key: string`

      - `metadata: optional map[unknown]`

      - `timestamp: optional number`

    - `scoring_details: optional object { fusion_method, keyword_rank, keyword_score, 3 more }`

      - `fusion_method: optional "rrf" or "max"`

        - `"rrf"`

        - `"max"`

      - `keyword_rank: optional number`

      - `keyword_score: optional number`

      - `reranking_score: optional number`

      - `vector_rank: optional number`

      - `vector_score: optional number`

  - `search_query: string`

### Instance Chat Completions Response

- `InstanceChatCompletionsResponse object { choices, chunks, id, 2 more }`

  - `choices: array of object { message, index }`

    - `message: object { content, role }`

      - `content: string`

      - `role: "system" or "developer" or "user" or 2 more`

        - `"system"`

        - `"developer"`

        - `"user"`

        - `"assistant"`

        - `"tool"`

    - `index: optional number`

  - `chunks: array of object { id, score, text, 3 more }`

    - `id: string`

    - `score: number`

    - `text: string`

    - `type: string`

    - `item: optional object { key, metadata, timestamp }`

      - `key: string`

      - `metadata: optional map[unknown]`

      - `timestamp: optional number`

    - `scoring_details: optional object { fusion_method, keyword_rank, keyword_score, 3 more }`

      - `fusion_method: optional "rrf" or "max"`

        - `"rrf"`

        - `"max"`

      - `keyword_rank: optional number`

      - `keyword_score: optional number`

      - `reranking_score: optional number`

      - `vector_rank: optional number`

      - `vector_score: optional number`

  - `id: optional string`

  - `model: optional string`

  - `object: optional string`

# Jobs

## List Jobs

**get** `/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/jobs`

Lists indexing jobs for an AI Search instance.

### Path Parameters

- `account_id: string`

- `name: string`

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

### Query Parameters

- `page: optional number`

- `per_page: optional number`

### Returns

- `result: array of object { id, source, description, 4 more }`

  - `id: string`

  - `source: "user" or "schedule"`

    - `"user"`

    - `"schedule"`

  - `description: optional string`

  - `end_reason: optional string`

  - `ended_at: optional string`

  - `last_seen_at: optional string`

  - `started_at: optional string`

- `result_info: object { count, page, per_page, total_count }`

  - `count: number`

  - `page: number`

  - `per_page: number`

  - `total_count: number`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME/instances/$ID/jobs \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": [
    {
      "id": "id",
      "source": "user",
      "description": "description",
      "end_reason": "end_reason",
      "ended_at": "ended_at",
      "last_seen_at": "last_seen_at",
      "started_at": "started_at"
    }
  ],
  "result_info": {
    "count": 0,
    "page": 0,
    "per_page": 0,
    "total_count": 0
  },
  "success": true
}
```

## Create new job

**post** `/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/jobs`

Creates a new indexing job for an AI Search instance.

### Path Parameters

- `account_id: string`

- `name: string`

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

### Body Parameters

- `description: optional string`

### Returns

- `result: object { id, source, description, 4 more }`

  - `id: string`

  - `source: "user" or "schedule"`

    - `"user"`

    - `"schedule"`

  - `description: optional string`

  - `end_reason: optional string`

  - `ended_at: optional string`

  - `last_seen_at: optional string`

  - `started_at: optional string`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME/instances/$ID/jobs \
    -X POST \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": {
    "id": "id",
    "source": "user",
    "description": "description",
    "end_reason": "end_reason",
    "ended_at": "ended_at",
    "last_seen_at": "last_seen_at",
    "started_at": "started_at"
  },
  "success": true
}
```

## Get a Job Details

**get** `/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/jobs/{job_id}`

Retrieves details for a specific AI Search indexing job.

### Path Parameters

- `account_id: string`

- `name: string`

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

- `job_id: string`

### Returns

- `result: object { id, source, description, 4 more }`

  - `id: string`

  - `source: "user" or "schedule"`

    - `"user"`

    - `"schedule"`

  - `description: optional string`

  - `end_reason: optional string`

  - `ended_at: optional string`

  - `last_seen_at: optional string`

  - `started_at: optional string`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME/instances/$ID/jobs/$JOB_ID \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": {
    "id": "id",
    "source": "user",
    "description": "description",
    "end_reason": "end_reason",
    "ended_at": "ended_at",
    "last_seen_at": "last_seen_at",
    "started_at": "started_at"
  },
  "success": true
}
```

## Change Job Status

**patch** `/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/jobs/{job_id}`

Updates the status of an AI Search indexing job.

### Path Parameters

- `account_id: string`

- `name: string`

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

- `job_id: string`

### Body Parameters

- `action: "cancel"`

  - `"cancel"`

### Returns

- `result: object { id, source, description, 4 more }`

  - `id: string`

  - `source: "user" or "schedule"`

    - `"user"`

    - `"schedule"`

  - `description: optional string`

  - `end_reason: optional string`

  - `ended_at: optional string`

  - `last_seen_at: optional string`

  - `started_at: optional string`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME/instances/$ID/jobs/$JOB_ID \
    -X PATCH \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
    -d '{
          "action": "cancel"
        }'
```

#### Response

```json
{
  "result": {
    "id": "id",
    "source": "user",
    "description": "description",
    "end_reason": "end_reason",
    "ended_at": "ended_at",
    "last_seen_at": "last_seen_at",
    "started_at": "started_at"
  },
  "success": true
}
```

## List Job Logs

**get** `/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/jobs/{job_id}/logs`

Lists log entries for an AI Search indexing job.

### Path Parameters

- `account_id: string`

- `name: string`

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

- `job_id: string`

### Query Parameters

- `page: optional number`

- `per_page: optional number`

### Returns

- `result: array of object { id, created_at, message, message_type }`

  - `id: number`

  - `created_at: number`

  - `message: string`

  - `message_type: number`

- `result_info: object { count, page, per_page, total_count }`

  - `count: number`

  - `page: number`

  - `per_page: number`

  - `total_count: number`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME/instances/$ID/jobs/$JOB_ID/logs \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": [
    {
      "id": 0,
      "created_at": 0,
      "message": "message",
      "message_type": 0
    }
  ],
  "result_info": {
    "count": 0,
    "page": 0,
    "per_page": 0,
    "total_count": 0
  },
  "success": true
}
```

## Domain Types

### Job List Response

- `JobListResponse object { id, source, description, 4 more }`

  - `id: string`

  - `source: "user" or "schedule"`

    - `"user"`

    - `"schedule"`

  - `description: optional string`

  - `end_reason: optional string`

  - `ended_at: optional string`

  - `last_seen_at: optional string`

  - `started_at: optional string`

### Job Create Response

- `JobCreateResponse object { id, source, description, 4 more }`

  - `id: string`

  - `source: "user" or "schedule"`

    - `"user"`

    - `"schedule"`

  - `description: optional string`

  - `end_reason: optional string`

  - `ended_at: optional string`

  - `last_seen_at: optional string`

  - `started_at: optional string`

### Job Get Response

- `JobGetResponse object { id, source, description, 4 more }`

  - `id: string`

  - `source: "user" or "schedule"`

    - `"user"`

    - `"schedule"`

  - `description: optional string`

  - `end_reason: optional string`

  - `ended_at: optional string`

  - `last_seen_at: optional string`

  - `started_at: optional string`

### Job Update Response

- `JobUpdateResponse object { id, source, description, 4 more }`

  - `id: string`

  - `source: "user" or "schedule"`

    - `"user"`

    - `"schedule"`

  - `description: optional string`

  - `end_reason: optional string`

  - `ended_at: optional string`

  - `last_seen_at: optional string`

  - `started_at: optional string`

### Job Logs Response

- `JobLogsResponse = array of object { id, created_at, message, message_type }`

  - `id: number`

  - `created_at: number`

  - `message: string`

  - `message_type: number`

# Items

## Items List.

**get** `/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items`

Lists indexed items in an AI Search instance.

### Path Parameters

- `account_id: string`

- `name: string`

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

### Query Parameters

- `item_id: optional string`

  Filter items by their unique ID. Returns at most one item.

- `metadata_filter: optional string`

  JSON-encoded metadata filter using Vectorize filter syntax. Examples: {"folder":"reports/"}, {"timestamp":{"$gte":1700000000000}}, {"folder":{"$in":["docs/","reports/"]}}

- `page: optional number`

- `per_page: optional number`

- `search: optional string`

- `sort_by: optional "status" or "modified_at"`

  Sort order for items. "status" (default) sorts by status priority then last_seen_at. "modified_at" sorts by file modification time (most recent first), falling back to created_at.

  - `"status"`

  - `"modified_at"`

- `source: optional string`

  Filter items by source_id. Use "builtin" for uploaded files, or a source identifier like "web-crawler:https://example.com".

- `status: optional "queued" or "running" or "completed" or 3 more`

  - `"queued"`

  - `"running"`

  - `"completed"`

  - `"error"`

  - `"skipped"`

  - `"outdated"`

### Returns

- `result: array of object { id, checksum, chunks_count, 9 more }`

  - `id: string`

  - `checksum: string`

  - `chunks_count: number`

  - `created_at: string`

  - `file_size: number`

  - `key: string`

  - `last_seen_at: string`

  - `namespace: string`

  - `next_action: "INDEX" or "DELETE"`

    - `"INDEX"`

    - `"DELETE"`

  - `source_id: string`

    Identifies which data source this item belongs to. "builtin" for uploaded files, "{type}:{source}" for external sources, null for legacy items.

  - `status: "queued" or "running" or "completed" or 3 more`

    - `"queued"`

    - `"running"`

    - `"completed"`

    - `"error"`

    - `"skipped"`

    - `"outdated"`

  - `error: optional string`

- `result_info: object { count, page, total_count, per_page }`

  - `count: number`

  - `page: number`

  - `total_count: number`

  - `per_page: optional number`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME/instances/$ID/items \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": [
    {
      "id": "id",
      "checksum": "checksum",
      "chunks_count": 0,
      "created_at": "2019-12-27T18:11:19.117Z",
      "file_size": 0,
      "key": "key",
      "last_seen_at": "2019-12-27T18:11:19.117Z",
      "namespace": "namespace",
      "next_action": "INDEX",
      "source_id": "source_id",
      "status": "queued",
      "error": "error"
    }
  ],
  "result_info": {
    "count": 0,
    "page": 0,
    "total_count": 0,
    "per_page": 5
  },
  "success": true
}
```

## Upload Item.

**post** `/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items`

Uploads a file to a managed AI Search instance via multipart/form-data (max 4MB).

### Path Parameters

- `account_id: string`

- `name: string`

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

### Returns

- `result: object { id, checksum, chunks_count, 9 more }`

  - `id: string`

  - `checksum: string`

  - `chunks_count: number`

  - `created_at: string`

  - `file_size: number`

  - `key: string`

  - `last_seen_at: string`

  - `namespace: string`

  - `next_action: "INDEX" or "DELETE"`

    - `"INDEX"`

    - `"DELETE"`

  - `source_id: string`

    Identifies which data source this item belongs to. "builtin" for uploaded files, "{type}:{source}" for external sources, null for legacy items.

  - `status: "queued" or "running" or "completed" or 3 more`

    - `"queued"`

    - `"running"`

    - `"completed"`

    - `"error"`

    - `"skipped"`

    - `"outdated"`

  - `error: optional string`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME/instances/$ID/items \
    -H 'Content-Type: multipart/form-data' \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
    -F file='{"file":"Example data"}'
```

#### Response

```json
{
  "result": {
    "id": "id",
    "checksum": "checksum",
    "chunks_count": 0,
    "created_at": "2019-12-27T18:11:19.117Z",
    "file_size": 0,
    "key": "key",
    "last_seen_at": "2019-12-27T18:11:19.117Z",
    "namespace": "namespace",
    "next_action": "INDEX",
    "source_id": "source_id",
    "status": "queued",
    "error": "error"
  },
  "success": true
}
```

## Create or Update Item.

**put** `/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items`

Creates or updates an indexed item in an AI Search instance.

### Path Parameters

- `account_id: string`

- `name: string`

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

### Body Parameters

- `key: string`

  Item key / filename. Must not exceed 128 characters.

- `next_action: "INDEX"`

  - `"INDEX"`

- `wait_for_completion: optional boolean`

  Wait for indexing to fully complete before responding. On RAGs with vector indexing enabled, this additionally waits for Vectorize ingestion confirmation (up to 40s) so the returned item reflects a queryable state. On timeout the item is returned in `running` state and the background alarm continues polling. Defaults to false.

### Returns

- `result: object { id, checksum, chunks_count, 9 more }`

  - `id: string`

  - `checksum: string`

  - `chunks_count: number`

  - `created_at: string`

  - `file_size: number`

  - `key: string`

  - `last_seen_at: string`

  - `namespace: string`

  - `next_action: "INDEX" or "DELETE"`

    - `"INDEX"`

    - `"DELETE"`

  - `source_id: string`

    Identifies which data source this item belongs to. "builtin" for uploaded files, "{type}:{source}" for external sources, null for legacy items.

  - `status: "queued" or "running" or "completed" or 3 more`

    - `"queued"`

    - `"running"`

    - `"completed"`

    - `"error"`

    - `"skipped"`

    - `"outdated"`

  - `error: optional string`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME/instances/$ID/items \
    -X PUT \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
    -d '{
          "key": "key",
          "next_action": "INDEX"
        }'
```

#### Response

```json
{
  "result": {
    "id": "id",
    "checksum": "checksum",
    "chunks_count": 0,
    "created_at": "2019-12-27T18:11:19.117Z",
    "file_size": 0,
    "key": "key",
    "last_seen_at": "2019-12-27T18:11:19.117Z",
    "namespace": "namespace",
    "next_action": "INDEX",
    "source_id": "source_id",
    "status": "queued",
    "error": "error"
  },
  "success": true
}
```

## Get Item.

**get** `/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items/{item_id}`

Retrieves a specific indexed item from an AI Search instance.

### Path Parameters

- `account_id: string`

- `name: string`

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

- `item_id: string`

### Returns

- `result: object { id, checksum, chunks_count, 9 more }`

  - `id: string`

  - `checksum: string`

  - `chunks_count: number`

  - `created_at: string`

  - `file_size: number`

  - `key: string`

  - `last_seen_at: string`

  - `namespace: string`

  - `next_action: "INDEX" or "DELETE"`

    - `"INDEX"`

    - `"DELETE"`

  - `source_id: string`

    Identifies which data source this item belongs to. "builtin" for uploaded files, "{type}:{source}" for external sources, null for legacy items.

  - `status: "queued" or "running" or "completed" or 3 more`

    - `"queued"`

    - `"running"`

    - `"completed"`

    - `"error"`

    - `"skipped"`

    - `"outdated"`

  - `error: optional string`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME/instances/$ID/items/$ITEM_ID \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": {
    "id": "id",
    "checksum": "checksum",
    "chunks_count": 0,
    "created_at": "2019-12-27T18:11:19.117Z",
    "file_size": 0,
    "key": "key",
    "last_seen_at": "2019-12-27T18:11:19.117Z",
    "namespace": "namespace",
    "next_action": "INDEX",
    "source_id": "source_id",
    "status": "queued",
    "error": "error"
  },
  "success": true
}
```

## Sync Item.

**patch** `/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items/{item_id}`

Syncs an item to an AI Search instance index.

### Path Parameters

- `account_id: string`

- `name: string`

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

- `item_id: string`

### Body Parameters

- `next_action: "INDEX"`

  - `"INDEX"`

- `wait_for_completion: optional boolean`

  Wait for indexing to fully complete before responding. On RAGs with vector indexing enabled, this additionally waits for Vectorize ingestion confirmation (up to 40s) so the returned item reflects a queryable state. On timeout the item is returned in `running` state and the background alarm continues polling. Defaults to false.

### Returns

- `result: object { id, checksum, chunks_count, 9 more }`

  - `id: string`

  - `checksum: string`

  - `chunks_count: number`

  - `created_at: string`

  - `file_size: number`

  - `key: string`

  - `last_seen_at: string`

  - `namespace: string`

  - `next_action: "INDEX" or "DELETE"`

    - `"INDEX"`

    - `"DELETE"`

  - `source_id: string`

    Identifies which data source this item belongs to. "builtin" for uploaded files, "{type}:{source}" for external sources, null for legacy items.

  - `status: "queued" or "running" or "completed" or 3 more`

    - `"queued"`

    - `"running"`

    - `"completed"`

    - `"error"`

    - `"skipped"`

    - `"outdated"`

  - `error: optional string`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME/instances/$ID/items/$ITEM_ID \
    -X PATCH \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
    -d '{
          "next_action": "INDEX"
        }'
```

#### Response

```json
{
  "result": {
    "id": "id",
    "checksum": "checksum",
    "chunks_count": 0,
    "created_at": "2019-12-27T18:11:19.117Z",
    "file_size": 0,
    "key": "key",
    "last_seen_at": "2019-12-27T18:11:19.117Z",
    "namespace": "namespace",
    "next_action": "INDEX",
    "source_id": "source_id",
    "status": "queued",
    "error": "error"
  },
  "success": true
}
```

## Delete Item.

**delete** `/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items/{item_id}`

Deletes a file from a managed AI Search instance and triggers a reindex.

### Path Parameters

- `account_id: string`

- `name: string`

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

- `item_id: string`

### Returns

- `result: object { key }`

  - `key: string`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME/instances/$ID/items/$ITEM_ID \
    -X DELETE \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": {
    "key": "key"
  },
  "success": true
}
```

## Download Item Content.

**get** `/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items/{item_id}/download`

Downloads the raw file content for a specific item from the managed AI Search instance storage.

### Path Parameters

- `account_id: string`

- `name: string`

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

- `item_id: string`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME/instances/$ID/items/$ITEM_ID/download \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

## Item Logs.

**get** `/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items/{item_id}/logs`

Lists processing logs for a specific item in an AI Search instance.

### Path Parameters

- `account_id: string`

- `name: string`

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

- `item_id: string`

### Query Parameters

- `cursor: optional string`

- `limit: optional number`

### Returns

- `result: array of object { action, chunkCount, errorType, 4 more }`

  - `action: string`

  - `chunkCount: number`

  - `errorType: string`

  - `fileKey: string`

  - `message: string`

  - `processingTimeMs: number`

  - `timestamp: string`

- `result_info: object { count, cursor, per_page, truncated }`

  - `count: number`

  - `cursor: string`

  - `per_page: number`

  - `truncated: boolean`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME/instances/$ID/items/$ITEM_ID/logs \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": [
    {
      "action": "action",
      "chunkCount": 0,
      "errorType": "errorType",
      "fileKey": "fileKey",
      "message": "message",
      "processingTimeMs": 0,
      "timestamp": "2019-12-27T18:11:19.117Z"
    }
  ],
  "result_info": {
    "count": 0,
    "cursor": "cursor",
    "per_page": 0,
    "truncated": true
  },
  "success": true
}
```

## List Item Chunks.

**get** `/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items/{item_id}/chunks`

Lists chunks for a specific item in an AI Search instance, including their text content.

### Path Parameters

- `account_id: string`

- `name: string`

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

- `item_id: string`

### Query Parameters

- `limit: optional number`

- `offset: optional number`

### Returns

- `result: array of object { id, item, text, 2 more }`

  - `id: string`

  - `item: object { key, metadata, timestamp }`

    - `key: string`

    - `metadata: optional map[unknown]`

    - `timestamp: optional number`

  - `text: string`

  - `end_byte: optional number`

  - `start_byte: optional number`

- `result_info: object { count, limit, offset, total }`

  - `count: number`

  - `limit: number`

  - `offset: number`

  - `total: number`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/namespaces/$NAME/instances/$ID/items/$ITEM_ID/chunks \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": [
    {
      "id": "id",
      "item": {
        "key": "key",
        "metadata": {
          "foo": "bar"
        },
        "timestamp": 0
      },
      "text": "text",
      "end_byte": 0,
      "start_byte": 0
    }
  ],
  "result_info": {
    "count": 0,
    "limit": 0,
    "offset": 0,
    "total": 0
  },
  "success": true
}
```

## Domain Types

### Item List Response

- `ItemListResponse object { id, checksum, chunks_count, 9 more }`

  - `id: string`

  - `checksum: string`

  - `chunks_count: number`

  - `created_at: string`

  - `file_size: number`

  - `key: string`

  - `last_seen_at: string`

  - `namespace: string`

  - `next_action: "INDEX" or "DELETE"`

    - `"INDEX"`

    - `"DELETE"`

  - `source_id: string`

    Identifies which data source this item belongs to. "builtin" for uploaded files, "{type}:{source}" for external sources, null for legacy items.

  - `status: "queued" or "running" or "completed" or 3 more`

    - `"queued"`

    - `"running"`

    - `"completed"`

    - `"error"`

    - `"skipped"`

    - `"outdated"`

  - `error: optional string`

### Item Upload Response

- `ItemUploadResponse object { id, checksum, chunks_count, 9 more }`

  - `id: string`

  - `checksum: string`

  - `chunks_count: number`

  - `created_at: string`

  - `file_size: number`

  - `key: string`

  - `last_seen_at: string`

  - `namespace: string`

  - `next_action: "INDEX" or "DELETE"`

    - `"INDEX"`

    - `"DELETE"`

  - `source_id: string`

    Identifies which data source this item belongs to. "builtin" for uploaded files, "{type}:{source}" for external sources, null for legacy items.

  - `status: "queued" or "running" or "completed" or 3 more`

    - `"queued"`

    - `"running"`

    - `"completed"`

    - `"error"`

    - `"skipped"`

    - `"outdated"`

  - `error: optional string`

### Item Create Or Update Response

- `ItemCreateOrUpdateResponse object { id, checksum, chunks_count, 9 more }`

  - `id: string`

  - `checksum: string`

  - `chunks_count: number`

  - `created_at: string`

  - `file_size: number`

  - `key: string`

  - `last_seen_at: string`

  - `namespace: string`

  - `next_action: "INDEX" or "DELETE"`

    - `"INDEX"`

    - `"DELETE"`

  - `source_id: string`

    Identifies which data source this item belongs to. "builtin" for uploaded files, "{type}:{source}" for external sources, null for legacy items.

  - `status: "queued" or "running" or "completed" or 3 more`

    - `"queued"`

    - `"running"`

    - `"completed"`

    - `"error"`

    - `"skipped"`

    - `"outdated"`

  - `error: optional string`

### Item Get Response

- `ItemGetResponse object { id, checksum, chunks_count, 9 more }`

  - `id: string`

  - `checksum: string`

  - `chunks_count: number`

  - `created_at: string`

  - `file_size: number`

  - `key: string`

  - `last_seen_at: string`

  - `namespace: string`

  - `next_action: "INDEX" or "DELETE"`

    - `"INDEX"`

    - `"DELETE"`

  - `source_id: string`

    Identifies which data source this item belongs to. "builtin" for uploaded files, "{type}:{source}" for external sources, null for legacy items.

  - `status: "queued" or "running" or "completed" or 3 more`

    - `"queued"`

    - `"running"`

    - `"completed"`

    - `"error"`

    - `"skipped"`

    - `"outdated"`

  - `error: optional string`

### Item Sync Response

- `ItemSyncResponse object { id, checksum, chunks_count, 9 more }`

  - `id: string`

  - `checksum: string`

  - `chunks_count: number`

  - `created_at: string`

  - `file_size: number`

  - `key: string`

  - `last_seen_at: string`

  - `namespace: string`

  - `next_action: "INDEX" or "DELETE"`

    - `"INDEX"`

    - `"DELETE"`

  - `source_id: string`

    Identifies which data source this item belongs to. "builtin" for uploaded files, "{type}:{source}" for external sources, null for legacy items.

  - `status: "queued" or "running" or "completed" or 3 more`

    - `"queued"`

    - `"running"`

    - `"completed"`

    - `"error"`

    - `"skipped"`

    - `"outdated"`

  - `error: optional string`

### Item Delete Response

- `ItemDeleteResponse object { key }`

  - `key: string`

### Item Logs Response

- `ItemLogsResponse = array of object { action, chunkCount, errorType, 4 more }`

  - `action: string`

  - `chunkCount: number`

  - `errorType: string`

  - `fileKey: string`

  - `message: string`

  - `processingTimeMs: number`

  - `timestamp: string`

### Item Chunks Response

- `ItemChunksResponse = array of object { id, item, text, 2 more }`

  - `id: string`

  - `item: object { key, metadata, timestamp }`

    - `key: string`

    - `metadata: optional map[unknown]`

    - `timestamp: optional number`

  - `text: string`

  - `end_byte: optional number`

  - `start_byte: optional number`

# Instances

## List instances.

**get** `/accounts/{account_id}/ai-search/instances`

List instances.

### Path Parameters

- `account_id: string`

### Query Parameters

- `namespace: optional string`

  Filter by namespace.

- `order_by: optional "created_at"`

  Field to order results by.

  - `"created_at"`

- `order_by_direction: optional "asc" or "desc"`

  Order direction.

  - `"asc"`

  - `"desc"`

- `page: optional number`

  Page number (1-indexed).

- `per_page: optional number`

  Number of results per page.

- `search: optional string`

  Filter instances whose id contains this string (case-insensitive).

### Returns

- `result: array of object { id, created_at, modified_at, 36 more }`

  - `id: string`

    AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

  - `created_at: string`

  - `modified_at: string`

  - `ai_gateway_id: optional string`

  - `ai_search_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `cache: optional boolean`

  - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

    - `"super_strict_match"`

    - `"close_enough"`

    - `"flexible_friend"`

    - `"anything_goes"`

  - `cache_ttl: optional 600 or 1800 or 3600 or 7 more`

    Cache entry TTL in seconds. Allowed values: 600 (10min), 1800 (30min), 3600 (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d).

    - `600`

    - `1800`

    - `3600`

    - `7200`

    - `21600`

    - `43200`

    - `86400`

    - `172800`

    - `259200`

    - `518400`

  - `chunk_overlap: optional number`

  - `chunk_size: optional number`

  - `created_by: optional string`

  - `custom_metadata: optional array of object { data_type, field_name }`

    - `data_type: "text" or "number" or "boolean" or "datetime"`

      - `"text"`

      - `"number"`

      - `"boolean"`

      - `"datetime"`

    - `field_name: string`

  - `embedding_model: optional "@cf/qwen/qwen3-embedding-0.6b" or "@cf/baai/bge-m3" or "@cf/baai/bge-large-en-v1.5" or 6 more`

    - `"@cf/qwen/qwen3-embedding-0.6b"`

    - `"@cf/baai/bge-m3"`

    - `"@cf/baai/bge-large-en-v1.5"`

    - `"@cf/google/embeddinggemma-300m"`

    - `"google-ai-studio/gemini-embedding-001"`

    - `"google-ai-studio/gemini-embedding-2-preview"`

    - `"openai/text-embedding-3-small"`

    - `"openai/text-embedding-3-large"`

    - `""`

  - `enable: optional boolean`

  - `engine_version: optional number`

  - `fusion_method: optional "max" or "rrf"`

    - `"max"`

    - `"rrf"`

  - `hybrid_search_enabled: optional boolean`

    Deprecated — use index_method instead.

  - `index_method: optional object { keyword, vector }`

    Controls which storage backends are used during indexing. Defaults to vector-only.

    - `keyword: boolean`

      Enable keyword (BM25) storage backend.

    - `vector: boolean`

      Enable vector (embedding) storage backend.

  - `indexing_options: optional object { keyword_tokenizer }`

    - `keyword_tokenizer: optional "porter" or "trigram"`

      Tokenizer used for keyword search indexing. porter provides word-level tokenization with Porter stemming (good for natural language queries). trigram enables character-level substring matching (good for partial matches, code, identifiers). Changing this triggers a full re-index. Defaults to porter.

      - `"porter"`

      - `"trigram"`

  - `last_activity: optional string`

  - `max_num_results: optional number`

  - `metadata: optional object { created_from_aisearch_wizard, worker_domain }`

    - `created_from_aisearch_wizard: optional boolean`

    - `worker_domain: optional string`

  - `modified_by: optional string`

  - `namespace: optional string`

  - `paused: optional boolean`

  - `public_endpoint_id: optional string`

  - `public_endpoint_params: optional object { authorized_hosts, chat_completions_endpoint, enabled, 3 more }`

    - `authorized_hosts: optional array of string`

    - `chat_completions_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable chat completions endpoint for this public endpoint

    - `enabled: optional boolean`

    - `mcp: optional object { description, disabled }`

      - `description: optional string`

      - `disabled: optional boolean`

        Disable MCP endpoint for this public endpoint

    - `rate_limit: optional object { period_ms, requests, technique }`

      - `period_ms: optional number`

      - `requests: optional number`

      - `technique: optional "fixed" or "sliding"`

        - `"fixed"`

        - `"sliding"`

    - `search_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable search endpoint for this public endpoint

  - `reranking: optional boolean`

  - `reranking_model: optional "@cf/baai/bge-reranker-base" or ""`

    - `"@cf/baai/bge-reranker-base"`

    - `""`

  - `retrieval_options: optional object { boost_by, keyword_match_mode }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Each entry specifies a metadata field and an optional direction. Direction defaults to 'asc' for numeric/datetime fields and 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

  - `rewrite_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `rewrite_query: optional boolean`

  - `score_threshold: optional number`

  - `source: optional string`

  - `source_params: optional object { exclude_items, include_items, prefix, 2 more }`

    - `exclude_items: optional array of string`

      List of path patterns to exclude. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and /admin/settings/advanced)

    - `include_items: optional array of string`

      List of path patterns to include. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post)

    - `prefix: optional string`

    - `r2_jurisdiction: optional string`

    - `web_crawler: optional object { crawl_options, parse_options, parse_type, store_options }`

      - `crawl_options: optional object { depth, include_external_links, include_subdomains, 2 more }`

        - `depth: optional number`

        - `include_external_links: optional boolean`

        - `include_subdomains: optional boolean`

        - `max_age: optional number`

        - `source: optional "all" or "sitemaps" or "links"`

          - `"all"`

          - `"sitemaps"`

          - `"links"`

      - `parse_options: optional object { content_selector, include_headers, include_images, 2 more }`

        - `content_selector: optional array of object { path, selector }`

          List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first matching path wins. Only the matched HTML fragment is stored and indexed. Omit the field to disable content selection — empty arrays are rejected.

          - `path: string`

            Glob pattern to match against the page URL path. Uses standard glob syntax: * matches within a segment, ** crosses directories.

          - `selector: string`

            CSS selector to extract content from pages matching the path pattern. Must not contain disallowed characters (;, `, $, {, }, ). Must target a single element; if multiple elements match, the selector is ignored and the full page is used.

        - `include_headers: optional map[string]`

          Up to 5 custom HTTP headers sent with each crawl request. Names must be RFC-7230 token characters (no spaces, colons, or control characters); values must be HTAB + printable ASCII (no CR/LF).

        - `include_images: optional boolean`

        - `specific_sitemaps: optional array of string`

          List of specific sitemap URLs to use for crawling. Only valid when parse_type is 'sitemap'.

        - `use_browser_rendering: optional boolean`

      - `parse_type: optional "sitemap" or "feed-rss" or "crawl"`

        - `"sitemap"`

        - `"feed-rss"`

        - `"crawl"`

      - `store_options: optional object { storage_id, r2_jurisdiction, storage_type }`

        - `storage_id: string`

        - `r2_jurisdiction: optional string`

        - `storage_type: optional Provider`

          - `"r2"`

  - `status: optional string`

  - `sync_interval: optional 900 or 1800 or 3600 or 5 more`

    Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h).

    - `900`

    - `1800`

    - `3600`

    - `7200`

    - `14400`

    - `21600`

    - `43200`

    - `86400`

  - `token_id: optional string`

  - `type: optional "r2" or "web-crawler"`

    - `"r2"`

    - `"web-crawler"`

- `result_info: object { count, page, per_page, total_count }`

  - `count: number`

  - `page: number`

  - `per_page: number`

  - `total_count: number`

- `success: true`

  - `true`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/instances \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": [
    {
      "id": "my-ai-search",
      "created_at": "2019-12-27T18:11:19.117Z",
      "modified_at": "2019-12-27T18:11:19.117Z",
      "ai_gateway_id": "ai_gateway_id",
      "ai_search_model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
      "cache": true,
      "cache_threshold": "super_strict_match",
      "cache_ttl": 600,
      "chunk_overlap": 0,
      "chunk_size": 64,
      "created_by": "created_by",
      "custom_metadata": [
        {
          "data_type": "text",
          "field_name": "x"
        }
      ],
      "embedding_model": "@cf/qwen/qwen3-embedding-0.6b",
      "enable": true,
      "engine_version": 0,
      "fusion_method": "max",
      "hybrid_search_enabled": true,
      "index_method": {
        "keyword": true,
        "vector": true
      },
      "indexing_options": {
        "keyword_tokenizer": "porter"
      },
      "last_activity": "2019-12-27T18:11:19.117Z",
      "max_num_results": 1,
      "metadata": {
        "created_from_aisearch_wizard": true,
        "worker_domain": "worker_domain"
      },
      "modified_by": "modified_by",
      "namespace": "namespace",
      "paused": true,
      "public_endpoint_id": "public_endpoint_id",
      "public_endpoint_params": {
        "authorized_hosts": [
          "string"
        ],
        "chat_completions_endpoint": {
          "disabled": true
        },
        "enabled": true,
        "mcp": {
          "description": "description",
          "disabled": true
        },
        "rate_limit": {
          "period_ms": 60000,
          "requests": 1,
          "technique": "fixed"
        },
        "search_endpoint": {
          "disabled": true
        }
      },
      "reranking": true,
      "reranking_model": "@cf/baai/bge-reranker-base",
      "retrieval_options": {
        "boost_by": [
          {
            "field": "timestamp",
            "direction": "desc"
          }
        ],
        "keyword_match_mode": "and"
      },
      "rewrite_model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
      "rewrite_query": true,
      "score_threshold": 0,
      "source": "source",
      "source_params": {
        "exclude_items": [
          "/admin/**",
          "/private/**",
          "**\\temp\\**"
        ],
        "include_items": [
          "/blog/**",
          "/docs/**/*.html",
          "**\\blog\\**.html"
        ],
        "prefix": "prefix",
        "r2_jurisdiction": "r2_jurisdiction",
        "web_crawler": {
          "crawl_options": {
            "depth": 1,
            "include_external_links": true,
            "include_subdomains": true,
            "max_age": 0,
            "source": "all"
          },
          "parse_options": {
            "content_selector": [
              {
                "path": "**/blog/**",
                "selector": "article div.post-body"
              },
              {
                "path": "**/docs/**",
                "selector": "main"
              }
            ],
            "include_headers": {
              "cache-control": "no-cache, no-store"
            },
            "include_images": true,
            "specific_sitemaps": [
              "https://example.com/sitemap.xml",
              "https://example.com/blog-sitemap.xml"
            ],
            "use_browser_rendering": true
          },
          "parse_type": "sitemap",
          "store_options": {
            "storage_id": "storage_id",
            "r2_jurisdiction": "r2_jurisdiction",
            "storage_type": "r2"
          }
        }
      },
      "status": "status",
      "sync_interval": 900,
      "token_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
      "type": "r2"
    }
  ],
  "result_info": {
    "count": 0,
    "page": 0,
    "per_page": 0,
    "total_count": 0
  },
  "success": true
}
```

## Create new instance.

**post** `/accounts/{account_id}/ai-search/instances`

Create a new instance.

### Path Parameters

- `account_id: string`

### Body Parameters

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

- `ai_gateway_id: optional string`

- `ai_search_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

  - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

  - `"@cf/zai-org/glm-4.7-flash"`

  - `"@cf/meta/llama-3.1-8b-instruct-fast"`

  - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

  - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

  - `"@cf/qwen/qwen3-30b-a3b-fp8"`

  - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

  - `"@cf/moonshotai/kimi-k2-instruct"`

  - `"@cf/google/gemma-3-12b-it"`

  - `"@cf/google/gemma-4-26b-a4b-it"`

  - `"@cf/moonshotai/kimi-k2.5"`

  - `"anthropic/claude-3-7-sonnet"`

  - `"anthropic/claude-sonnet-4"`

  - `"anthropic/claude-opus-4"`

  - `"anthropic/claude-3-5-haiku"`

  - `"cerebras/qwen-3-235b-a22b-instruct"`

  - `"cerebras/qwen-3-235b-a22b-thinking"`

  - `"cerebras/llama-3.3-70b"`

  - `"cerebras/llama-4-maverick-17b-128e-instruct"`

  - `"cerebras/llama-4-scout-17b-16e-instruct"`

  - `"cerebras/gpt-oss-120b"`

  - `"google-ai-studio/gemini-2.5-flash"`

  - `"google-ai-studio/gemini-2.5-pro"`

  - `"grok/grok-4"`

  - `"groq/llama-3.3-70b-versatile"`

  - `"groq/llama-3.1-8b-instant"`

  - `"openai/gpt-5"`

  - `"openai/gpt-5-mini"`

  - `"openai/gpt-5-nano"`

  - `""`

- `cache: optional boolean`

- `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

  - `"super_strict_match"`

  - `"close_enough"`

  - `"flexible_friend"`

  - `"anything_goes"`

- `cache_ttl: optional 600 or 1800 or 3600 or 7 more`

  Cache entry TTL in seconds. Allowed values: 600 (10min), 1800 (30min), 3600 (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d).

  - `600`

  - `1800`

  - `3600`

  - `7200`

  - `21600`

  - `43200`

  - `86400`

  - `172800`

  - `259200`

  - `518400`

- `chunk: optional boolean`

- `chunk_overlap: optional number`

- `chunk_size: optional number`

- `custom_metadata: optional array of object { data_type, field_name }`

  - `data_type: "text" or "number" or "boolean" or "datetime"`

    - `"text"`

    - `"number"`

    - `"boolean"`

    - `"datetime"`

  - `field_name: string`

- `embedding_model: optional "@cf/qwen/qwen3-embedding-0.6b" or "@cf/baai/bge-m3" or "@cf/baai/bge-large-en-v1.5" or 6 more`

  - `"@cf/qwen/qwen3-embedding-0.6b"`

  - `"@cf/baai/bge-m3"`

  - `"@cf/baai/bge-large-en-v1.5"`

  - `"@cf/google/embeddinggemma-300m"`

  - `"google-ai-studio/gemini-embedding-001"`

  - `"google-ai-studio/gemini-embedding-2-preview"`

  - `"openai/text-embedding-3-small"`

  - `"openai/text-embedding-3-large"`

  - `""`

- `fusion_method: optional "max" or "rrf"`

  - `"max"`

  - `"rrf"`

- `hybrid_search_enabled: optional boolean`

  Deprecated — use index_method instead.

- `index_method: optional object { keyword, vector }`

  Controls which storage backends are used during indexing. Defaults to vector-only.

  - `keyword: boolean`

    Enable keyword (BM25) storage backend.

  - `vector: boolean`

    Enable vector (embedding) storage backend.

- `indexing_options: optional object { keyword_tokenizer }`

  - `keyword_tokenizer: optional "porter" or "trigram"`

    Tokenizer used for keyword search indexing. porter provides word-level tokenization with Porter stemming (good for natural language queries). trigram enables character-level substring matching (good for partial matches, code, identifiers). Changing this triggers a full re-index. Defaults to porter.

    - `"porter"`

    - `"trigram"`

- `max_num_results: optional number`

- `metadata: optional object { created_from_aisearch_wizard, worker_domain }`

  - `created_from_aisearch_wizard: optional boolean`

  - `worker_domain: optional string`

- `public_endpoint_params: optional object { authorized_hosts, chat_completions_endpoint, enabled, 3 more }`

  - `authorized_hosts: optional array of string`

  - `chat_completions_endpoint: optional object { disabled }`

    - `disabled: optional boolean`

      Disable chat completions endpoint for this public endpoint

  - `enabled: optional boolean`

  - `mcp: optional object { description, disabled }`

    - `description: optional string`

    - `disabled: optional boolean`

      Disable MCP endpoint for this public endpoint

  - `rate_limit: optional object { period_ms, requests, technique }`

    - `period_ms: optional number`

    - `requests: optional number`

    - `technique: optional "fixed" or "sliding"`

      - `"fixed"`

      - `"sliding"`

  - `search_endpoint: optional object { disabled }`

    - `disabled: optional boolean`

      Disable search endpoint for this public endpoint

- `reranking: optional boolean`

- `reranking_model: optional "@cf/baai/bge-reranker-base" or ""`

  - `"@cf/baai/bge-reranker-base"`

  - `""`

- `retrieval_options: optional object { boost_by, keyword_match_mode }`

  - `boost_by: optional array of object { field, direction }`

    Metadata fields to boost search results by. Each entry specifies a metadata field and an optional direction. Direction defaults to 'asc' for numeric/datetime fields and 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

    - `field: string`

      Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

    - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

      Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

      - `"asc"`

      - `"desc"`

      - `"exists"`

      - `"not_exists"`

  - `keyword_match_mode: optional "and" or "or"`

    Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

    - `"and"`

    - `"or"`

- `rewrite_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

  - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

  - `"@cf/zai-org/glm-4.7-flash"`

  - `"@cf/meta/llama-3.1-8b-instruct-fast"`

  - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

  - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

  - `"@cf/qwen/qwen3-30b-a3b-fp8"`

  - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

  - `"@cf/moonshotai/kimi-k2-instruct"`

  - `"@cf/google/gemma-3-12b-it"`

  - `"@cf/google/gemma-4-26b-a4b-it"`

  - `"@cf/moonshotai/kimi-k2.5"`

  - `"anthropic/claude-3-7-sonnet"`

  - `"anthropic/claude-sonnet-4"`

  - `"anthropic/claude-opus-4"`

  - `"anthropic/claude-3-5-haiku"`

  - `"cerebras/qwen-3-235b-a22b-instruct"`

  - `"cerebras/qwen-3-235b-a22b-thinking"`

  - `"cerebras/llama-3.3-70b"`

  - `"cerebras/llama-4-maverick-17b-128e-instruct"`

  - `"cerebras/llama-4-scout-17b-16e-instruct"`

  - `"cerebras/gpt-oss-120b"`

  - `"google-ai-studio/gemini-2.5-flash"`

  - `"google-ai-studio/gemini-2.5-pro"`

  - `"grok/grok-4"`

  - `"groq/llama-3.3-70b-versatile"`

  - `"groq/llama-3.1-8b-instant"`

  - `"openai/gpt-5"`

  - `"openai/gpt-5-mini"`

  - `"openai/gpt-5-nano"`

  - `""`

- `rewrite_query: optional boolean`

- `score_threshold: optional number`

- `source: optional string`

- `source_params: optional object { exclude_items, include_items, prefix, 2 more }`

  - `exclude_items: optional array of string`

    List of path patterns to exclude. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and /admin/settings/advanced)

  - `include_items: optional array of string`

    List of path patterns to include. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post)

  - `prefix: optional string`

  - `r2_jurisdiction: optional string`

  - `web_crawler: optional object { crawl_options, parse_options, parse_type, store_options }`

    - `crawl_options: optional object { depth, include_external_links, include_subdomains, 2 more }`

      - `depth: optional number`

      - `include_external_links: optional boolean`

      - `include_subdomains: optional boolean`

      - `max_age: optional number`

      - `source: optional "all" or "sitemaps" or "links"`

        - `"all"`

        - `"sitemaps"`

        - `"links"`

    - `parse_options: optional object { content_selector, include_headers, include_images, 2 more }`

      - `content_selector: optional array of object { path, selector }`

        List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first matching path wins. Only the matched HTML fragment is stored and indexed. Omit the field to disable content selection — empty arrays are rejected.

        - `path: string`

          Glob pattern to match against the page URL path. Uses standard glob syntax: * matches within a segment, ** crosses directories.

        - `selector: string`

          CSS selector to extract content from pages matching the path pattern. Must not contain disallowed characters (;, `, $, {, }, ). Must target a single element; if multiple elements match, the selector is ignored and the full page is used.

      - `include_headers: optional map[string]`

        Up to 5 custom HTTP headers sent with each crawl request. Names must be RFC-7230 token characters (no spaces, colons, or control characters); values must be HTAB + printable ASCII (no CR/LF).

      - `include_images: optional boolean`

      - `specific_sitemaps: optional array of string`

        List of specific sitemap URLs to use for crawling. Only valid when parse_type is 'sitemap'.

      - `use_browser_rendering: optional boolean`

    - `parse_type: optional "sitemap" or "feed-rss" or "crawl"`

      - `"sitemap"`

      - `"feed-rss"`

      - `"crawl"`

    - `store_options: optional object { storage_id, r2_jurisdiction, storage_type }`

      - `storage_id: string`

      - `r2_jurisdiction: optional string`

      - `storage_type: optional Provider`

        - `"r2"`

- `sync_interval: optional 900 or 1800 or 3600 or 5 more`

  Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h).

  - `900`

  - `1800`

  - `3600`

  - `7200`

  - `14400`

  - `21600`

  - `43200`

  - `86400`

- `token_id: optional string`

- `type: optional "r2" or "web-crawler"`

  - `"r2"`

  - `"web-crawler"`

### Returns

- `result: object { id, created_at, modified_at, 36 more }`

  - `id: string`

    AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

  - `created_at: string`

  - `modified_at: string`

  - `ai_gateway_id: optional string`

  - `ai_search_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `cache: optional boolean`

  - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

    - `"super_strict_match"`

    - `"close_enough"`

    - `"flexible_friend"`

    - `"anything_goes"`

  - `cache_ttl: optional 600 or 1800 or 3600 or 7 more`

    Cache entry TTL in seconds. Allowed values: 600 (10min), 1800 (30min), 3600 (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d).

    - `600`

    - `1800`

    - `3600`

    - `7200`

    - `21600`

    - `43200`

    - `86400`

    - `172800`

    - `259200`

    - `518400`

  - `chunk_overlap: optional number`

  - `chunk_size: optional number`

  - `created_by: optional string`

  - `custom_metadata: optional array of object { data_type, field_name }`

    - `data_type: "text" or "number" or "boolean" or "datetime"`

      - `"text"`

      - `"number"`

      - `"boolean"`

      - `"datetime"`

    - `field_name: string`

  - `embedding_model: optional "@cf/qwen/qwen3-embedding-0.6b" or "@cf/baai/bge-m3" or "@cf/baai/bge-large-en-v1.5" or 6 more`

    - `"@cf/qwen/qwen3-embedding-0.6b"`

    - `"@cf/baai/bge-m3"`

    - `"@cf/baai/bge-large-en-v1.5"`

    - `"@cf/google/embeddinggemma-300m"`

    - `"google-ai-studio/gemini-embedding-001"`

    - `"google-ai-studio/gemini-embedding-2-preview"`

    - `"openai/text-embedding-3-small"`

    - `"openai/text-embedding-3-large"`

    - `""`

  - `enable: optional boolean`

  - `engine_version: optional number`

  - `fusion_method: optional "max" or "rrf"`

    - `"max"`

    - `"rrf"`

  - `hybrid_search_enabled: optional boolean`

    Deprecated — use index_method instead.

  - `index_method: optional object { keyword, vector }`

    Controls which storage backends are used during indexing. Defaults to vector-only.

    - `keyword: boolean`

      Enable keyword (BM25) storage backend.

    - `vector: boolean`

      Enable vector (embedding) storage backend.

  - `indexing_options: optional object { keyword_tokenizer }`

    - `keyword_tokenizer: optional "porter" or "trigram"`

      Tokenizer used for keyword search indexing. porter provides word-level tokenization with Porter stemming (good for natural language queries). trigram enables character-level substring matching (good for partial matches, code, identifiers). Changing this triggers a full re-index. Defaults to porter.

      - `"porter"`

      - `"trigram"`

  - `last_activity: optional string`

  - `max_num_results: optional number`

  - `metadata: optional object { created_from_aisearch_wizard, worker_domain }`

    - `created_from_aisearch_wizard: optional boolean`

    - `worker_domain: optional string`

  - `modified_by: optional string`

  - `namespace: optional string`

  - `paused: optional boolean`

  - `public_endpoint_id: optional string`

  - `public_endpoint_params: optional object { authorized_hosts, chat_completions_endpoint, enabled, 3 more }`

    - `authorized_hosts: optional array of string`

    - `chat_completions_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable chat completions endpoint for this public endpoint

    - `enabled: optional boolean`

    - `mcp: optional object { description, disabled }`

      - `description: optional string`

      - `disabled: optional boolean`

        Disable MCP endpoint for this public endpoint

    - `rate_limit: optional object { period_ms, requests, technique }`

      - `period_ms: optional number`

      - `requests: optional number`

      - `technique: optional "fixed" or "sliding"`

        - `"fixed"`

        - `"sliding"`

    - `search_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable search endpoint for this public endpoint

  - `reranking: optional boolean`

  - `reranking_model: optional "@cf/baai/bge-reranker-base" or ""`

    - `"@cf/baai/bge-reranker-base"`

    - `""`

  - `retrieval_options: optional object { boost_by, keyword_match_mode }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Each entry specifies a metadata field and an optional direction. Direction defaults to 'asc' for numeric/datetime fields and 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

  - `rewrite_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `rewrite_query: optional boolean`

  - `score_threshold: optional number`

  - `source: optional string`

  - `source_params: optional object { exclude_items, include_items, prefix, 2 more }`

    - `exclude_items: optional array of string`

      List of path patterns to exclude. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and /admin/settings/advanced)

    - `include_items: optional array of string`

      List of path patterns to include. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post)

    - `prefix: optional string`

    - `r2_jurisdiction: optional string`

    - `web_crawler: optional object { crawl_options, parse_options, parse_type, store_options }`

      - `crawl_options: optional object { depth, include_external_links, include_subdomains, 2 more }`

        - `depth: optional number`

        - `include_external_links: optional boolean`

        - `include_subdomains: optional boolean`

        - `max_age: optional number`

        - `source: optional "all" or "sitemaps" or "links"`

          - `"all"`

          - `"sitemaps"`

          - `"links"`

      - `parse_options: optional object { content_selector, include_headers, include_images, 2 more }`

        - `content_selector: optional array of object { path, selector }`

          List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first matching path wins. Only the matched HTML fragment is stored and indexed. Omit the field to disable content selection — empty arrays are rejected.

          - `path: string`

            Glob pattern to match against the page URL path. Uses standard glob syntax: * matches within a segment, ** crosses directories.

          - `selector: string`

            CSS selector to extract content from pages matching the path pattern. Must not contain disallowed characters (;, `, $, {, }, ). Must target a single element; if multiple elements match, the selector is ignored and the full page is used.

        - `include_headers: optional map[string]`

          Up to 5 custom HTTP headers sent with each crawl request. Names must be RFC-7230 token characters (no spaces, colons, or control characters); values must be HTAB + printable ASCII (no CR/LF).

        - `include_images: optional boolean`

        - `specific_sitemaps: optional array of string`

          List of specific sitemap URLs to use for crawling. Only valid when parse_type is 'sitemap'.

        - `use_browser_rendering: optional boolean`

      - `parse_type: optional "sitemap" or "feed-rss" or "crawl"`

        - `"sitemap"`

        - `"feed-rss"`

        - `"crawl"`

      - `store_options: optional object { storage_id, r2_jurisdiction, storage_type }`

        - `storage_id: string`

        - `r2_jurisdiction: optional string`

        - `storage_type: optional Provider`

          - `"r2"`

  - `status: optional string`

  - `sync_interval: optional 900 or 1800 or 3600 or 5 more`

    Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h).

    - `900`

    - `1800`

    - `3600`

    - `7200`

    - `14400`

    - `21600`

    - `43200`

    - `86400`

  - `token_id: optional string`

  - `type: optional "r2" or "web-crawler"`

    - `"r2"`

    - `"web-crawler"`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/instances \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
    -d '{
          "id": "my-ai-search"
        }'
```

#### Response

```json
{
  "result": {
    "id": "my-ai-search",
    "created_at": "2019-12-27T18:11:19.117Z",
    "modified_at": "2019-12-27T18:11:19.117Z",
    "ai_gateway_id": "ai_gateway_id",
    "ai_search_model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
    "cache": true,
    "cache_threshold": "super_strict_match",
    "cache_ttl": 600,
    "chunk_overlap": 0,
    "chunk_size": 64,
    "created_by": "created_by",
    "custom_metadata": [
      {
        "data_type": "text",
        "field_name": "x"
      }
    ],
    "embedding_model": "@cf/qwen/qwen3-embedding-0.6b",
    "enable": true,
    "engine_version": 0,
    "fusion_method": "max",
    "hybrid_search_enabled": true,
    "index_method": {
      "keyword": true,
      "vector": true
    },
    "indexing_options": {
      "keyword_tokenizer": "porter"
    },
    "last_activity": "2019-12-27T18:11:19.117Z",
    "max_num_results": 1,
    "metadata": {
      "created_from_aisearch_wizard": true,
      "worker_domain": "worker_domain"
    },
    "modified_by": "modified_by",
    "namespace": "namespace",
    "paused": true,
    "public_endpoint_id": "public_endpoint_id",
    "public_endpoint_params": {
      "authorized_hosts": [
        "string"
      ],
      "chat_completions_endpoint": {
        "disabled": true
      },
      "enabled": true,
      "mcp": {
        "description": "description",
        "disabled": true
      },
      "rate_limit": {
        "period_ms": 60000,
        "requests": 1,
        "technique": "fixed"
      },
      "search_endpoint": {
        "disabled": true
      }
    },
    "reranking": true,
    "reranking_model": "@cf/baai/bge-reranker-base",
    "retrieval_options": {
      "boost_by": [
        {
          "field": "timestamp",
          "direction": "desc"
        }
      ],
      "keyword_match_mode": "and"
    },
    "rewrite_model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
    "rewrite_query": true,
    "score_threshold": 0,
    "source": "source",
    "source_params": {
      "exclude_items": [
        "/admin/**",
        "/private/**",
        "**\\temp\\**"
      ],
      "include_items": [
        "/blog/**",
        "/docs/**/*.html",
        "**\\blog\\**.html"
      ],
      "prefix": "prefix",
      "r2_jurisdiction": "r2_jurisdiction",
      "web_crawler": {
        "crawl_options": {
          "depth": 1,
          "include_external_links": true,
          "include_subdomains": true,
          "max_age": 0,
          "source": "all"
        },
        "parse_options": {
          "content_selector": [
            {
              "path": "**/blog/**",
              "selector": "article div.post-body"
            },
            {
              "path": "**/docs/**",
              "selector": "main"
            }
          ],
          "include_headers": {
            "cache-control": "no-cache, no-store"
          },
          "include_images": true,
          "specific_sitemaps": [
            "https://example.com/sitemap.xml",
            "https://example.com/blog-sitemap.xml"
          ],
          "use_browser_rendering": true
        },
        "parse_type": "sitemap",
        "store_options": {
          "storage_id": "storage_id",
          "r2_jurisdiction": "r2_jurisdiction",
          "storage_type": "r2"
        }
      }
    },
    "status": "status",
    "sync_interval": 900,
    "token_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
    "type": "r2"
  },
  "success": true
}
```

## Read instance.

**get** `/accounts/{account_id}/ai-search/instances/{id}`

Read instance.

### Path Parameters

- `account_id: string`

- `id: string`

### Returns

- `result: object { id, created_at, modified_at, 36 more }`

  - `id: string`

    AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

  - `created_at: string`

  - `modified_at: string`

  - `ai_gateway_id: optional string`

  - `ai_search_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `cache: optional boolean`

  - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

    - `"super_strict_match"`

    - `"close_enough"`

    - `"flexible_friend"`

    - `"anything_goes"`

  - `cache_ttl: optional 600 or 1800 or 3600 or 7 more`

    Cache entry TTL in seconds. Allowed values: 600 (10min), 1800 (30min), 3600 (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d).

    - `600`

    - `1800`

    - `3600`

    - `7200`

    - `21600`

    - `43200`

    - `86400`

    - `172800`

    - `259200`

    - `518400`

  - `chunk_overlap: optional number`

  - `chunk_size: optional number`

  - `created_by: optional string`

  - `custom_metadata: optional array of object { data_type, field_name }`

    - `data_type: "text" or "number" or "boolean" or "datetime"`

      - `"text"`

      - `"number"`

      - `"boolean"`

      - `"datetime"`

    - `field_name: string`

  - `embedding_model: optional "@cf/qwen/qwen3-embedding-0.6b" or "@cf/baai/bge-m3" or "@cf/baai/bge-large-en-v1.5" or 6 more`

    - `"@cf/qwen/qwen3-embedding-0.6b"`

    - `"@cf/baai/bge-m3"`

    - `"@cf/baai/bge-large-en-v1.5"`

    - `"@cf/google/embeddinggemma-300m"`

    - `"google-ai-studio/gemini-embedding-001"`

    - `"google-ai-studio/gemini-embedding-2-preview"`

    - `"openai/text-embedding-3-small"`

    - `"openai/text-embedding-3-large"`

    - `""`

  - `enable: optional boolean`

  - `engine_version: optional number`

  - `fusion_method: optional "max" or "rrf"`

    - `"max"`

    - `"rrf"`

  - `hybrid_search_enabled: optional boolean`

    Deprecated — use index_method instead.

  - `index_method: optional object { keyword, vector }`

    Controls which storage backends are used during indexing. Defaults to vector-only.

    - `keyword: boolean`

      Enable keyword (BM25) storage backend.

    - `vector: boolean`

      Enable vector (embedding) storage backend.

  - `indexing_options: optional object { keyword_tokenizer }`

    - `keyword_tokenizer: optional "porter" or "trigram"`

      Tokenizer used for keyword search indexing. porter provides word-level tokenization with Porter stemming (good for natural language queries). trigram enables character-level substring matching (good for partial matches, code, identifiers). Changing this triggers a full re-index. Defaults to porter.

      - `"porter"`

      - `"trigram"`

  - `last_activity: optional string`

  - `max_num_results: optional number`

  - `metadata: optional object { created_from_aisearch_wizard, worker_domain }`

    - `created_from_aisearch_wizard: optional boolean`

    - `worker_domain: optional string`

  - `modified_by: optional string`

  - `namespace: optional string`

  - `paused: optional boolean`

  - `public_endpoint_id: optional string`

  - `public_endpoint_params: optional object { authorized_hosts, chat_completions_endpoint, enabled, 3 more }`

    - `authorized_hosts: optional array of string`

    - `chat_completions_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable chat completions endpoint for this public endpoint

    - `enabled: optional boolean`

    - `mcp: optional object { description, disabled }`

      - `description: optional string`

      - `disabled: optional boolean`

        Disable MCP endpoint for this public endpoint

    - `rate_limit: optional object { period_ms, requests, technique }`

      - `period_ms: optional number`

      - `requests: optional number`

      - `technique: optional "fixed" or "sliding"`

        - `"fixed"`

        - `"sliding"`

    - `search_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable search endpoint for this public endpoint

  - `reranking: optional boolean`

  - `reranking_model: optional "@cf/baai/bge-reranker-base" or ""`

    - `"@cf/baai/bge-reranker-base"`

    - `""`

  - `retrieval_options: optional object { boost_by, keyword_match_mode }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Each entry specifies a metadata field and an optional direction. Direction defaults to 'asc' for numeric/datetime fields and 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

  - `rewrite_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `rewrite_query: optional boolean`

  - `score_threshold: optional number`

  - `source: optional string`

  - `source_params: optional object { exclude_items, include_items, prefix, 2 more }`

    - `exclude_items: optional array of string`

      List of path patterns to exclude. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and /admin/settings/advanced)

    - `include_items: optional array of string`

      List of path patterns to include. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post)

    - `prefix: optional string`

    - `r2_jurisdiction: optional string`

    - `web_crawler: optional object { crawl_options, parse_options, parse_type, store_options }`

      - `crawl_options: optional object { depth, include_external_links, include_subdomains, 2 more }`

        - `depth: optional number`

        - `include_external_links: optional boolean`

        - `include_subdomains: optional boolean`

        - `max_age: optional number`

        - `source: optional "all" or "sitemaps" or "links"`

          - `"all"`

          - `"sitemaps"`

          - `"links"`

      - `parse_options: optional object { content_selector, include_headers, include_images, 2 more }`

        - `content_selector: optional array of object { path, selector }`

          List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first matching path wins. Only the matched HTML fragment is stored and indexed. Omit the field to disable content selection — empty arrays are rejected.

          - `path: string`

            Glob pattern to match against the page URL path. Uses standard glob syntax: * matches within a segment, ** crosses directories.

          - `selector: string`

            CSS selector to extract content from pages matching the path pattern. Must not contain disallowed characters (;, `, $, {, }, ). Must target a single element; if multiple elements match, the selector is ignored and the full page is used.

        - `include_headers: optional map[string]`

          Up to 5 custom HTTP headers sent with each crawl request. Names must be RFC-7230 token characters (no spaces, colons, or control characters); values must be HTAB + printable ASCII (no CR/LF).

        - `include_images: optional boolean`

        - `specific_sitemaps: optional array of string`

          List of specific sitemap URLs to use for crawling. Only valid when parse_type is 'sitemap'.

        - `use_browser_rendering: optional boolean`

      - `parse_type: optional "sitemap" or "feed-rss" or "crawl"`

        - `"sitemap"`

        - `"feed-rss"`

        - `"crawl"`

      - `store_options: optional object { storage_id, r2_jurisdiction, storage_type }`

        - `storage_id: string`

        - `r2_jurisdiction: optional string`

        - `storage_type: optional Provider`

          - `"r2"`

  - `status: optional string`

  - `sync_interval: optional 900 or 1800 or 3600 or 5 more`

    Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h).

    - `900`

    - `1800`

    - `3600`

    - `7200`

    - `14400`

    - `21600`

    - `43200`

    - `86400`

  - `token_id: optional string`

  - `type: optional "r2" or "web-crawler"`

    - `"r2"`

    - `"web-crawler"`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/instances/$ID \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": {
    "id": "my-ai-search",
    "created_at": "2019-12-27T18:11:19.117Z",
    "modified_at": "2019-12-27T18:11:19.117Z",
    "ai_gateway_id": "ai_gateway_id",
    "ai_search_model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
    "cache": true,
    "cache_threshold": "super_strict_match",
    "cache_ttl": 600,
    "chunk_overlap": 0,
    "chunk_size": 64,
    "created_by": "created_by",
    "custom_metadata": [
      {
        "data_type": "text",
        "field_name": "x"
      }
    ],
    "embedding_model": "@cf/qwen/qwen3-embedding-0.6b",
    "enable": true,
    "engine_version": 0,
    "fusion_method": "max",
    "hybrid_search_enabled": true,
    "index_method": {
      "keyword": true,
      "vector": true
    },
    "indexing_options": {
      "keyword_tokenizer": "porter"
    },
    "last_activity": "2019-12-27T18:11:19.117Z",
    "max_num_results": 1,
    "metadata": {
      "created_from_aisearch_wizard": true,
      "worker_domain": "worker_domain"
    },
    "modified_by": "modified_by",
    "namespace": "namespace",
    "paused": true,
    "public_endpoint_id": "public_endpoint_id",
    "public_endpoint_params": {
      "authorized_hosts": [
        "string"
      ],
      "chat_completions_endpoint": {
        "disabled": true
      },
      "enabled": true,
      "mcp": {
        "description": "description",
        "disabled": true
      },
      "rate_limit": {
        "period_ms": 60000,
        "requests": 1,
        "technique": "fixed"
      },
      "search_endpoint": {
        "disabled": true
      }
    },
    "reranking": true,
    "reranking_model": "@cf/baai/bge-reranker-base",
    "retrieval_options": {
      "boost_by": [
        {
          "field": "timestamp",
          "direction": "desc"
        }
      ],
      "keyword_match_mode": "and"
    },
    "rewrite_model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
    "rewrite_query": true,
    "score_threshold": 0,
    "source": "source",
    "source_params": {
      "exclude_items": [
        "/admin/**",
        "/private/**",
        "**\\temp\\**"
      ],
      "include_items": [
        "/blog/**",
        "/docs/**/*.html",
        "**\\blog\\**.html"
      ],
      "prefix": "prefix",
      "r2_jurisdiction": "r2_jurisdiction",
      "web_crawler": {
        "crawl_options": {
          "depth": 1,
          "include_external_links": true,
          "include_subdomains": true,
          "max_age": 0,
          "source": "all"
        },
        "parse_options": {
          "content_selector": [
            {
              "path": "**/blog/**",
              "selector": "article div.post-body"
            },
            {
              "path": "**/docs/**",
              "selector": "main"
            }
          ],
          "include_headers": {
            "cache-control": "no-cache, no-store"
          },
          "include_images": true,
          "specific_sitemaps": [
            "https://example.com/sitemap.xml",
            "https://example.com/blog-sitemap.xml"
          ],
          "use_browser_rendering": true
        },
        "parse_type": "sitemap",
        "store_options": {
          "storage_id": "storage_id",
          "r2_jurisdiction": "r2_jurisdiction",
          "storage_type": "r2"
        }
      }
    },
    "status": "status",
    "sync_interval": 900,
    "token_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
    "type": "r2"
  },
  "success": true
}
```

## Update instance.

**put** `/accounts/{account_id}/ai-search/instances/{id}`

Update instance.

### Path Parameters

- `account_id: string`

- `id: string`

### Body Parameters

- `ai_gateway_id: optional string`

- `ai_search_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

  - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

  - `"@cf/zai-org/glm-4.7-flash"`

  - `"@cf/meta/llama-3.1-8b-instruct-fast"`

  - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

  - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

  - `"@cf/qwen/qwen3-30b-a3b-fp8"`

  - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

  - `"@cf/moonshotai/kimi-k2-instruct"`

  - `"@cf/google/gemma-3-12b-it"`

  - `"@cf/google/gemma-4-26b-a4b-it"`

  - `"@cf/moonshotai/kimi-k2.5"`

  - `"anthropic/claude-3-7-sonnet"`

  - `"anthropic/claude-sonnet-4"`

  - `"anthropic/claude-opus-4"`

  - `"anthropic/claude-3-5-haiku"`

  - `"cerebras/qwen-3-235b-a22b-instruct"`

  - `"cerebras/qwen-3-235b-a22b-thinking"`

  - `"cerebras/llama-3.3-70b"`

  - `"cerebras/llama-4-maverick-17b-128e-instruct"`

  - `"cerebras/llama-4-scout-17b-16e-instruct"`

  - `"cerebras/gpt-oss-120b"`

  - `"google-ai-studio/gemini-2.5-flash"`

  - `"google-ai-studio/gemini-2.5-pro"`

  - `"grok/grok-4"`

  - `"groq/llama-3.3-70b-versatile"`

  - `"groq/llama-3.1-8b-instant"`

  - `"openai/gpt-5"`

  - `"openai/gpt-5-mini"`

  - `"openai/gpt-5-nano"`

  - `""`

- `cache: optional boolean`

- `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

  - `"super_strict_match"`

  - `"close_enough"`

  - `"flexible_friend"`

  - `"anything_goes"`

- `cache_ttl: optional 600 or 1800 or 3600 or 7 more`

  Cache entry TTL in seconds. Allowed values: 600 (10min), 1800 (30min), 3600 (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d).

  - `600`

  - `1800`

  - `3600`

  - `7200`

  - `21600`

  - `43200`

  - `86400`

  - `172800`

  - `259200`

  - `518400`

- `chunk: optional boolean`

- `chunk_overlap: optional number`

- `chunk_size: optional number`

- `custom_metadata: optional array of object { data_type, field_name }`

  - `data_type: "text" or "number" or "boolean" or "datetime"`

    - `"text"`

    - `"number"`

    - `"boolean"`

    - `"datetime"`

  - `field_name: string`

- `embedding_model: optional "@cf/qwen/qwen3-embedding-0.6b" or "@cf/baai/bge-m3" or "@cf/baai/bge-large-en-v1.5" or 6 more`

  - `"@cf/qwen/qwen3-embedding-0.6b"`

  - `"@cf/baai/bge-m3"`

  - `"@cf/baai/bge-large-en-v1.5"`

  - `"@cf/google/embeddinggemma-300m"`

  - `"google-ai-studio/gemini-embedding-001"`

  - `"google-ai-studio/gemini-embedding-2-preview"`

  - `"openai/text-embedding-3-small"`

  - `"openai/text-embedding-3-large"`

  - `""`

- `fusion_method: optional "max" or "rrf"`

  - `"max"`

  - `"rrf"`

- `index_method: optional object { keyword, vector }`

  Controls which storage backends are used during indexing. Defaults to vector-only.

  - `keyword: boolean`

    Enable keyword (BM25) storage backend.

  - `vector: boolean`

    Enable vector (embedding) storage backend.

- `indexing_options: optional object { keyword_tokenizer }`

  - `keyword_tokenizer: optional "porter" or "trigram"`

    Tokenizer used for keyword search indexing. porter provides word-level tokenization with Porter stemming (good for natural language queries). trigram enables character-level substring matching (good for partial matches, code, identifiers). Changing this triggers a full re-index. Defaults to porter.

    - `"porter"`

    - `"trigram"`

- `max_num_results: optional number`

- `metadata: optional object { created_from_aisearch_wizard, worker_domain }`

  - `created_from_aisearch_wizard: optional boolean`

  - `worker_domain: optional string`

- `paused: optional boolean`

- `public_endpoint_params: optional object { authorized_hosts, chat_completions_endpoint, enabled, 3 more }`

  - `authorized_hosts: optional array of string`

  - `chat_completions_endpoint: optional object { disabled }`

    - `disabled: optional boolean`

      Disable chat completions endpoint for this public endpoint

  - `enabled: optional boolean`

  - `mcp: optional object { description, disabled }`

    - `description: optional string`

    - `disabled: optional boolean`

      Disable MCP endpoint for this public endpoint

  - `rate_limit: optional object { period_ms, requests, technique }`

    - `period_ms: optional number`

    - `requests: optional number`

    - `technique: optional "fixed" or "sliding"`

      - `"fixed"`

      - `"sliding"`

  - `search_endpoint: optional object { disabled }`

    - `disabled: optional boolean`

      Disable search endpoint for this public endpoint

- `reranking: optional boolean`

- `reranking_model: optional "@cf/baai/bge-reranker-base" or ""`

  - `"@cf/baai/bge-reranker-base"`

  - `""`

- `retrieval_options: optional object { boost_by, keyword_match_mode }`

  - `boost_by: optional array of object { field, direction }`

    Metadata fields to boost search results by. Each entry specifies a metadata field and an optional direction. Direction defaults to 'asc' for numeric/datetime fields and 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

    - `field: string`

      Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

    - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

      Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

      - `"asc"`

      - `"desc"`

      - `"exists"`

      - `"not_exists"`

  - `keyword_match_mode: optional "and" or "or"`

    Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

    - `"and"`

    - `"or"`

- `rewrite_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

  - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

  - `"@cf/zai-org/glm-4.7-flash"`

  - `"@cf/meta/llama-3.1-8b-instruct-fast"`

  - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

  - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

  - `"@cf/qwen/qwen3-30b-a3b-fp8"`

  - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

  - `"@cf/moonshotai/kimi-k2-instruct"`

  - `"@cf/google/gemma-3-12b-it"`

  - `"@cf/google/gemma-4-26b-a4b-it"`

  - `"@cf/moonshotai/kimi-k2.5"`

  - `"anthropic/claude-3-7-sonnet"`

  - `"anthropic/claude-sonnet-4"`

  - `"anthropic/claude-opus-4"`

  - `"anthropic/claude-3-5-haiku"`

  - `"cerebras/qwen-3-235b-a22b-instruct"`

  - `"cerebras/qwen-3-235b-a22b-thinking"`

  - `"cerebras/llama-3.3-70b"`

  - `"cerebras/llama-4-maverick-17b-128e-instruct"`

  - `"cerebras/llama-4-scout-17b-16e-instruct"`

  - `"cerebras/gpt-oss-120b"`

  - `"google-ai-studio/gemini-2.5-flash"`

  - `"google-ai-studio/gemini-2.5-pro"`

  - `"grok/grok-4"`

  - `"groq/llama-3.3-70b-versatile"`

  - `"groq/llama-3.1-8b-instant"`

  - `"openai/gpt-5"`

  - `"openai/gpt-5-mini"`

  - `"openai/gpt-5-nano"`

  - `""`

- `rewrite_query: optional boolean`

- `score_threshold: optional number`

- `source_params: optional object { exclude_items, include_items, prefix, 2 more }`

  - `exclude_items: optional array of string`

    List of path patterns to exclude. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and /admin/settings/advanced)

  - `include_items: optional array of string`

    List of path patterns to include. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post)

  - `prefix: optional string`

  - `r2_jurisdiction: optional string`

  - `web_crawler: optional object { crawl_options, parse_options, parse_type, store_options }`

    - `crawl_options: optional object { depth, include_external_links, include_subdomains, 2 more }`

      - `depth: optional number`

      - `include_external_links: optional boolean`

      - `include_subdomains: optional boolean`

      - `max_age: optional number`

      - `source: optional "all" or "sitemaps" or "links"`

        - `"all"`

        - `"sitemaps"`

        - `"links"`

    - `parse_options: optional object { content_selector, include_headers, include_images, 2 more }`

      - `content_selector: optional array of object { path, selector }`

        List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first matching path wins. Only the matched HTML fragment is stored and indexed. Omit the field to disable content selection — empty arrays are rejected.

        - `path: string`

          Glob pattern to match against the page URL path. Uses standard glob syntax: * matches within a segment, ** crosses directories.

        - `selector: string`

          CSS selector to extract content from pages matching the path pattern. Must not contain disallowed characters (;, `, $, {, }, ). Must target a single element; if multiple elements match, the selector is ignored and the full page is used.

      - `include_headers: optional map[string]`

        Up to 5 custom HTTP headers sent with each crawl request. Names must be RFC-7230 token characters (no spaces, colons, or control characters); values must be HTAB + printable ASCII (no CR/LF).

      - `include_images: optional boolean`

      - `specific_sitemaps: optional array of string`

        List of specific sitemap URLs to use for crawling. Only valid when parse_type is 'sitemap'.

      - `use_browser_rendering: optional boolean`

    - `parse_type: optional "sitemap" or "feed-rss" or "crawl"`

      - `"sitemap"`

      - `"feed-rss"`

      - `"crawl"`

    - `store_options: optional object { storage_id, r2_jurisdiction, storage_type }`

      - `storage_id: string`

      - `r2_jurisdiction: optional string`

      - `storage_type: optional Provider`

        - `"r2"`

- `summarization: optional boolean`

- `summarization_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

  - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

  - `"@cf/zai-org/glm-4.7-flash"`

  - `"@cf/meta/llama-3.1-8b-instruct-fast"`

  - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

  - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

  - `"@cf/qwen/qwen3-30b-a3b-fp8"`

  - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

  - `"@cf/moonshotai/kimi-k2-instruct"`

  - `"@cf/google/gemma-3-12b-it"`

  - `"@cf/google/gemma-4-26b-a4b-it"`

  - `"@cf/moonshotai/kimi-k2.5"`

  - `"anthropic/claude-3-7-sonnet"`

  - `"anthropic/claude-sonnet-4"`

  - `"anthropic/claude-opus-4"`

  - `"anthropic/claude-3-5-haiku"`

  - `"cerebras/qwen-3-235b-a22b-instruct"`

  - `"cerebras/qwen-3-235b-a22b-thinking"`

  - `"cerebras/llama-3.3-70b"`

  - `"cerebras/llama-4-maverick-17b-128e-instruct"`

  - `"cerebras/llama-4-scout-17b-16e-instruct"`

  - `"cerebras/gpt-oss-120b"`

  - `"google-ai-studio/gemini-2.5-flash"`

  - `"google-ai-studio/gemini-2.5-pro"`

  - `"grok/grok-4"`

  - `"groq/llama-3.3-70b-versatile"`

  - `"groq/llama-3.1-8b-instant"`

  - `"openai/gpt-5"`

  - `"openai/gpt-5-mini"`

  - `"openai/gpt-5-nano"`

  - `""`

- `sync_interval: optional 900 or 1800 or 3600 or 5 more`

  Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h).

  - `900`

  - `1800`

  - `3600`

  - `7200`

  - `14400`

  - `21600`

  - `43200`

  - `86400`

- `system_prompt_ai_search: optional string`

- `system_prompt_index_summarization: optional string`

- `system_prompt_rewrite_query: optional string`

- `token_id: optional string`

### Returns

- `result: object { id, created_at, modified_at, 36 more }`

  - `id: string`

    AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

  - `created_at: string`

  - `modified_at: string`

  - `ai_gateway_id: optional string`

  - `ai_search_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `cache: optional boolean`

  - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

    - `"super_strict_match"`

    - `"close_enough"`

    - `"flexible_friend"`

    - `"anything_goes"`

  - `cache_ttl: optional 600 or 1800 or 3600 or 7 more`

    Cache entry TTL in seconds. Allowed values: 600 (10min), 1800 (30min), 3600 (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d).

    - `600`

    - `1800`

    - `3600`

    - `7200`

    - `21600`

    - `43200`

    - `86400`

    - `172800`

    - `259200`

    - `518400`

  - `chunk_overlap: optional number`

  - `chunk_size: optional number`

  - `created_by: optional string`

  - `custom_metadata: optional array of object { data_type, field_name }`

    - `data_type: "text" or "number" or "boolean" or "datetime"`

      - `"text"`

      - `"number"`

      - `"boolean"`

      - `"datetime"`

    - `field_name: string`

  - `embedding_model: optional "@cf/qwen/qwen3-embedding-0.6b" or "@cf/baai/bge-m3" or "@cf/baai/bge-large-en-v1.5" or 6 more`

    - `"@cf/qwen/qwen3-embedding-0.6b"`

    - `"@cf/baai/bge-m3"`

    - `"@cf/baai/bge-large-en-v1.5"`

    - `"@cf/google/embeddinggemma-300m"`

    - `"google-ai-studio/gemini-embedding-001"`

    - `"google-ai-studio/gemini-embedding-2-preview"`

    - `"openai/text-embedding-3-small"`

    - `"openai/text-embedding-3-large"`

    - `""`

  - `enable: optional boolean`

  - `engine_version: optional number`

  - `fusion_method: optional "max" or "rrf"`

    - `"max"`

    - `"rrf"`

  - `hybrid_search_enabled: optional boolean`

    Deprecated — use index_method instead.

  - `index_method: optional object { keyword, vector }`

    Controls which storage backends are used during indexing. Defaults to vector-only.

    - `keyword: boolean`

      Enable keyword (BM25) storage backend.

    - `vector: boolean`

      Enable vector (embedding) storage backend.

  - `indexing_options: optional object { keyword_tokenizer }`

    - `keyword_tokenizer: optional "porter" or "trigram"`

      Tokenizer used for keyword search indexing. porter provides word-level tokenization with Porter stemming (good for natural language queries). trigram enables character-level substring matching (good for partial matches, code, identifiers). Changing this triggers a full re-index. Defaults to porter.

      - `"porter"`

      - `"trigram"`

  - `last_activity: optional string`

  - `max_num_results: optional number`

  - `metadata: optional object { created_from_aisearch_wizard, worker_domain }`

    - `created_from_aisearch_wizard: optional boolean`

    - `worker_domain: optional string`

  - `modified_by: optional string`

  - `namespace: optional string`

  - `paused: optional boolean`

  - `public_endpoint_id: optional string`

  - `public_endpoint_params: optional object { authorized_hosts, chat_completions_endpoint, enabled, 3 more }`

    - `authorized_hosts: optional array of string`

    - `chat_completions_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable chat completions endpoint for this public endpoint

    - `enabled: optional boolean`

    - `mcp: optional object { description, disabled }`

      - `description: optional string`

      - `disabled: optional boolean`

        Disable MCP endpoint for this public endpoint

    - `rate_limit: optional object { period_ms, requests, technique }`

      - `period_ms: optional number`

      - `requests: optional number`

      - `technique: optional "fixed" or "sliding"`

        - `"fixed"`

        - `"sliding"`

    - `search_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable search endpoint for this public endpoint

  - `reranking: optional boolean`

  - `reranking_model: optional "@cf/baai/bge-reranker-base" or ""`

    - `"@cf/baai/bge-reranker-base"`

    - `""`

  - `retrieval_options: optional object { boost_by, keyword_match_mode }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Each entry specifies a metadata field and an optional direction. Direction defaults to 'asc' for numeric/datetime fields and 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

  - `rewrite_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `rewrite_query: optional boolean`

  - `score_threshold: optional number`

  - `source: optional string`

  - `source_params: optional object { exclude_items, include_items, prefix, 2 more }`

    - `exclude_items: optional array of string`

      List of path patterns to exclude. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and /admin/settings/advanced)

    - `include_items: optional array of string`

      List of path patterns to include. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post)

    - `prefix: optional string`

    - `r2_jurisdiction: optional string`

    - `web_crawler: optional object { crawl_options, parse_options, parse_type, store_options }`

      - `crawl_options: optional object { depth, include_external_links, include_subdomains, 2 more }`

        - `depth: optional number`

        - `include_external_links: optional boolean`

        - `include_subdomains: optional boolean`

        - `max_age: optional number`

        - `source: optional "all" or "sitemaps" or "links"`

          - `"all"`

          - `"sitemaps"`

          - `"links"`

      - `parse_options: optional object { content_selector, include_headers, include_images, 2 more }`

        - `content_selector: optional array of object { path, selector }`

          List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first matching path wins. Only the matched HTML fragment is stored and indexed. Omit the field to disable content selection — empty arrays are rejected.

          - `path: string`

            Glob pattern to match against the page URL path. Uses standard glob syntax: * matches within a segment, ** crosses directories.

          - `selector: string`

            CSS selector to extract content from pages matching the path pattern. Must not contain disallowed characters (;, `, $, {, }, ). Must target a single element; if multiple elements match, the selector is ignored and the full page is used.

        - `include_headers: optional map[string]`

          Up to 5 custom HTTP headers sent with each crawl request. Names must be RFC-7230 token characters (no spaces, colons, or control characters); values must be HTAB + printable ASCII (no CR/LF).

        - `include_images: optional boolean`

        - `specific_sitemaps: optional array of string`

          List of specific sitemap URLs to use for crawling. Only valid when parse_type is 'sitemap'.

        - `use_browser_rendering: optional boolean`

      - `parse_type: optional "sitemap" or "feed-rss" or "crawl"`

        - `"sitemap"`

        - `"feed-rss"`

        - `"crawl"`

      - `store_options: optional object { storage_id, r2_jurisdiction, storage_type }`

        - `storage_id: string`

        - `r2_jurisdiction: optional string`

        - `storage_type: optional Provider`

          - `"r2"`

  - `status: optional string`

  - `sync_interval: optional 900 or 1800 or 3600 or 5 more`

    Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h).

    - `900`

    - `1800`

    - `3600`

    - `7200`

    - `14400`

    - `21600`

    - `43200`

    - `86400`

  - `token_id: optional string`

  - `type: optional "r2" or "web-crawler"`

    - `"r2"`

    - `"web-crawler"`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/instances/$ID \
    -X PUT \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": {
    "id": "my-ai-search",
    "created_at": "2019-12-27T18:11:19.117Z",
    "modified_at": "2019-12-27T18:11:19.117Z",
    "ai_gateway_id": "ai_gateway_id",
    "ai_search_model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
    "cache": true,
    "cache_threshold": "super_strict_match",
    "cache_ttl": 600,
    "chunk_overlap": 0,
    "chunk_size": 64,
    "created_by": "created_by",
    "custom_metadata": [
      {
        "data_type": "text",
        "field_name": "x"
      }
    ],
    "embedding_model": "@cf/qwen/qwen3-embedding-0.6b",
    "enable": true,
    "engine_version": 0,
    "fusion_method": "max",
    "hybrid_search_enabled": true,
    "index_method": {
      "keyword": true,
      "vector": true
    },
    "indexing_options": {
      "keyword_tokenizer": "porter"
    },
    "last_activity": "2019-12-27T18:11:19.117Z",
    "max_num_results": 1,
    "metadata": {
      "created_from_aisearch_wizard": true,
      "worker_domain": "worker_domain"
    },
    "modified_by": "modified_by",
    "namespace": "namespace",
    "paused": true,
    "public_endpoint_id": "public_endpoint_id",
    "public_endpoint_params": {
      "authorized_hosts": [
        "string"
      ],
      "chat_completions_endpoint": {
        "disabled": true
      },
      "enabled": true,
      "mcp": {
        "description": "description",
        "disabled": true
      },
      "rate_limit": {
        "period_ms": 60000,
        "requests": 1,
        "technique": "fixed"
      },
      "search_endpoint": {
        "disabled": true
      }
    },
    "reranking": true,
    "reranking_model": "@cf/baai/bge-reranker-base",
    "retrieval_options": {
      "boost_by": [
        {
          "field": "timestamp",
          "direction": "desc"
        }
      ],
      "keyword_match_mode": "and"
    },
    "rewrite_model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
    "rewrite_query": true,
    "score_threshold": 0,
    "source": "source",
    "source_params": {
      "exclude_items": [
        "/admin/**",
        "/private/**",
        "**\\temp\\**"
      ],
      "include_items": [
        "/blog/**",
        "/docs/**/*.html",
        "**\\blog\\**.html"
      ],
      "prefix": "prefix",
      "r2_jurisdiction": "r2_jurisdiction",
      "web_crawler": {
        "crawl_options": {
          "depth": 1,
          "include_external_links": true,
          "include_subdomains": true,
          "max_age": 0,
          "source": "all"
        },
        "parse_options": {
          "content_selector": [
            {
              "path": "**/blog/**",
              "selector": "article div.post-body"
            },
            {
              "path": "**/docs/**",
              "selector": "main"
            }
          ],
          "include_headers": {
            "cache-control": "no-cache, no-store"
          },
          "include_images": true,
          "specific_sitemaps": [
            "https://example.com/sitemap.xml",
            "https://example.com/blog-sitemap.xml"
          ],
          "use_browser_rendering": true
        },
        "parse_type": "sitemap",
        "store_options": {
          "storage_id": "storage_id",
          "r2_jurisdiction": "r2_jurisdiction",
          "storage_type": "r2"
        }
      }
    },
    "status": "status",
    "sync_interval": 900,
    "token_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
    "type": "r2"
  },
  "success": true
}
```

## Delete instance.

**delete** `/accounts/{account_id}/ai-search/instances/{id}`

Delete instance.

### Path Parameters

- `account_id: string`

- `id: string`

### Returns

- `result: object { id, created_at, modified_at, 36 more }`

  - `id: string`

    AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

  - `created_at: string`

  - `modified_at: string`

  - `ai_gateway_id: optional string`

  - `ai_search_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `cache: optional boolean`

  - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

    - `"super_strict_match"`

    - `"close_enough"`

    - `"flexible_friend"`

    - `"anything_goes"`

  - `cache_ttl: optional 600 or 1800 or 3600 or 7 more`

    Cache entry TTL in seconds. Allowed values: 600 (10min), 1800 (30min), 3600 (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d).

    - `600`

    - `1800`

    - `3600`

    - `7200`

    - `21600`

    - `43200`

    - `86400`

    - `172800`

    - `259200`

    - `518400`

  - `chunk_overlap: optional number`

  - `chunk_size: optional number`

  - `created_by: optional string`

  - `custom_metadata: optional array of object { data_type, field_name }`

    - `data_type: "text" or "number" or "boolean" or "datetime"`

      - `"text"`

      - `"number"`

      - `"boolean"`

      - `"datetime"`

    - `field_name: string`

  - `embedding_model: optional "@cf/qwen/qwen3-embedding-0.6b" or "@cf/baai/bge-m3" or "@cf/baai/bge-large-en-v1.5" or 6 more`

    - `"@cf/qwen/qwen3-embedding-0.6b"`

    - `"@cf/baai/bge-m3"`

    - `"@cf/baai/bge-large-en-v1.5"`

    - `"@cf/google/embeddinggemma-300m"`

    - `"google-ai-studio/gemini-embedding-001"`

    - `"google-ai-studio/gemini-embedding-2-preview"`

    - `"openai/text-embedding-3-small"`

    - `"openai/text-embedding-3-large"`

    - `""`

  - `enable: optional boolean`

  - `engine_version: optional number`

  - `fusion_method: optional "max" or "rrf"`

    - `"max"`

    - `"rrf"`

  - `hybrid_search_enabled: optional boolean`

    Deprecated — use index_method instead.

  - `index_method: optional object { keyword, vector }`

    Controls which storage backends are used during indexing. Defaults to vector-only.

    - `keyword: boolean`

      Enable keyword (BM25) storage backend.

    - `vector: boolean`

      Enable vector (embedding) storage backend.

  - `indexing_options: optional object { keyword_tokenizer }`

    - `keyword_tokenizer: optional "porter" or "trigram"`

      Tokenizer used for keyword search indexing. porter provides word-level tokenization with Porter stemming (good for natural language queries). trigram enables character-level substring matching (good for partial matches, code, identifiers). Changing this triggers a full re-index. Defaults to porter.

      - `"porter"`

      - `"trigram"`

  - `last_activity: optional string`

  - `max_num_results: optional number`

  - `metadata: optional object { created_from_aisearch_wizard, worker_domain }`

    - `created_from_aisearch_wizard: optional boolean`

    - `worker_domain: optional string`

  - `modified_by: optional string`

  - `namespace: optional string`

  - `paused: optional boolean`

  - `public_endpoint_id: optional string`

  - `public_endpoint_params: optional object { authorized_hosts, chat_completions_endpoint, enabled, 3 more }`

    - `authorized_hosts: optional array of string`

    - `chat_completions_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable chat completions endpoint for this public endpoint

    - `enabled: optional boolean`

    - `mcp: optional object { description, disabled }`

      - `description: optional string`

      - `disabled: optional boolean`

        Disable MCP endpoint for this public endpoint

    - `rate_limit: optional object { period_ms, requests, technique }`

      - `period_ms: optional number`

      - `requests: optional number`

      - `technique: optional "fixed" or "sliding"`

        - `"fixed"`

        - `"sliding"`

    - `search_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable search endpoint for this public endpoint

  - `reranking: optional boolean`

  - `reranking_model: optional "@cf/baai/bge-reranker-base" or ""`

    - `"@cf/baai/bge-reranker-base"`

    - `""`

  - `retrieval_options: optional object { boost_by, keyword_match_mode }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Each entry specifies a metadata field and an optional direction. Direction defaults to 'asc' for numeric/datetime fields and 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

  - `rewrite_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `rewrite_query: optional boolean`

  - `score_threshold: optional number`

  - `source: optional string`

  - `source_params: optional object { exclude_items, include_items, prefix, 2 more }`

    - `exclude_items: optional array of string`

      List of path patterns to exclude. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and /admin/settings/advanced)

    - `include_items: optional array of string`

      List of path patterns to include. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post)

    - `prefix: optional string`

    - `r2_jurisdiction: optional string`

    - `web_crawler: optional object { crawl_options, parse_options, parse_type, store_options }`

      - `crawl_options: optional object { depth, include_external_links, include_subdomains, 2 more }`

        - `depth: optional number`

        - `include_external_links: optional boolean`

        - `include_subdomains: optional boolean`

        - `max_age: optional number`

        - `source: optional "all" or "sitemaps" or "links"`

          - `"all"`

          - `"sitemaps"`

          - `"links"`

      - `parse_options: optional object { content_selector, include_headers, include_images, 2 more }`

        - `content_selector: optional array of object { path, selector }`

          List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first matching path wins. Only the matched HTML fragment is stored and indexed. Omit the field to disable content selection — empty arrays are rejected.

          - `path: string`

            Glob pattern to match against the page URL path. Uses standard glob syntax: * matches within a segment, ** crosses directories.

          - `selector: string`

            CSS selector to extract content from pages matching the path pattern. Must not contain disallowed characters (;, `, $, {, }, ). Must target a single element; if multiple elements match, the selector is ignored and the full page is used.

        - `include_headers: optional map[string]`

          Up to 5 custom HTTP headers sent with each crawl request. Names must be RFC-7230 token characters (no spaces, colons, or control characters); values must be HTAB + printable ASCII (no CR/LF).

        - `include_images: optional boolean`

        - `specific_sitemaps: optional array of string`

          List of specific sitemap URLs to use for crawling. Only valid when parse_type is 'sitemap'.

        - `use_browser_rendering: optional boolean`

      - `parse_type: optional "sitemap" or "feed-rss" or "crawl"`

        - `"sitemap"`

        - `"feed-rss"`

        - `"crawl"`

      - `store_options: optional object { storage_id, r2_jurisdiction, storage_type }`

        - `storage_id: string`

        - `r2_jurisdiction: optional string`

        - `storage_type: optional Provider`

          - `"r2"`

  - `status: optional string`

  - `sync_interval: optional 900 or 1800 or 3600 or 5 more`

    Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h).

    - `900`

    - `1800`

    - `3600`

    - `7200`

    - `14400`

    - `21600`

    - `43200`

    - `86400`

  - `token_id: optional string`

  - `type: optional "r2" or "web-crawler"`

    - `"r2"`

    - `"web-crawler"`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/instances/$ID \
    -X DELETE \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": {
    "id": "my-ai-search",
    "created_at": "2019-12-27T18:11:19.117Z",
    "modified_at": "2019-12-27T18:11:19.117Z",
    "ai_gateway_id": "ai_gateway_id",
    "ai_search_model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
    "cache": true,
    "cache_threshold": "super_strict_match",
    "cache_ttl": 600,
    "chunk_overlap": 0,
    "chunk_size": 64,
    "created_by": "created_by",
    "custom_metadata": [
      {
        "data_type": "text",
        "field_name": "x"
      }
    ],
    "embedding_model": "@cf/qwen/qwen3-embedding-0.6b",
    "enable": true,
    "engine_version": 0,
    "fusion_method": "max",
    "hybrid_search_enabled": true,
    "index_method": {
      "keyword": true,
      "vector": true
    },
    "indexing_options": {
      "keyword_tokenizer": "porter"
    },
    "last_activity": "2019-12-27T18:11:19.117Z",
    "max_num_results": 1,
    "metadata": {
      "created_from_aisearch_wizard": true,
      "worker_domain": "worker_domain"
    },
    "modified_by": "modified_by",
    "namespace": "namespace",
    "paused": true,
    "public_endpoint_id": "public_endpoint_id",
    "public_endpoint_params": {
      "authorized_hosts": [
        "string"
      ],
      "chat_completions_endpoint": {
        "disabled": true
      },
      "enabled": true,
      "mcp": {
        "description": "description",
        "disabled": true
      },
      "rate_limit": {
        "period_ms": 60000,
        "requests": 1,
        "technique": "fixed"
      },
      "search_endpoint": {
        "disabled": true
      }
    },
    "reranking": true,
    "reranking_model": "@cf/baai/bge-reranker-base",
    "retrieval_options": {
      "boost_by": [
        {
          "field": "timestamp",
          "direction": "desc"
        }
      ],
      "keyword_match_mode": "and"
    },
    "rewrite_model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
    "rewrite_query": true,
    "score_threshold": 0,
    "source": "source",
    "source_params": {
      "exclude_items": [
        "/admin/**",
        "/private/**",
        "**\\temp\\**"
      ],
      "include_items": [
        "/blog/**",
        "/docs/**/*.html",
        "**\\blog\\**.html"
      ],
      "prefix": "prefix",
      "r2_jurisdiction": "r2_jurisdiction",
      "web_crawler": {
        "crawl_options": {
          "depth": 1,
          "include_external_links": true,
          "include_subdomains": true,
          "max_age": 0,
          "source": "all"
        },
        "parse_options": {
          "content_selector": [
            {
              "path": "**/blog/**",
              "selector": "article div.post-body"
            },
            {
              "path": "**/docs/**",
              "selector": "main"
            }
          ],
          "include_headers": {
            "cache-control": "no-cache, no-store"
          },
          "include_images": true,
          "specific_sitemaps": [
            "https://example.com/sitemap.xml",
            "https://example.com/blog-sitemap.xml"
          ],
          "use_browser_rendering": true
        },
        "parse_type": "sitemap",
        "store_options": {
          "storage_id": "storage_id",
          "r2_jurisdiction": "r2_jurisdiction",
          "storage_type": "r2"
        }
      }
    },
    "status": "status",
    "sync_interval": 900,
    "token_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
    "type": "r2"
  },
  "success": true
}
```

## Stats

**get** `/accounts/{account_id}/ai-search/instances/{id}/stats`

Retrieves usage statistics for AI Search instances.

### Path Parameters

- `account_id: string`

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

### Returns

- `result: object { completed, degraded, engine, 8 more }`

  - `completed: optional number`

  - `degraded: optional boolean`

    True when status counts are unavailable (e.g. legacy stats query exceeded D1 statement-size limit). Counts are omitted in this case.

  - `engine: optional object { r2, vectorize }`

    Engine-specific metadata. Present only for managed (v3) instances.

    - `r2: optional object { metadataSizeBytes, objectCount, payloadSizeBytes }`

      R2 bucket storage usage in bytes.

      - `metadataSizeBytes: number`

      - `objectCount: number`

      - `payloadSizeBytes: number`

    - `vectorize: optional object { dimensions, vectorsCount }`

      Vectorize index metadata (dimensions, vector count).

      - `dimensions: number`

      - `vectorsCount: number`

  - `error: optional number`

  - `file_embed_errors: optional map[unknown]`

  - `index_source_errors: optional map[unknown]`

  - `last_activity: optional string`

  - `outdated: optional number`

  - `queued: optional number`

  - `running: optional number`

  - `skipped: optional number`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/instances/$ID/stats \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": {
    "completed": 0,
    "degraded": true,
    "engine": {
      "r2": {
        "metadataSizeBytes": 0,
        "objectCount": 0,
        "payloadSizeBytes": 0
      },
      "vectorize": {
        "dimensions": 0,
        "vectorsCount": 0
      }
    },
    "error": 0,
    "file_embed_errors": {
      "foo": "bar"
    },
    "index_source_errors": {
      "foo": "bar"
    },
    "last_activity": "2019-12-27T18:11:19.117Z",
    "outdated": 0,
    "queued": 0,
    "running": 0,
    "skipped": 0
  },
  "success": true
}
```

## Search

**post** `/accounts/{account_id}/ai-search/instances/{id}/search`

Executes a semantic search query against an AI Search instance to find relevant indexed content.

### Path Parameters

- `account_id: string`

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

### Body Parameters

- `ai_search_options: optional object { cache, query_rewrite, reranking, retrieval }`

  - `cache: optional object { cache_threshold, enabled }`

    - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

      - `"super_strict_match"`

      - `"close_enough"`

      - `"flexible_friend"`

      - `"anything_goes"`

    - `enabled: optional boolean`

  - `query_rewrite: optional object { enabled, model, rewrite_prompt }`

    - `enabled: optional boolean`

    - `model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

      - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

      - `"@cf/zai-org/glm-4.7-flash"`

      - `"@cf/meta/llama-3.1-8b-instruct-fast"`

      - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

      - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

      - `"@cf/qwen/qwen3-30b-a3b-fp8"`

      - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

      - `"@cf/moonshotai/kimi-k2-instruct"`

      - `"@cf/google/gemma-3-12b-it"`

      - `"@cf/google/gemma-4-26b-a4b-it"`

      - `"@cf/moonshotai/kimi-k2.5"`

      - `"anthropic/claude-3-7-sonnet"`

      - `"anthropic/claude-sonnet-4"`

      - `"anthropic/claude-opus-4"`

      - `"anthropic/claude-3-5-haiku"`

      - `"cerebras/qwen-3-235b-a22b-instruct"`

      - `"cerebras/qwen-3-235b-a22b-thinking"`

      - `"cerebras/llama-3.3-70b"`

      - `"cerebras/llama-4-maverick-17b-128e-instruct"`

      - `"cerebras/llama-4-scout-17b-16e-instruct"`

      - `"cerebras/gpt-oss-120b"`

      - `"google-ai-studio/gemini-2.5-flash"`

      - `"google-ai-studio/gemini-2.5-pro"`

      - `"grok/grok-4"`

      - `"groq/llama-3.3-70b-versatile"`

      - `"groq/llama-3.1-8b-instant"`

      - `"openai/gpt-5"`

      - `"openai/gpt-5-mini"`

      - `"openai/gpt-5-nano"`

      - `""`

    - `rewrite_prompt: optional string`

  - `reranking: optional object { enabled, match_threshold, model }`

    - `enabled: optional boolean`

    - `match_threshold: optional number`

    - `model: optional "@cf/baai/bge-reranker-base" or ""`

      - `"@cf/baai/bge-reranker-base"`

      - `""`

  - `retrieval: optional object { boost_by, context_expansion, filters, 6 more }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Overrides the instance-level boost_by config. Direction defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `context_expansion: optional number`

    - `filters: optional map[unknown]`

    - `fusion_method: optional "max" or "rrf"`

      - `"max"`

      - `"rrf"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

    - `match_threshold: optional number`

    - `max_num_results: optional number`

    - `retrieval_type: optional "vector" or "keyword" or "hybrid"`

      - `"vector"`

      - `"keyword"`

      - `"hybrid"`

    - `return_on_failure: optional boolean`

- `messages: optional array of object { content, role }`

  - `content: string`

  - `role: "system" or "developer" or "user" or 2 more`

    - `"system"`

    - `"developer"`

    - `"user"`

    - `"assistant"`

    - `"tool"`

- `query: optional string`

  A simple text query string. Alternative to 'messages' — provide either this or 'messages', not both.

### Returns

- `result: object { chunks, search_query }`

  - `chunks: array of object { id, score, text, 3 more }`

    - `id: string`

    - `score: number`

    - `text: string`

    - `type: string`

    - `item: optional object { key, metadata, timestamp }`

      - `key: string`

      - `metadata: optional map[unknown]`

      - `timestamp: optional number`

    - `scoring_details: optional object { fusion_method, keyword_rank, keyword_score, 3 more }`

      - `fusion_method: optional "rrf" or "max"`

        - `"rrf"`

        - `"max"`

      - `keyword_rank: optional number`

      - `keyword_score: optional number`

      - `reranking_score: optional number`

      - `vector_rank: optional number`

      - `vector_score: optional number`

  - `search_query: string`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/instances/$ID/search \
    -X POST \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": {
    "chunks": [
      {
        "id": "id",
        "score": 0,
        "text": "text",
        "type": "type",
        "item": {
          "key": "key",
          "metadata": {
            "foo": "bar"
          },
          "timestamp": 0
        },
        "scoring_details": {
          "fusion_method": "rrf",
          "keyword_rank": 0,
          "keyword_score": 0,
          "reranking_score": 0,
          "vector_rank": 0,
          "vector_score": 0
        }
      }
    ],
    "search_query": "search_query"
  },
  "success": true
}
```

## Chat Completions

**post** `/accounts/{account_id}/ai-search/instances/{id}/chat/completions`

Performs a chat completion request against an AI Search instance, using indexed content as context for generating responses.

### Path Parameters

- `account_id: string`

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

### Body Parameters

- `messages: array of object { content, role }`

  - `content: string`

  - `role: "system" or "developer" or "user" or 2 more`

    - `"system"`

    - `"developer"`

    - `"user"`

    - `"assistant"`

    - `"tool"`

- `ai_search_options: optional object { cache, query_rewrite, reranking, retrieval }`

  - `cache: optional object { cache_threshold, enabled }`

    - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

      - `"super_strict_match"`

      - `"close_enough"`

      - `"flexible_friend"`

      - `"anything_goes"`

    - `enabled: optional boolean`

  - `query_rewrite: optional object { enabled, model, rewrite_prompt }`

    - `enabled: optional boolean`

    - `model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

      - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

      - `"@cf/zai-org/glm-4.7-flash"`

      - `"@cf/meta/llama-3.1-8b-instruct-fast"`

      - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

      - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

      - `"@cf/qwen/qwen3-30b-a3b-fp8"`

      - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

      - `"@cf/moonshotai/kimi-k2-instruct"`

      - `"@cf/google/gemma-3-12b-it"`

      - `"@cf/google/gemma-4-26b-a4b-it"`

      - `"@cf/moonshotai/kimi-k2.5"`

      - `"anthropic/claude-3-7-sonnet"`

      - `"anthropic/claude-sonnet-4"`

      - `"anthropic/claude-opus-4"`

      - `"anthropic/claude-3-5-haiku"`

      - `"cerebras/qwen-3-235b-a22b-instruct"`

      - `"cerebras/qwen-3-235b-a22b-thinking"`

      - `"cerebras/llama-3.3-70b"`

      - `"cerebras/llama-4-maverick-17b-128e-instruct"`

      - `"cerebras/llama-4-scout-17b-16e-instruct"`

      - `"cerebras/gpt-oss-120b"`

      - `"google-ai-studio/gemini-2.5-flash"`

      - `"google-ai-studio/gemini-2.5-pro"`

      - `"grok/grok-4"`

      - `"groq/llama-3.3-70b-versatile"`

      - `"groq/llama-3.1-8b-instant"`

      - `"openai/gpt-5"`

      - `"openai/gpt-5-mini"`

      - `"openai/gpt-5-nano"`

      - `""`

    - `rewrite_prompt: optional string`

  - `reranking: optional object { enabled, match_threshold, model }`

    - `enabled: optional boolean`

    - `match_threshold: optional number`

    - `model: optional "@cf/baai/bge-reranker-base" or ""`

      - `"@cf/baai/bge-reranker-base"`

      - `""`

  - `retrieval: optional object { boost_by, context_expansion, filters, 6 more }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Overrides the instance-level boost_by config. Direction defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `context_expansion: optional number`

    - `filters: optional map[unknown]`

    - `fusion_method: optional "max" or "rrf"`

      - `"max"`

      - `"rrf"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

    - `match_threshold: optional number`

    - `max_num_results: optional number`

    - `retrieval_type: optional "vector" or "keyword" or "hybrid"`

      - `"vector"`

      - `"keyword"`

      - `"hybrid"`

    - `return_on_failure: optional boolean`

- `model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

  - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

  - `"@cf/zai-org/glm-4.7-flash"`

  - `"@cf/meta/llama-3.1-8b-instruct-fast"`

  - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

  - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

  - `"@cf/qwen/qwen3-30b-a3b-fp8"`

  - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

  - `"@cf/moonshotai/kimi-k2-instruct"`

  - `"@cf/google/gemma-3-12b-it"`

  - `"@cf/google/gemma-4-26b-a4b-it"`

  - `"@cf/moonshotai/kimi-k2.5"`

  - `"anthropic/claude-3-7-sonnet"`

  - `"anthropic/claude-sonnet-4"`

  - `"anthropic/claude-opus-4"`

  - `"anthropic/claude-3-5-haiku"`

  - `"cerebras/qwen-3-235b-a22b-instruct"`

  - `"cerebras/qwen-3-235b-a22b-thinking"`

  - `"cerebras/llama-3.3-70b"`

  - `"cerebras/llama-4-maverick-17b-128e-instruct"`

  - `"cerebras/llama-4-scout-17b-16e-instruct"`

  - `"cerebras/gpt-oss-120b"`

  - `"google-ai-studio/gemini-2.5-flash"`

  - `"google-ai-studio/gemini-2.5-pro"`

  - `"grok/grok-4"`

  - `"groq/llama-3.3-70b-versatile"`

  - `"groq/llama-3.1-8b-instant"`

  - `"openai/gpt-5"`

  - `"openai/gpt-5-mini"`

  - `"openai/gpt-5-nano"`

  - `""`

- `stream: optional boolean`

### Returns

- `choices: array of object { message, index }`

  - `message: object { content, role }`

    - `content: string`

    - `role: "system" or "developer" or "user" or 2 more`

      - `"system"`

      - `"developer"`

      - `"user"`

      - `"assistant"`

      - `"tool"`

  - `index: optional number`

- `chunks: array of object { id, score, text, 3 more }`

  - `id: string`

  - `score: number`

  - `text: string`

  - `type: string`

  - `item: optional object { key, metadata, timestamp }`

    - `key: string`

    - `metadata: optional map[unknown]`

    - `timestamp: optional number`

  - `scoring_details: optional object { fusion_method, keyword_rank, keyword_score, 3 more }`

    - `fusion_method: optional "rrf" or "max"`

      - `"rrf"`

      - `"max"`

    - `keyword_rank: optional number`

    - `keyword_score: optional number`

    - `reranking_score: optional number`

    - `vector_rank: optional number`

    - `vector_score: optional number`

- `id: optional string`

- `model: optional string`

- `object: optional string`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/instances/$ID/chat/completions \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
    -d '{
          "messages": [
            {
              "content": "content",
              "role": "system"
            }
          ]
        }'
```

#### Response

```json
{
  "choices": [
    {
      "message": {
        "content": "content",
        "role": "system"
      },
      "index": 0
    }
  ],
  "chunks": [
    {
      "id": "id",
      "score": 0,
      "text": "text",
      "type": "type",
      "item": {
        "key": "key",
        "metadata": {
          "foo": "bar"
        },
        "timestamp": 0
      },
      "scoring_details": {
        "fusion_method": "rrf",
        "keyword_rank": 0,
        "keyword_score": 0,
        "reranking_score": 0,
        "vector_rank": 0,
        "vector_score": 0
      }
    }
  ],
  "id": "id",
  "model": "model",
  "object": "object"
}
```

## Domain Types

### Instance List Response

- `InstanceListResponse object { id, created_at, modified_at, 36 more }`

  - `id: string`

    AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

  - `created_at: string`

  - `modified_at: string`

  - `ai_gateway_id: optional string`

  - `ai_search_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `cache: optional boolean`

  - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

    - `"super_strict_match"`

    - `"close_enough"`

    - `"flexible_friend"`

    - `"anything_goes"`

  - `cache_ttl: optional 600 or 1800 or 3600 or 7 more`

    Cache entry TTL in seconds. Allowed values: 600 (10min), 1800 (30min), 3600 (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d).

    - `600`

    - `1800`

    - `3600`

    - `7200`

    - `21600`

    - `43200`

    - `86400`

    - `172800`

    - `259200`

    - `518400`

  - `chunk_overlap: optional number`

  - `chunk_size: optional number`

  - `created_by: optional string`

  - `custom_metadata: optional array of object { data_type, field_name }`

    - `data_type: "text" or "number" or "boolean" or "datetime"`

      - `"text"`

      - `"number"`

      - `"boolean"`

      - `"datetime"`

    - `field_name: string`

  - `embedding_model: optional "@cf/qwen/qwen3-embedding-0.6b" or "@cf/baai/bge-m3" or "@cf/baai/bge-large-en-v1.5" or 6 more`

    - `"@cf/qwen/qwen3-embedding-0.6b"`

    - `"@cf/baai/bge-m3"`

    - `"@cf/baai/bge-large-en-v1.5"`

    - `"@cf/google/embeddinggemma-300m"`

    - `"google-ai-studio/gemini-embedding-001"`

    - `"google-ai-studio/gemini-embedding-2-preview"`

    - `"openai/text-embedding-3-small"`

    - `"openai/text-embedding-3-large"`

    - `""`

  - `enable: optional boolean`

  - `engine_version: optional number`

  - `fusion_method: optional "max" or "rrf"`

    - `"max"`

    - `"rrf"`

  - `hybrid_search_enabled: optional boolean`

    Deprecated — use index_method instead.

  - `index_method: optional object { keyword, vector }`

    Controls which storage backends are used during indexing. Defaults to vector-only.

    - `keyword: boolean`

      Enable keyword (BM25) storage backend.

    - `vector: boolean`

      Enable vector (embedding) storage backend.

  - `indexing_options: optional object { keyword_tokenizer }`

    - `keyword_tokenizer: optional "porter" or "trigram"`

      Tokenizer used for keyword search indexing. porter provides word-level tokenization with Porter stemming (good for natural language queries). trigram enables character-level substring matching (good for partial matches, code, identifiers). Changing this triggers a full re-index. Defaults to porter.

      - `"porter"`

      - `"trigram"`

  - `last_activity: optional string`

  - `max_num_results: optional number`

  - `metadata: optional object { created_from_aisearch_wizard, worker_domain }`

    - `created_from_aisearch_wizard: optional boolean`

    - `worker_domain: optional string`

  - `modified_by: optional string`

  - `namespace: optional string`

  - `paused: optional boolean`

  - `public_endpoint_id: optional string`

  - `public_endpoint_params: optional object { authorized_hosts, chat_completions_endpoint, enabled, 3 more }`

    - `authorized_hosts: optional array of string`

    - `chat_completions_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable chat completions endpoint for this public endpoint

    - `enabled: optional boolean`

    - `mcp: optional object { description, disabled }`

      - `description: optional string`

      - `disabled: optional boolean`

        Disable MCP endpoint for this public endpoint

    - `rate_limit: optional object { period_ms, requests, technique }`

      - `period_ms: optional number`

      - `requests: optional number`

      - `technique: optional "fixed" or "sliding"`

        - `"fixed"`

        - `"sliding"`

    - `search_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable search endpoint for this public endpoint

  - `reranking: optional boolean`

  - `reranking_model: optional "@cf/baai/bge-reranker-base" or ""`

    - `"@cf/baai/bge-reranker-base"`

    - `""`

  - `retrieval_options: optional object { boost_by, keyword_match_mode }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Each entry specifies a metadata field and an optional direction. Direction defaults to 'asc' for numeric/datetime fields and 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

  - `rewrite_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `rewrite_query: optional boolean`

  - `score_threshold: optional number`

  - `source: optional string`

  - `source_params: optional object { exclude_items, include_items, prefix, 2 more }`

    - `exclude_items: optional array of string`

      List of path patterns to exclude. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and /admin/settings/advanced)

    - `include_items: optional array of string`

      List of path patterns to include. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post)

    - `prefix: optional string`

    - `r2_jurisdiction: optional string`

    - `web_crawler: optional object { crawl_options, parse_options, parse_type, store_options }`

      - `crawl_options: optional object { depth, include_external_links, include_subdomains, 2 more }`

        - `depth: optional number`

        - `include_external_links: optional boolean`

        - `include_subdomains: optional boolean`

        - `max_age: optional number`

        - `source: optional "all" or "sitemaps" or "links"`

          - `"all"`

          - `"sitemaps"`

          - `"links"`

      - `parse_options: optional object { content_selector, include_headers, include_images, 2 more }`

        - `content_selector: optional array of object { path, selector }`

          List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first matching path wins. Only the matched HTML fragment is stored and indexed. Omit the field to disable content selection — empty arrays are rejected.

          - `path: string`

            Glob pattern to match against the page URL path. Uses standard glob syntax: * matches within a segment, ** crosses directories.

          - `selector: string`

            CSS selector to extract content from pages matching the path pattern. Must not contain disallowed characters (;, `, $, {, }, ). Must target a single element; if multiple elements match, the selector is ignored and the full page is used.

        - `include_headers: optional map[string]`

          Up to 5 custom HTTP headers sent with each crawl request. Names must be RFC-7230 token characters (no spaces, colons, or control characters); values must be HTAB + printable ASCII (no CR/LF).

        - `include_images: optional boolean`

        - `specific_sitemaps: optional array of string`

          List of specific sitemap URLs to use for crawling. Only valid when parse_type is 'sitemap'.

        - `use_browser_rendering: optional boolean`

      - `parse_type: optional "sitemap" or "feed-rss" or "crawl"`

        - `"sitemap"`

        - `"feed-rss"`

        - `"crawl"`

      - `store_options: optional object { storage_id, r2_jurisdiction, storage_type }`

        - `storage_id: string`

        - `r2_jurisdiction: optional string`

        - `storage_type: optional Provider`

          - `"r2"`

  - `status: optional string`

  - `sync_interval: optional 900 or 1800 or 3600 or 5 more`

    Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h).

    - `900`

    - `1800`

    - `3600`

    - `7200`

    - `14400`

    - `21600`

    - `43200`

    - `86400`

  - `token_id: optional string`

  - `type: optional "r2" or "web-crawler"`

    - `"r2"`

    - `"web-crawler"`

### Instance Create Response

- `InstanceCreateResponse object { id, created_at, modified_at, 36 more }`

  - `id: string`

    AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

  - `created_at: string`

  - `modified_at: string`

  - `ai_gateway_id: optional string`

  - `ai_search_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `cache: optional boolean`

  - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

    - `"super_strict_match"`

    - `"close_enough"`

    - `"flexible_friend"`

    - `"anything_goes"`

  - `cache_ttl: optional 600 or 1800 or 3600 or 7 more`

    Cache entry TTL in seconds. Allowed values: 600 (10min), 1800 (30min), 3600 (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d).

    - `600`

    - `1800`

    - `3600`

    - `7200`

    - `21600`

    - `43200`

    - `86400`

    - `172800`

    - `259200`

    - `518400`

  - `chunk_overlap: optional number`

  - `chunk_size: optional number`

  - `created_by: optional string`

  - `custom_metadata: optional array of object { data_type, field_name }`

    - `data_type: "text" or "number" or "boolean" or "datetime"`

      - `"text"`

      - `"number"`

      - `"boolean"`

      - `"datetime"`

    - `field_name: string`

  - `embedding_model: optional "@cf/qwen/qwen3-embedding-0.6b" or "@cf/baai/bge-m3" or "@cf/baai/bge-large-en-v1.5" or 6 more`

    - `"@cf/qwen/qwen3-embedding-0.6b"`

    - `"@cf/baai/bge-m3"`

    - `"@cf/baai/bge-large-en-v1.5"`

    - `"@cf/google/embeddinggemma-300m"`

    - `"google-ai-studio/gemini-embedding-001"`

    - `"google-ai-studio/gemini-embedding-2-preview"`

    - `"openai/text-embedding-3-small"`

    - `"openai/text-embedding-3-large"`

    - `""`

  - `enable: optional boolean`

  - `engine_version: optional number`

  - `fusion_method: optional "max" or "rrf"`

    - `"max"`

    - `"rrf"`

  - `hybrid_search_enabled: optional boolean`

    Deprecated — use index_method instead.

  - `index_method: optional object { keyword, vector }`

    Controls which storage backends are used during indexing. Defaults to vector-only.

    - `keyword: boolean`

      Enable keyword (BM25) storage backend.

    - `vector: boolean`

      Enable vector (embedding) storage backend.

  - `indexing_options: optional object { keyword_tokenizer }`

    - `keyword_tokenizer: optional "porter" or "trigram"`

      Tokenizer used for keyword search indexing. porter provides word-level tokenization with Porter stemming (good for natural language queries). trigram enables character-level substring matching (good for partial matches, code, identifiers). Changing this triggers a full re-index. Defaults to porter.

      - `"porter"`

      - `"trigram"`

  - `last_activity: optional string`

  - `max_num_results: optional number`

  - `metadata: optional object { created_from_aisearch_wizard, worker_domain }`

    - `created_from_aisearch_wizard: optional boolean`

    - `worker_domain: optional string`

  - `modified_by: optional string`

  - `namespace: optional string`

  - `paused: optional boolean`

  - `public_endpoint_id: optional string`

  - `public_endpoint_params: optional object { authorized_hosts, chat_completions_endpoint, enabled, 3 more }`

    - `authorized_hosts: optional array of string`

    - `chat_completions_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable chat completions endpoint for this public endpoint

    - `enabled: optional boolean`

    - `mcp: optional object { description, disabled }`

      - `description: optional string`

      - `disabled: optional boolean`

        Disable MCP endpoint for this public endpoint

    - `rate_limit: optional object { period_ms, requests, technique }`

      - `period_ms: optional number`

      - `requests: optional number`

      - `technique: optional "fixed" or "sliding"`

        - `"fixed"`

        - `"sliding"`

    - `search_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable search endpoint for this public endpoint

  - `reranking: optional boolean`

  - `reranking_model: optional "@cf/baai/bge-reranker-base" or ""`

    - `"@cf/baai/bge-reranker-base"`

    - `""`

  - `retrieval_options: optional object { boost_by, keyword_match_mode }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Each entry specifies a metadata field and an optional direction. Direction defaults to 'asc' for numeric/datetime fields and 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

  - `rewrite_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `rewrite_query: optional boolean`

  - `score_threshold: optional number`

  - `source: optional string`

  - `source_params: optional object { exclude_items, include_items, prefix, 2 more }`

    - `exclude_items: optional array of string`

      List of path patterns to exclude. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and /admin/settings/advanced)

    - `include_items: optional array of string`

      List of path patterns to include. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post)

    - `prefix: optional string`

    - `r2_jurisdiction: optional string`

    - `web_crawler: optional object { crawl_options, parse_options, parse_type, store_options }`

      - `crawl_options: optional object { depth, include_external_links, include_subdomains, 2 more }`

        - `depth: optional number`

        - `include_external_links: optional boolean`

        - `include_subdomains: optional boolean`

        - `max_age: optional number`

        - `source: optional "all" or "sitemaps" or "links"`

          - `"all"`

          - `"sitemaps"`

          - `"links"`

      - `parse_options: optional object { content_selector, include_headers, include_images, 2 more }`

        - `content_selector: optional array of object { path, selector }`

          List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first matching path wins. Only the matched HTML fragment is stored and indexed. Omit the field to disable content selection — empty arrays are rejected.

          - `path: string`

            Glob pattern to match against the page URL path. Uses standard glob syntax: * matches within a segment, ** crosses directories.

          - `selector: string`

            CSS selector to extract content from pages matching the path pattern. Must not contain disallowed characters (;, `, $, {, }, ). Must target a single element; if multiple elements match, the selector is ignored and the full page is used.

        - `include_headers: optional map[string]`

          Up to 5 custom HTTP headers sent with each crawl request. Names must be RFC-7230 token characters (no spaces, colons, or control characters); values must be HTAB + printable ASCII (no CR/LF).

        - `include_images: optional boolean`

        - `specific_sitemaps: optional array of string`

          List of specific sitemap URLs to use for crawling. Only valid when parse_type is 'sitemap'.

        - `use_browser_rendering: optional boolean`

      - `parse_type: optional "sitemap" or "feed-rss" or "crawl"`

        - `"sitemap"`

        - `"feed-rss"`

        - `"crawl"`

      - `store_options: optional object { storage_id, r2_jurisdiction, storage_type }`

        - `storage_id: string`

        - `r2_jurisdiction: optional string`

        - `storage_type: optional Provider`

          - `"r2"`

  - `status: optional string`

  - `sync_interval: optional 900 or 1800 or 3600 or 5 more`

    Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h).

    - `900`

    - `1800`

    - `3600`

    - `7200`

    - `14400`

    - `21600`

    - `43200`

    - `86400`

  - `token_id: optional string`

  - `type: optional "r2" or "web-crawler"`

    - `"r2"`

    - `"web-crawler"`

### Instance Read Response

- `InstanceReadResponse object { id, created_at, modified_at, 36 more }`

  - `id: string`

    AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

  - `created_at: string`

  - `modified_at: string`

  - `ai_gateway_id: optional string`

  - `ai_search_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `cache: optional boolean`

  - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

    - `"super_strict_match"`

    - `"close_enough"`

    - `"flexible_friend"`

    - `"anything_goes"`

  - `cache_ttl: optional 600 or 1800 or 3600 or 7 more`

    Cache entry TTL in seconds. Allowed values: 600 (10min), 1800 (30min), 3600 (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d).

    - `600`

    - `1800`

    - `3600`

    - `7200`

    - `21600`

    - `43200`

    - `86400`

    - `172800`

    - `259200`

    - `518400`

  - `chunk_overlap: optional number`

  - `chunk_size: optional number`

  - `created_by: optional string`

  - `custom_metadata: optional array of object { data_type, field_name }`

    - `data_type: "text" or "number" or "boolean" or "datetime"`

      - `"text"`

      - `"number"`

      - `"boolean"`

      - `"datetime"`

    - `field_name: string`

  - `embedding_model: optional "@cf/qwen/qwen3-embedding-0.6b" or "@cf/baai/bge-m3" or "@cf/baai/bge-large-en-v1.5" or 6 more`

    - `"@cf/qwen/qwen3-embedding-0.6b"`

    - `"@cf/baai/bge-m3"`

    - `"@cf/baai/bge-large-en-v1.5"`

    - `"@cf/google/embeddinggemma-300m"`

    - `"google-ai-studio/gemini-embedding-001"`

    - `"google-ai-studio/gemini-embedding-2-preview"`

    - `"openai/text-embedding-3-small"`

    - `"openai/text-embedding-3-large"`

    - `""`

  - `enable: optional boolean`

  - `engine_version: optional number`

  - `fusion_method: optional "max" or "rrf"`

    - `"max"`

    - `"rrf"`

  - `hybrid_search_enabled: optional boolean`

    Deprecated — use index_method instead.

  - `index_method: optional object { keyword, vector }`

    Controls which storage backends are used during indexing. Defaults to vector-only.

    - `keyword: boolean`

      Enable keyword (BM25) storage backend.

    - `vector: boolean`

      Enable vector (embedding) storage backend.

  - `indexing_options: optional object { keyword_tokenizer }`

    - `keyword_tokenizer: optional "porter" or "trigram"`

      Tokenizer used for keyword search indexing. porter provides word-level tokenization with Porter stemming (good for natural language queries). trigram enables character-level substring matching (good for partial matches, code, identifiers). Changing this triggers a full re-index. Defaults to porter.

      - `"porter"`

      - `"trigram"`

  - `last_activity: optional string`

  - `max_num_results: optional number`

  - `metadata: optional object { created_from_aisearch_wizard, worker_domain }`

    - `created_from_aisearch_wizard: optional boolean`

    - `worker_domain: optional string`

  - `modified_by: optional string`

  - `namespace: optional string`

  - `paused: optional boolean`

  - `public_endpoint_id: optional string`

  - `public_endpoint_params: optional object { authorized_hosts, chat_completions_endpoint, enabled, 3 more }`

    - `authorized_hosts: optional array of string`

    - `chat_completions_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable chat completions endpoint for this public endpoint

    - `enabled: optional boolean`

    - `mcp: optional object { description, disabled }`

      - `description: optional string`

      - `disabled: optional boolean`

        Disable MCP endpoint for this public endpoint

    - `rate_limit: optional object { period_ms, requests, technique }`

      - `period_ms: optional number`

      - `requests: optional number`

      - `technique: optional "fixed" or "sliding"`

        - `"fixed"`

        - `"sliding"`

    - `search_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable search endpoint for this public endpoint

  - `reranking: optional boolean`

  - `reranking_model: optional "@cf/baai/bge-reranker-base" or ""`

    - `"@cf/baai/bge-reranker-base"`

    - `""`

  - `retrieval_options: optional object { boost_by, keyword_match_mode }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Each entry specifies a metadata field and an optional direction. Direction defaults to 'asc' for numeric/datetime fields and 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

  - `rewrite_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `rewrite_query: optional boolean`

  - `score_threshold: optional number`

  - `source: optional string`

  - `source_params: optional object { exclude_items, include_items, prefix, 2 more }`

    - `exclude_items: optional array of string`

      List of path patterns to exclude. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and /admin/settings/advanced)

    - `include_items: optional array of string`

      List of path patterns to include. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post)

    - `prefix: optional string`

    - `r2_jurisdiction: optional string`

    - `web_crawler: optional object { crawl_options, parse_options, parse_type, store_options }`

      - `crawl_options: optional object { depth, include_external_links, include_subdomains, 2 more }`

        - `depth: optional number`

        - `include_external_links: optional boolean`

        - `include_subdomains: optional boolean`

        - `max_age: optional number`

        - `source: optional "all" or "sitemaps" or "links"`

          - `"all"`

          - `"sitemaps"`

          - `"links"`

      - `parse_options: optional object { content_selector, include_headers, include_images, 2 more }`

        - `content_selector: optional array of object { path, selector }`

          List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first matching path wins. Only the matched HTML fragment is stored and indexed. Omit the field to disable content selection — empty arrays are rejected.

          - `path: string`

            Glob pattern to match against the page URL path. Uses standard glob syntax: * matches within a segment, ** crosses directories.

          - `selector: string`

            CSS selector to extract content from pages matching the path pattern. Must not contain disallowed characters (;, `, $, {, }, ). Must target a single element; if multiple elements match, the selector is ignored and the full page is used.

        - `include_headers: optional map[string]`

          Up to 5 custom HTTP headers sent with each crawl request. Names must be RFC-7230 token characters (no spaces, colons, or control characters); values must be HTAB + printable ASCII (no CR/LF).

        - `include_images: optional boolean`

        - `specific_sitemaps: optional array of string`

          List of specific sitemap URLs to use for crawling. Only valid when parse_type is 'sitemap'.

        - `use_browser_rendering: optional boolean`

      - `parse_type: optional "sitemap" or "feed-rss" or "crawl"`

        - `"sitemap"`

        - `"feed-rss"`

        - `"crawl"`

      - `store_options: optional object { storage_id, r2_jurisdiction, storage_type }`

        - `storage_id: string`

        - `r2_jurisdiction: optional string`

        - `storage_type: optional Provider`

          - `"r2"`

  - `status: optional string`

  - `sync_interval: optional 900 or 1800 or 3600 or 5 more`

    Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h).

    - `900`

    - `1800`

    - `3600`

    - `7200`

    - `14400`

    - `21600`

    - `43200`

    - `86400`

  - `token_id: optional string`

  - `type: optional "r2" or "web-crawler"`

    - `"r2"`

    - `"web-crawler"`

### Instance Update Response

- `InstanceUpdateResponse object { id, created_at, modified_at, 36 more }`

  - `id: string`

    AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

  - `created_at: string`

  - `modified_at: string`

  - `ai_gateway_id: optional string`

  - `ai_search_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `cache: optional boolean`

  - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

    - `"super_strict_match"`

    - `"close_enough"`

    - `"flexible_friend"`

    - `"anything_goes"`

  - `cache_ttl: optional 600 or 1800 or 3600 or 7 more`

    Cache entry TTL in seconds. Allowed values: 600 (10min), 1800 (30min), 3600 (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d).

    - `600`

    - `1800`

    - `3600`

    - `7200`

    - `21600`

    - `43200`

    - `86400`

    - `172800`

    - `259200`

    - `518400`

  - `chunk_overlap: optional number`

  - `chunk_size: optional number`

  - `created_by: optional string`

  - `custom_metadata: optional array of object { data_type, field_name }`

    - `data_type: "text" or "number" or "boolean" or "datetime"`

      - `"text"`

      - `"number"`

      - `"boolean"`

      - `"datetime"`

    - `field_name: string`

  - `embedding_model: optional "@cf/qwen/qwen3-embedding-0.6b" or "@cf/baai/bge-m3" or "@cf/baai/bge-large-en-v1.5" or 6 more`

    - `"@cf/qwen/qwen3-embedding-0.6b"`

    - `"@cf/baai/bge-m3"`

    - `"@cf/baai/bge-large-en-v1.5"`

    - `"@cf/google/embeddinggemma-300m"`

    - `"google-ai-studio/gemini-embedding-001"`

    - `"google-ai-studio/gemini-embedding-2-preview"`

    - `"openai/text-embedding-3-small"`

    - `"openai/text-embedding-3-large"`

    - `""`

  - `enable: optional boolean`

  - `engine_version: optional number`

  - `fusion_method: optional "max" or "rrf"`

    - `"max"`

    - `"rrf"`

  - `hybrid_search_enabled: optional boolean`

    Deprecated — use index_method instead.

  - `index_method: optional object { keyword, vector }`

    Controls which storage backends are used during indexing. Defaults to vector-only.

    - `keyword: boolean`

      Enable keyword (BM25) storage backend.

    - `vector: boolean`

      Enable vector (embedding) storage backend.

  - `indexing_options: optional object { keyword_tokenizer }`

    - `keyword_tokenizer: optional "porter" or "trigram"`

      Tokenizer used for keyword search indexing. porter provides word-level tokenization with Porter stemming (good for natural language queries). trigram enables character-level substring matching (good for partial matches, code, identifiers). Changing this triggers a full re-index. Defaults to porter.

      - `"porter"`

      - `"trigram"`

  - `last_activity: optional string`

  - `max_num_results: optional number`

  - `metadata: optional object { created_from_aisearch_wizard, worker_domain }`

    - `created_from_aisearch_wizard: optional boolean`

    - `worker_domain: optional string`

  - `modified_by: optional string`

  - `namespace: optional string`

  - `paused: optional boolean`

  - `public_endpoint_id: optional string`

  - `public_endpoint_params: optional object { authorized_hosts, chat_completions_endpoint, enabled, 3 more }`

    - `authorized_hosts: optional array of string`

    - `chat_completions_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable chat completions endpoint for this public endpoint

    - `enabled: optional boolean`

    - `mcp: optional object { description, disabled }`

      - `description: optional string`

      - `disabled: optional boolean`

        Disable MCP endpoint for this public endpoint

    - `rate_limit: optional object { period_ms, requests, technique }`

      - `period_ms: optional number`

      - `requests: optional number`

      - `technique: optional "fixed" or "sliding"`

        - `"fixed"`

        - `"sliding"`

    - `search_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable search endpoint for this public endpoint

  - `reranking: optional boolean`

  - `reranking_model: optional "@cf/baai/bge-reranker-base" or ""`

    - `"@cf/baai/bge-reranker-base"`

    - `""`

  - `retrieval_options: optional object { boost_by, keyword_match_mode }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Each entry specifies a metadata field and an optional direction. Direction defaults to 'asc' for numeric/datetime fields and 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

  - `rewrite_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `rewrite_query: optional boolean`

  - `score_threshold: optional number`

  - `source: optional string`

  - `source_params: optional object { exclude_items, include_items, prefix, 2 more }`

    - `exclude_items: optional array of string`

      List of path patterns to exclude. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and /admin/settings/advanced)

    - `include_items: optional array of string`

      List of path patterns to include. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post)

    - `prefix: optional string`

    - `r2_jurisdiction: optional string`

    - `web_crawler: optional object { crawl_options, parse_options, parse_type, store_options }`

      - `crawl_options: optional object { depth, include_external_links, include_subdomains, 2 more }`

        - `depth: optional number`

        - `include_external_links: optional boolean`

        - `include_subdomains: optional boolean`

        - `max_age: optional number`

        - `source: optional "all" or "sitemaps" or "links"`

          - `"all"`

          - `"sitemaps"`

          - `"links"`

      - `parse_options: optional object { content_selector, include_headers, include_images, 2 more }`

        - `content_selector: optional array of object { path, selector }`

          List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first matching path wins. Only the matched HTML fragment is stored and indexed. Omit the field to disable content selection — empty arrays are rejected.

          - `path: string`

            Glob pattern to match against the page URL path. Uses standard glob syntax: * matches within a segment, ** crosses directories.

          - `selector: string`

            CSS selector to extract content from pages matching the path pattern. Must not contain disallowed characters (;, `, $, {, }, ). Must target a single element; if multiple elements match, the selector is ignored and the full page is used.

        - `include_headers: optional map[string]`

          Up to 5 custom HTTP headers sent with each crawl request. Names must be RFC-7230 token characters (no spaces, colons, or control characters); values must be HTAB + printable ASCII (no CR/LF).

        - `include_images: optional boolean`

        - `specific_sitemaps: optional array of string`

          List of specific sitemap URLs to use for crawling. Only valid when parse_type is 'sitemap'.

        - `use_browser_rendering: optional boolean`

      - `parse_type: optional "sitemap" or "feed-rss" or "crawl"`

        - `"sitemap"`

        - `"feed-rss"`

        - `"crawl"`

      - `store_options: optional object { storage_id, r2_jurisdiction, storage_type }`

        - `storage_id: string`

        - `r2_jurisdiction: optional string`

        - `storage_type: optional Provider`

          - `"r2"`

  - `status: optional string`

  - `sync_interval: optional 900 or 1800 or 3600 or 5 more`

    Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h).

    - `900`

    - `1800`

    - `3600`

    - `7200`

    - `14400`

    - `21600`

    - `43200`

    - `86400`

  - `token_id: optional string`

  - `type: optional "r2" or "web-crawler"`

    - `"r2"`

    - `"web-crawler"`

### Instance Delete Response

- `InstanceDeleteResponse object { id, created_at, modified_at, 36 more }`

  - `id: string`

    AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

  - `created_at: string`

  - `modified_at: string`

  - `ai_gateway_id: optional string`

  - `ai_search_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `cache: optional boolean`

  - `cache_threshold: optional "super_strict_match" or "close_enough" or "flexible_friend" or "anything_goes"`

    - `"super_strict_match"`

    - `"close_enough"`

    - `"flexible_friend"`

    - `"anything_goes"`

  - `cache_ttl: optional 600 or 1800 or 3600 or 7 more`

    Cache entry TTL in seconds. Allowed values: 600 (10min), 1800 (30min), 3600 (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d).

    - `600`

    - `1800`

    - `3600`

    - `7200`

    - `21600`

    - `43200`

    - `86400`

    - `172800`

    - `259200`

    - `518400`

  - `chunk_overlap: optional number`

  - `chunk_size: optional number`

  - `created_by: optional string`

  - `custom_metadata: optional array of object { data_type, field_name }`

    - `data_type: "text" or "number" or "boolean" or "datetime"`

      - `"text"`

      - `"number"`

      - `"boolean"`

      - `"datetime"`

    - `field_name: string`

  - `embedding_model: optional "@cf/qwen/qwen3-embedding-0.6b" or "@cf/baai/bge-m3" or "@cf/baai/bge-large-en-v1.5" or 6 more`

    - `"@cf/qwen/qwen3-embedding-0.6b"`

    - `"@cf/baai/bge-m3"`

    - `"@cf/baai/bge-large-en-v1.5"`

    - `"@cf/google/embeddinggemma-300m"`

    - `"google-ai-studio/gemini-embedding-001"`

    - `"google-ai-studio/gemini-embedding-2-preview"`

    - `"openai/text-embedding-3-small"`

    - `"openai/text-embedding-3-large"`

    - `""`

  - `enable: optional boolean`

  - `engine_version: optional number`

  - `fusion_method: optional "max" or "rrf"`

    - `"max"`

    - `"rrf"`

  - `hybrid_search_enabled: optional boolean`

    Deprecated — use index_method instead.

  - `index_method: optional object { keyword, vector }`

    Controls which storage backends are used during indexing. Defaults to vector-only.

    - `keyword: boolean`

      Enable keyword (BM25) storage backend.

    - `vector: boolean`

      Enable vector (embedding) storage backend.

  - `indexing_options: optional object { keyword_tokenizer }`

    - `keyword_tokenizer: optional "porter" or "trigram"`

      Tokenizer used for keyword search indexing. porter provides word-level tokenization with Porter stemming (good for natural language queries). trigram enables character-level substring matching (good for partial matches, code, identifiers). Changing this triggers a full re-index. Defaults to porter.

      - `"porter"`

      - `"trigram"`

  - `last_activity: optional string`

  - `max_num_results: optional number`

  - `metadata: optional object { created_from_aisearch_wizard, worker_domain }`

    - `created_from_aisearch_wizard: optional boolean`

    - `worker_domain: optional string`

  - `modified_by: optional string`

  - `namespace: optional string`

  - `paused: optional boolean`

  - `public_endpoint_id: optional string`

  - `public_endpoint_params: optional object { authorized_hosts, chat_completions_endpoint, enabled, 3 more }`

    - `authorized_hosts: optional array of string`

    - `chat_completions_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable chat completions endpoint for this public endpoint

    - `enabled: optional boolean`

    - `mcp: optional object { description, disabled }`

      - `description: optional string`

      - `disabled: optional boolean`

        Disable MCP endpoint for this public endpoint

    - `rate_limit: optional object { period_ms, requests, technique }`

      - `period_ms: optional number`

      - `requests: optional number`

      - `technique: optional "fixed" or "sliding"`

        - `"fixed"`

        - `"sliding"`

    - `search_endpoint: optional object { disabled }`

      - `disabled: optional boolean`

        Disable search endpoint for this public endpoint

  - `reranking: optional boolean`

  - `reranking_model: optional "@cf/baai/bge-reranker-base" or ""`

    - `"@cf/baai/bge-reranker-base"`

    - `""`

  - `retrieval_options: optional object { boost_by, keyword_match_mode }`

    - `boost_by: optional array of object { field, direction }`

      Metadata fields to boost search results by. Each entry specifies a metadata field and an optional direction. Direction defaults to 'asc' for numeric/datetime fields and 'exists' for text/boolean fields. Fields must match 'timestamp' or a defined custom_metadata field.

      - `field: string`

        Metadata field name to boost by. Use 'timestamp' for document freshness, or any custom_metadata field. Numeric and datetime fields support all four directions (asc, desc, exists, not_exists); text/boolean fields only support exists/not_exists.

      - `direction: optional "asc" or "desc" or "exists" or "not_exists"`

        Boost direction. 'desc' = higher values rank higher (e.g. newer timestamps). 'asc' = lower values rank higher. 'exists' = boost chunks that have the field. 'not_exists' = boost chunks that lack the field. Optional — defaults to 'asc' for numeric/datetime fields, 'exists' for text/boolean fields.

        - `"asc"`

        - `"desc"`

        - `"exists"`

        - `"not_exists"`

    - `keyword_match_mode: optional "and" or "or"`

      Controls which documents are candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' includes any document containing at least one term, ranked by BM25 relevance. Defaults to 'and'.

      - `"and"`

      - `"or"`

  - `rewrite_model: optional "@cf/meta/llama-3.3-70b-instruct-fp8-fast" or "@cf/zai-org/glm-4.7-flash" or "@cf/meta/llama-3.1-8b-instruct-fast" or 27 more`

    - `"@cf/meta/llama-3.3-70b-instruct-fp8-fast"`

    - `"@cf/zai-org/glm-4.7-flash"`

    - `"@cf/meta/llama-3.1-8b-instruct-fast"`

    - `"@cf/meta/llama-3.1-8b-instruct-fp8"`

    - `"@cf/meta/llama-4-scout-17b-16e-instruct"`

    - `"@cf/qwen/qwen3-30b-a3b-fp8"`

    - `"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b"`

    - `"@cf/moonshotai/kimi-k2-instruct"`

    - `"@cf/google/gemma-3-12b-it"`

    - `"@cf/google/gemma-4-26b-a4b-it"`

    - `"@cf/moonshotai/kimi-k2.5"`

    - `"anthropic/claude-3-7-sonnet"`

    - `"anthropic/claude-sonnet-4"`

    - `"anthropic/claude-opus-4"`

    - `"anthropic/claude-3-5-haiku"`

    - `"cerebras/qwen-3-235b-a22b-instruct"`

    - `"cerebras/qwen-3-235b-a22b-thinking"`

    - `"cerebras/llama-3.3-70b"`

    - `"cerebras/llama-4-maverick-17b-128e-instruct"`

    - `"cerebras/llama-4-scout-17b-16e-instruct"`

    - `"cerebras/gpt-oss-120b"`

    - `"google-ai-studio/gemini-2.5-flash"`

    - `"google-ai-studio/gemini-2.5-pro"`

    - `"grok/grok-4"`

    - `"groq/llama-3.3-70b-versatile"`

    - `"groq/llama-3.1-8b-instant"`

    - `"openai/gpt-5"`

    - `"openai/gpt-5-mini"`

    - `"openai/gpt-5-nano"`

    - `""`

  - `rewrite_query: optional boolean`

  - `score_threshold: optional number`

  - `source: optional string`

  - `source_params: optional object { exclude_items, include_items, prefix, 2 more }`

    - `exclude_items: optional array of string`

      List of path patterns to exclude. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and /admin/settings/advanced)

    - `include_items: optional array of string`

      List of path patterns to include. Uses micromatch glob syntax: * matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post)

    - `prefix: optional string`

    - `r2_jurisdiction: optional string`

    - `web_crawler: optional object { crawl_options, parse_options, parse_type, store_options }`

      - `crawl_options: optional object { depth, include_external_links, include_subdomains, 2 more }`

        - `depth: optional number`

        - `include_external_links: optional boolean`

        - `include_subdomains: optional boolean`

        - `max_age: optional number`

        - `source: optional "all" or "sitemaps" or "links"`

          - `"all"`

          - `"sitemaps"`

          - `"links"`

      - `parse_options: optional object { content_selector, include_headers, include_images, 2 more }`

        - `content_selector: optional array of object { path, selector }`

          List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first matching path wins. Only the matched HTML fragment is stored and indexed. Omit the field to disable content selection — empty arrays are rejected.

          - `path: string`

            Glob pattern to match against the page URL path. Uses standard glob syntax: * matches within a segment, ** crosses directories.

          - `selector: string`

            CSS selector to extract content from pages matching the path pattern. Must not contain disallowed characters (;, `, $, {, }, ). Must target a single element; if multiple elements match, the selector is ignored and the full page is used.

        - `include_headers: optional map[string]`

          Up to 5 custom HTTP headers sent with each crawl request. Names must be RFC-7230 token characters (no spaces, colons, or control characters); values must be HTAB + printable ASCII (no CR/LF).

        - `include_images: optional boolean`

        - `specific_sitemaps: optional array of string`

          List of specific sitemap URLs to use for crawling. Only valid when parse_type is 'sitemap'.

        - `use_browser_rendering: optional boolean`

      - `parse_type: optional "sitemap" or "feed-rss" or "crawl"`

        - `"sitemap"`

        - `"feed-rss"`

        - `"crawl"`

      - `store_options: optional object { storage_id, r2_jurisdiction, storage_type }`

        - `storage_id: string`

        - `r2_jurisdiction: optional string`

        - `storage_type: optional Provider`

          - `"r2"`

  - `status: optional string`

  - `sync_interval: optional 900 or 1800 or 3600 or 5 more`

    Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h).

    - `900`

    - `1800`

    - `3600`

    - `7200`

    - `14400`

    - `21600`

    - `43200`

    - `86400`

  - `token_id: optional string`

  - `type: optional "r2" or "web-crawler"`

    - `"r2"`

    - `"web-crawler"`

### Instance Stats Response

- `InstanceStatsResponse object { completed, degraded, engine, 8 more }`

  - `completed: optional number`

  - `degraded: optional boolean`

    True when status counts are unavailable (e.g. legacy stats query exceeded D1 statement-size limit). Counts are omitted in this case.

  - `engine: optional object { r2, vectorize }`

    Engine-specific metadata. Present only for managed (v3) instances.

    - `r2: optional object { metadataSizeBytes, objectCount, payloadSizeBytes }`

      R2 bucket storage usage in bytes.

      - `metadataSizeBytes: number`

      - `objectCount: number`

      - `payloadSizeBytes: number`

    - `vectorize: optional object { dimensions, vectorsCount }`

      Vectorize index metadata (dimensions, vector count).

      - `dimensions: number`

      - `vectorsCount: number`

  - `error: optional number`

  - `file_embed_errors: optional map[unknown]`

  - `index_source_errors: optional map[unknown]`

  - `last_activity: optional string`

  - `outdated: optional number`

  - `queued: optional number`

  - `running: optional number`

  - `skipped: optional number`

### Instance Search Response

- `InstanceSearchResponse object { chunks, search_query }`

  - `chunks: array of object { id, score, text, 3 more }`

    - `id: string`

    - `score: number`

    - `text: string`

    - `type: string`

    - `item: optional object { key, metadata, timestamp }`

      - `key: string`

      - `metadata: optional map[unknown]`

      - `timestamp: optional number`

    - `scoring_details: optional object { fusion_method, keyword_rank, keyword_score, 3 more }`

      - `fusion_method: optional "rrf" or "max"`

        - `"rrf"`

        - `"max"`

      - `keyword_rank: optional number`

      - `keyword_score: optional number`

      - `reranking_score: optional number`

      - `vector_rank: optional number`

      - `vector_score: optional number`

  - `search_query: string`

### Instance Chat Completions Response

- `InstanceChatCompletionsResponse object { choices, chunks, id, 2 more }`

  - `choices: array of object { message, index }`

    - `message: object { content, role }`

      - `content: string`

      - `role: "system" or "developer" or "user" or 2 more`

        - `"system"`

        - `"developer"`

        - `"user"`

        - `"assistant"`

        - `"tool"`

    - `index: optional number`

  - `chunks: array of object { id, score, text, 3 more }`

    - `id: string`

    - `score: number`

    - `text: string`

    - `type: string`

    - `item: optional object { key, metadata, timestamp }`

      - `key: string`

      - `metadata: optional map[unknown]`

      - `timestamp: optional number`

    - `scoring_details: optional object { fusion_method, keyword_rank, keyword_score, 3 more }`

      - `fusion_method: optional "rrf" or "max"`

        - `"rrf"`

        - `"max"`

      - `keyword_rank: optional number`

      - `keyword_score: optional number`

      - `reranking_score: optional number`

      - `vector_rank: optional number`

      - `vector_score: optional number`

  - `id: optional string`

  - `model: optional string`

  - `object: optional string`

# Jobs

## List Jobs

**get** `/accounts/{account_id}/ai-search/instances/{id}/jobs`

Lists indexing jobs for an AI Search instance.

### Path Parameters

- `account_id: string`

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

### Query Parameters

- `page: optional number`

- `per_page: optional number`

### Returns

- `result: array of object { id, source, description, 4 more }`

  - `id: string`

  - `source: "user" or "schedule"`

    - `"user"`

    - `"schedule"`

  - `description: optional string`

  - `end_reason: optional string`

  - `ended_at: optional string`

  - `last_seen_at: optional string`

  - `started_at: optional string`

- `result_info: object { count, page, per_page, total_count }`

  - `count: number`

  - `page: number`

  - `per_page: number`

  - `total_count: number`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/instances/$ID/jobs \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": [
    {
      "id": "id",
      "source": "user",
      "description": "description",
      "end_reason": "end_reason",
      "ended_at": "ended_at",
      "last_seen_at": "last_seen_at",
      "started_at": "started_at"
    }
  ],
  "result_info": {
    "count": 0,
    "page": 0,
    "per_page": 0,
    "total_count": 0
  },
  "success": true
}
```

## Create new job

**post** `/accounts/{account_id}/ai-search/instances/{id}/jobs`

Creates a new indexing job for an AI Search instance.

### Path Parameters

- `account_id: string`

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

### Body Parameters

- `description: optional string`

### Returns

- `result: object { id, source, description, 4 more }`

  - `id: string`

  - `source: "user" or "schedule"`

    - `"user"`

    - `"schedule"`

  - `description: optional string`

  - `end_reason: optional string`

  - `ended_at: optional string`

  - `last_seen_at: optional string`

  - `started_at: optional string`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/instances/$ID/jobs \
    -X POST \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": {
    "id": "id",
    "source": "user",
    "description": "description",
    "end_reason": "end_reason",
    "ended_at": "ended_at",
    "last_seen_at": "last_seen_at",
    "started_at": "started_at"
  },
  "success": true
}
```

## Get a Job Details

**get** `/accounts/{account_id}/ai-search/instances/{id}/jobs/{job_id}`

Retrieves details for a specific AI Search indexing job.

### Path Parameters

- `account_id: string`

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

- `job_id: string`

### Returns

- `result: object { id, source, description, 4 more }`

  - `id: string`

  - `source: "user" or "schedule"`

    - `"user"`

    - `"schedule"`

  - `description: optional string`

  - `end_reason: optional string`

  - `ended_at: optional string`

  - `last_seen_at: optional string`

  - `started_at: optional string`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/instances/$ID/jobs/$JOB_ID \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": {
    "id": "id",
    "source": "user",
    "description": "description",
    "end_reason": "end_reason",
    "ended_at": "ended_at",
    "last_seen_at": "last_seen_at",
    "started_at": "started_at"
  },
  "success": true
}
```

## List Job Logs

**get** `/accounts/{account_id}/ai-search/instances/{id}/jobs/{job_id}/logs`

Lists log entries for an AI Search indexing job.

### Path Parameters

- `account_id: string`

- `id: string`

  AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.

- `job_id: string`

### Query Parameters

- `page: optional number`

- `per_page: optional number`

### Returns

- `result: array of object { id, created_at, message, message_type }`

  - `id: number`

  - `created_at: number`

  - `message: string`

  - `message_type: number`

- `result_info: object { count, page, per_page, total_count }`

  - `count: number`

  - `page: number`

  - `per_page: number`

  - `total_count: number`

- `success: boolean`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/instances/$ID/jobs/$JOB_ID/logs \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": [
    {
      "id": 0,
      "created_at": 0,
      "message": "message",
      "message_type": 0
    }
  ],
  "result_info": {
    "count": 0,
    "page": 0,
    "per_page": 0,
    "total_count": 0
  },
  "success": true
}
```

## Domain Types

### Job List Response

- `JobListResponse object { id, source, description, 4 more }`

  - `id: string`

  - `source: "user" or "schedule"`

    - `"user"`

    - `"schedule"`

  - `description: optional string`

  - `end_reason: optional string`

  - `ended_at: optional string`

  - `last_seen_at: optional string`

  - `started_at: optional string`

### Job Create Response

- `JobCreateResponse object { id, source, description, 4 more }`

  - `id: string`

  - `source: "user" or "schedule"`

    - `"user"`

    - `"schedule"`

  - `description: optional string`

  - `end_reason: optional string`

  - `ended_at: optional string`

  - `last_seen_at: optional string`

  - `started_at: optional string`

### Job Get Response

- `JobGetResponse object { id, source, description, 4 more }`

  - `id: string`

  - `source: "user" or "schedule"`

    - `"user"`

    - `"schedule"`

  - `description: optional string`

  - `end_reason: optional string`

  - `ended_at: optional string`

  - `last_seen_at: optional string`

  - `started_at: optional string`

### Job Logs Response

- `JobLogsResponse = array of object { id, created_at, message, message_type }`

  - `id: number`

  - `created_at: number`

  - `message: string`

  - `message_type: number`

# Tokens

## List tokens.

**get** `/accounts/{account_id}/ai-search/tokens`

List tokens.

### Path Parameters

- `account_id: string`

### Query Parameters

- `page: optional number`

  Page number (1-indexed).

- `per_page: optional number`

  Number of results per page.

- `search: optional string`

  Filter tokens whose name contains this string (case-insensitive).

### Returns

- `result: array of object { id, cf_api_id, created_at, 6 more }`

  - `id: string`

  - `cf_api_id: string`

  - `created_at: string`

  - `modified_at: string`

  - `name: string`

  - `created_by: optional string`

  - `enabled: optional boolean`

  - `legacy: optional boolean`

  - `modified_by: optional string`

- `result_info: object { count, page, per_page, total_count }`

  - `count: number`

  - `page: number`

  - `per_page: number`

  - `total_count: number`

- `success: true`

  - `true`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/tokens \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": [
    {
      "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
      "cf_api_id": "cf_api_id",
      "created_at": "2019-12-27T18:11:19.117Z",
      "modified_at": "2019-12-27T18:11:19.117Z",
      "name": "name",
      "created_by": "created_by",
      "enabled": true,
      "legacy": true,
      "modified_by": "modified_by"
    }
  ],
  "result_info": {
    "count": 0,
    "page": 0,
    "per_page": 0,
    "total_count": 0
  },
  "success": true
}
```

## Create token.

**post** `/accounts/{account_id}/ai-search/tokens`

Create a new token.

### Path Parameters

- `account_id: string`

### Body Parameters

- `cf_api_id: string`

- `cf_api_key: string`

- `name: string`

- `legacy: optional boolean`

### Returns

- `result: object { id, cf_api_id, created_at, 6 more }`

  - `id: string`

  - `cf_api_id: string`

  - `created_at: string`

  - `modified_at: string`

  - `name: string`

  - `created_by: optional string`

  - `enabled: optional boolean`

  - `legacy: optional boolean`

  - `modified_by: optional string`

- `success: true`

  - `true`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/tokens \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
    -d '{
          "cf_api_id": "a1b2c3d4e5f6",
          "cf_api_key": "abc123",
          "name": "my-token"
        }'
```

#### Response

```json
{
  "result": {
    "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
    "cf_api_id": "cf_api_id",
    "created_at": "2019-12-27T18:11:19.117Z",
    "modified_at": "2019-12-27T18:11:19.117Z",
    "name": "name",
    "created_by": "created_by",
    "enabled": true,
    "legacy": true,
    "modified_by": "modified_by"
  },
  "success": true
}
```

## Read token.

**get** `/accounts/{account_id}/ai-search/tokens/{id}`

Read token.

### Path Parameters

- `account_id: string`

- `id: string`

### Returns

- `result: object { id, cf_api_id, created_at, 6 more }`

  - `id: string`

  - `cf_api_id: string`

  - `created_at: string`

  - `modified_at: string`

  - `name: string`

  - `created_by: optional string`

  - `enabled: optional boolean`

  - `legacy: optional boolean`

  - `modified_by: optional string`

- `success: true`

  - `true`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/tokens/$ID \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": {
    "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
    "cf_api_id": "cf_api_id",
    "created_at": "2019-12-27T18:11:19.117Z",
    "modified_at": "2019-12-27T18:11:19.117Z",
    "name": "name",
    "created_by": "created_by",
    "enabled": true,
    "legacy": true,
    "modified_by": "modified_by"
  },
  "success": true
}
```

## Update token.

**put** `/accounts/{account_id}/ai-search/tokens/{id}`

Update token.

### Path Parameters

- `account_id: string`

- `id: string`

### Body Parameters

- `cf_api_id: string`

- `cf_api_key: string`

- `name: string`

- `legacy: optional boolean`

### Returns

- `result: object { id, cf_api_id, created_at, 6 more }`

  - `id: string`

  - `cf_api_id: string`

  - `created_at: string`

  - `modified_at: string`

  - `name: string`

  - `created_by: optional string`

  - `enabled: optional boolean`

  - `legacy: optional boolean`

  - `modified_by: optional string`

- `success: true`

  - `true`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/tokens/$ID \
    -X PUT \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
    -d '{
          "cf_api_id": "a1b2c3d4e5f6",
          "cf_api_key": "abc123",
          "name": "my-token"
        }'
```

#### Response

```json
{
  "result": {
    "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
    "cf_api_id": "cf_api_id",
    "created_at": "2019-12-27T18:11:19.117Z",
    "modified_at": "2019-12-27T18:11:19.117Z",
    "name": "name",
    "created_by": "created_by",
    "enabled": true,
    "legacy": true,
    "modified_by": "modified_by"
  },
  "success": true
}
```

## Delete token.

**delete** `/accounts/{account_id}/ai-search/tokens/{id}`

Delete token.

### Path Parameters

- `account_id: string`

- `id: string`

### Returns

- `result: unknown`

- `success: true`

  - `true`

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-search/tokens/$ID \
    -X DELETE \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

#### Response

```json
{
  "result": {},
  "success": true
}
```

## Domain Types

### Token List Response

- `TokenListResponse object { id, cf_api_id, created_at, 6 more }`

  - `id: string`

  - `cf_api_id: string`

  - `created_at: string`

  - `modified_at: string`

  - `name: string`

  - `created_by: optional string`

  - `enabled: optional boolean`

  - `legacy: optional boolean`

  - `modified_by: optional string`

### Token Create Response

- `TokenCreateResponse object { id, cf_api_id, created_at, 6 more }`

  - `id: string`

  - `cf_api_id: string`

  - `created_at: string`

  - `modified_at: string`

  - `name: string`

  - `created_by: optional string`

  - `enabled: optional boolean`

  - `legacy: optional boolean`

  - `modified_by: optional string`

### Token Read Response

- `TokenReadResponse object { id, cf_api_id, created_at, 6 more }`

  - `id: string`

  - `cf_api_id: string`

  - `created_at: string`

  - `modified_at: string`

  - `name: string`

  - `created_by: optional string`

  - `enabled: optional boolean`

  - `legacy: optional boolean`

  - `modified_by: optional string`

### Token Update Response

- `TokenUpdateResponse object { id, cf_api_id, created_at, 6 more }`

  - `id: string`

  - `cf_api_id: string`

  - `created_at: string`

  - `modified_at: string`

  - `name: string`

  - `created_by: optional string`

  - `enabled: optional boolean`

  - `legacy: optional boolean`

  - `modified_by: optional string`

### Token Delete Response

- `TokenDeleteResponse = unknown`

---

---
title: REST API
description: Manage AI Search instances and sync jobs over HTTP using the Instances REST API.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# REST API

Use the AI Search REST API to manage instances and sync jobs over HTTP.

## Authentication

All requests require an API token with **AI Search:Edit** and **AI Search:Run** permissions.

1. In the Cloudflare dashboard, go to **My Profile** \> **API Tokens**.  
[ Go to **API Tokens** ](https://dash.cloudflare.com/profile/api-tokens)
2. Select **Create Token**.
3. Select **Create Custom Token**.
4. Enter a **Token name**, for example `AI Search Manager`.
5. Under **Permissions**, add two permissions:  
   * **Account** \> **AI Search:Edit**  
   * **Account** \> **AI Search:Run**
6. Select **Continue to summary**, then select **Create Token**.
7. Copy and save the token value. This is your `API_TOKEN`.

Include the token in the `Authorization` header for all requests:

```

Authorization: Bearer <API_TOKEN>


```

## API paths

AI Search APIs are available at two base paths:

| Path                                                                    | Description                                                                                                  |
| ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| /accounts/{account\_id}/ai-search/instances/{id}                        | Operates on a specific instance                                                                              |
| /accounts/{account\_id}/ai-search/namespaces/{namespace}/instances/{id} | Operates on instances within a [namespace](https://developers.cloudflare.com/ai-search/concepts/namespaces/) |

The available operations are the same for both paths. For the namespace-scoped API, refer to the [Namespace API reference](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/namespaces/).

## Instances

Create, list, get, update, and delete AI Search instances. For the full specification, refer to the [Instances API reference](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/instances/).

| Operation                                                                                                    | Method | Description                   |
| ------------------------------------------------------------------------------------------------------------ | ------ | ----------------------------- |
| [Create](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/instances/methods/create/) | POST   | Create a new instance         |
| [List](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/instances/methods/list/)     | GET    | List all instances            |
| [Get](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/instances/methods/read/)      | GET    | Get an instance by ID         |
| [Update](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/instances/methods/update/) | PUT    | Update instance configuration |
| [Delete](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/instances/methods/delete/) | DELETE | Delete an instance            |
| [Stats](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/instances/methods/stats/)   | GET    | Get indexing statistics       |

### Example: Create an instance

Create an instance in the default namespace:

Terminal window

```

curl -X POST "https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai-search/instances" \

  -H "Authorization: Bearer <API_TOKEN>" \

  -H "Content-Type: application/json" \

  -d '{

    "id": "my-instance"

  }'


```

## Jobs

Trigger and monitor [sync jobs](https://developers.cloudflare.com/ai-search/configuration/indexing/syncing/) that scan your data source and index new or updated content. For the full specification, refer to the [Jobs API reference](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/instances/subresources/jobs/).

| Operation                                                                                                                      | Method | Description                   |
| ------------------------------------------------------------------------------------------------------------------------------ | ------ | ----------------------------- |
| [Create](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/instances/subresources/jobs/methods/create/) | POST   | Trigger a new sync job        |
| [List](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/instances/subresources/jobs/methods/list/)     | GET    | List all jobs for an instance |
| [Get](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/instances/subresources/jobs/methods/read/)      | GET    | Get job details               |
| [Logs](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/instances/subresources/jobs/methods/logs/)     | GET    | View job logs                 |

### Example: Trigger a sync job

Start a new sync job for an instance:

Terminal window

```

curl -X POST "https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai-search/instances/<INSTANCE_NAME>/jobs" \

  -H "Authorization: Bearer <API_TOKEN>"


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/api/","name":"API"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/api/instances/","name":"Instances"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/api/instances/rest-api/","name":"REST API"}}]}
```

---

---
title: Workers binding
description: Manage AI Search instances from a Cloudflare Worker using the Instances Workers binding.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Workers binding

[Workers](https://developers.cloudflare.com/workers/) provides a serverless execution environment that allows you to create new applications or augment existing ones. Use a [Workers binding](https://developers.cloudflare.com/workers/runtime-apis/bindings/) to create, list, update, and delete AI Search instances from a Cloudflare Worker. You can also check instance configuration and monitor indexing progress.

## Configure the binding

To use AI Search with Workers, you must create an AI Search binding. You create bindings by updating your [Wrangler configuration](https://developers.cloudflare.com/workers/wrangler/configuration/). AI Search provides two types of bindings:

* Namespace binding: `ai_search_namespaces`
* Instance binding: `ai_search`

### Namespace binding

Access all instances within a [namespace](https://developers.cloudflare.com/ai-search/concepts/namespaces/). You can get, create, list, and delete instances at runtime.

* [  wrangler.jsonc ](#tab-panel-6452)
* [  wrangler.toml ](#tab-panel-6453)

JSONC

```

{

  "$schema": "./node_modules/wrangler/config-schema.json",

  "compatibility_date": "2026-03-27",

  "ai_search_namespaces": [

    {

      "binding": "AI_SEARCH",

      "namespace": "my-namespace"

    }

  ]

}


```

TOML

```

compatibility_date = "2026-03-27"


[[ai_search_namespaces]]

binding = "AI_SEARCH"

namespace = "my-namespace"


```

| Field     | Type    | Required | Description                                                                                                                                                                                                                   |
| --------- | ------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| binding   | string  | Yes      | The variable name available on env. For example, "AI\_SEARCH" makes it accessible as env.AI\_SEARCH.                                                                                                                          |
| namespace | string  | Yes      | The [namespace](https://developers.cloudflare.com/ai-search/concepts/namespaces/) to bind to. A default namespace is created automatically for every account. If the namespace does not exist, Wrangler creates it on deploy. |
| remote    | boolean | No       | Set to true for local development with wrangler dev.                                                                                                                                                                          |

### Instance binding

Bind directly to a single instance in the `default` namespace. Use this when you know which instance you need at deploy time.

* [  wrangler.jsonc ](#tab-panel-6454)
* [  wrangler.toml ](#tab-panel-6455)

JSONC

```

{

  "$schema": "./node_modules/wrangler/config-schema.json",

  "compatibility_date": "2026-03-27",

  "ai_search": [

    {

      "binding": "MY_SEARCH",

      "instance_name": "my-instance"

    }

  ]

}


```

TOML

```

compatibility_date = "2026-03-27"


[[ai_search]]

binding = "MY_SEARCH"

instance_name = "my-instance"


```

| Field          | Type    | Required | Description                                                                                          |
| -------------- | ------- | -------- | ---------------------------------------------------------------------------------------------------- |
| binding        | string  | Yes      | The variable name available on env. For example, "MY\_SEARCH" makes it accessible as env.MY\_SEARCH. |
| instance\_name | string  | Yes      | The name of the AI Search instance. Must exist in the default namespace at deploy time.              |
| remote         | boolean | No       | Set to true for local development with wrangler dev.                                                 |

## Namespace methods

The following methods are only available when using the `ai_search_namespaces` binding. The namespace handle (`env.AI_SEARCH`) exposes methods for working with instances within a [namespace](https://developers.cloudflare.com/ai-search/concepts/namespaces/).

### `get()`

Returns a handle to a specific instance. This is **synchronous** and does not make a network call. The instance is resolved lazily when you call methods like `search()` or `info()`.

TypeScript

```

const instance = env.AI_SEARCH.get("my-instance");

const results = await instance.search({

  messages: [{ role: "user", content: "What is Cloudflare?" }],

});


```

#### Parameters

| Parameter | Type   | Required | Description                                  |
| --------- | ------ | -------- | -------------------------------------------- |
| name      | string | Yes      | The name of the instance to get a handle to. |

### `list()`

Returns all instances within the namespace.

TypeScript

```

const { result, result_info } = await env.AI_SEARCH.list();


for (const instance of result) {

  console.log(`${instance.id} (${instance.type}) - ${instance.status}`);

}

// result_info.total_count contains the total number of instances


```

#### Parameters

| Parameter            | Type   | Required | Description                                                     |
| -------------------- | ------ | -------- | --------------------------------------------------------------- |
| page                 | number | No       | The page number to return. Defaults to 1.                       |
| per\_page            | number | No       | The number of instances per page. Defaults to 20. Maximum 100.  |
| search               | string | No       | Search instances by ID.                                         |
| order\_by            | string | No       | Sort column. Valid value: created\_at. Defaults to created\_at. |
| order\_by\_direction | string | No       | Sort direction. Valid values: asc, desc. Defaults to desc.      |

#### Response

| Field                     | Type    | Description                                                          |
| ------------------------- | ------- | -------------------------------------------------------------------- |
| result                    | array   | Array of instance objects.                                           |
| result\[\].id             | string  | The instance identifier.                                             |
| result\[\].type           | string  | The data source type (r2, web-crawler, or null for empty instances). |
| result\[\].source         | string  | The data source location.                                            |
| result\[\].status         | string  | The instance status (active, waiting, indexing).                     |
| result\[\].enable         | boolean | Whether the instance is enabled.                                     |
| result\[\].namespace      | string  | The namespace the instance belongs to.                               |
| result\[\].created\_at    | string  | ISO 8601 timestamp of when the instance was created.                 |
| result\[\].modified\_at   | string  | ISO 8601 timestamp of the last modification.                         |
| result\_info              | object  | Pagination metadata.                                                 |
| result\_info.total\_count | number  | Total number of instances in the namespace.                          |

### `create()`

Creates a new instance and returns a handle to it. You can create instances backed by a data source or create empty instances for use with the [Items API](https://developers.cloudflare.com/ai-search/api/items/workers-binding/).

**Create an empty instance for file uploads:**

AI Search instances come with [built-in storage](https://developers.cloudflare.com/ai-search/configuration/data-source/built-in-storage/) where you can upload documents directly.

TypeScript

```

const instance = await env.AI_SEARCH.create({

  id: "knowledge-base",

});


// Upload documents using the Items API

await instance.items.upload("guide.pdf", pdfArrayBuffer);


```

**Create a web-crawler instance:**

Automatically crawl and index a website that you own. For more configuration options, refer to [Website data source](https://developers.cloudflare.com/ai-search/configuration/data-source/website/).

TypeScript

```

const instance = await env.AI_SEARCH.create({

  id: "my-docs",

  type: "web-crawler",

  source: "developers.cloudflare.com",

});


```

**Create an R2-backed instance:**

Index documents stored in an [R2](https://developers.cloudflare.com/r2/) bucket. For more configuration options, refer to [R2 data source](https://developers.cloudflare.com/ai-search/configuration/data-source/r2/).

TypeScript

```

const instance = await env.AI_SEARCH.create({

  id: "internal-docs",

  type: "r2",

  source: "my-docs-bucket",

});


```

#### Parameters

`id` ` string ` required

The unique identifier for the AI Search instance. Must be 1-64 characters and match the pattern `^[a-z0-9_]+(?:-[a-z0-9_]+)*$`.

---

`type` ` string ` optional

The type of data source. Valid values: `r2`, `web-crawler`. Required when creating an instance with a data source. Omit when creating an empty instance for use with the [Items API](https://developers.cloudflare.com/ai-search/api/items/workers-binding/).

---

`source` ` string ` optional

The data source location. For `r2` type, this is the R2 bucket name. For `web-crawler` type, this is the website domain. Required when `type` is specified.

---

`source_params` ` object ` optional

Additional parameters for the data source.

* `prefix` ` string ` optional  
   * For R2 sources, limits indexing to objects with this key prefix.
* `r2_jurisdiction` ` string ` optional  
   * The jurisdiction for the R2 bucket, for example `eu`.
* `include_items` ` array ` optional  
   * Glob patterns for paths to include in indexing. For example: `["/blog/**", "/docs/**/*.html"]`.
* `exclude_items` ` array ` optional  
   * Glob patterns for paths to exclude from indexing. For example: `["/admin/**", "/private/**"]`.
* `web_crawler` ` object ` optional  
   * Configuration for web crawler sources.  
   * `parse_type` ` string ` optional  
         * The parsing method. Valid value: `sitemap`.  
   * `parse_options` ` object ` optional  
         * `include_headers` ` object ` optional  
                  * Custom HTTP headers to include when crawling.  
         * `include_images` ` boolean ` optional  
                  * Whether to include images in the index.  
         * `specific_sitemaps` ` array ` optional  
                  * Specific sitemap URLs to crawl. For example: `["https://example.com/sitemap.xml"]`.  
         * `use_browser_rendering` ` boolean ` optional  
                  * Use Browser Run (formerly Browser Rendering) to crawl JavaScript-rendered pages.  
   * `store_options` ` object ` optional  
         * `storage_type` ` string ` optional  
                  * The storage type. Valid value: `r2`.  
         * `storage_id` ` string ` optional  
                  * The storage bucket ID.  
         * `r2_jurisdiction` ` string ` optional  
                  * The jurisdiction for the storage bucket.

---

`index_method` ` object ` optional

Configures which indexing methods are enabled for the instance. Determines whether vector (semantic) search, keyword search, or both are available. At least one must be `true`.

* `vector` ` boolean ` optional  
   * Enable vector-based semantic search. Defaults to `true`.
* `keyword` ` boolean ` optional  
   * Enable keyword-based search. Defaults to `false`.

Set both to `true` for hybrid search.

---

`fusion_method` ` string ` optional

Controls how vector and keyword scores are combined when using hybrid search. Valid values: `rrf` (Reciprocal Rank Fusion), `max` (takes the maximum score). Defaults to `rrf`.

---

`indexing_options` ` object ` optional

Configuration for how content is indexed.

* `keyword_tokenizer` ` string ` optional  
   * The tokenizer used for keyword search indexing. Valid values: `porter` (stemming-based), `trigram` (character n-gram). Defaults to `porter`.

---

`retrieval_options` ` object ` optional

Default retrieval configuration for the instance. These defaults can be overridden per-request using `ai_search_options`.

* `keyword_match_mode` ` string ` optional  
   * Controls how keyword (BM25) matching selects candidate documents. `and` requires all terms to match. `or` requires any term to match. Defaults to `and`.
* `boost_by` ` array ` optional  
   * Default boost fields applied to all search queries. Maximum 3 items. Each item has:  
         * `field` ` string ` required \- The metadata field name to boost by. Maximum 64 characters.  
         * `direction` ` string ` optional \- The boost direction. Valid values: `asc`, `desc`, `exists`, `not_exists`.

---

`sync_interval` ` number ` optional

Seconds between automatic data source syncs. Valid values: `3600`, `7200`, `14400`, `21600`, `43200`, `86400`. Defaults to `21600` (6 hours).

---

`token_id` ` string ` optional

The UUID of the [service API token](https://developers.cloudflare.com/ai-search/configuration/indexing/service-api-token/) to use for this instance. Only required if you have never created an AI Search instance before. Refer to the [API get started guide](https://developers.cloudflare.com/ai-search/get-started/api/) for how to create and register a service token.

---

`ai_gateway_id` ` string ` optional

The AI Gateway ID to route requests through for logging and analytics.

---

`embedding_model` ` string ` optional

The embedding model to use for vectorizing content.

---

`ai_search_model` ` string ` optional

The text-generation model to use for generating responses.

---

`rewrite_query` ` boolean ` optional

Enable query rewriting to improve retrieval accuracy. Defaults to `false`.

---

`rewrite_model` ` string ` optional

The model to use for query rewriting.

---

`reranking` ` boolean ` optional

Enable reranking to reorder retrieved results by semantic relevance. Defaults to `false`.

---

`reranking_model` ` string ` optional

The reranking model to use. Valid value: `@cf/baai/bge-reranker-base`.

---

`chunk_size` ` number ` optional

The size of chunks when splitting documents. Minimum value: `64`.

---

`chunk_overlap` ` number ` optional

The overlap between chunks. Minimum value: `0`.

---

`max_num_results` ` number ` optional

The default maximum number of results to return. Minimum value: `1`.

---

`score_threshold` ` number ` optional

The default minimum score threshold for results. Minimum value: `0`.

---

`cache` ` boolean ` optional

Enable response caching. Defaults to `true`.

---

`cache_threshold` ` string ` optional

The cache matching threshold. Valid values: `super_strict_match`, `close_enough`, `flexible_friend`, `anything_goes`. Defaults to `close_enough`.

---

`custom_metadata` ` array ` optional

Custom metadata fields to extract and index from documents.

* `field_name` ` string ` required  
   * The name of the metadata field.
* `data_type` ` string ` required  
   * The data type of the field. Valid values: `text`, `number`, `boolean`, `datetime`.

---

`enable` ` boolean ` optional

Whether the instance is enabled. Defaults to `true`.

#### Response

Returns an `AiSearchInstance` handle that is immediately usable for calling methods like `search()`, `info()`, `stats()`, and `items.upload()`. Call `info()` on the handle to get the instance configuration.

### `delete()`

Permanently deletes an instance and all its indexed content. This action cannot be undone.

TypeScript

```

await env.AI_SEARCH.delete("old-docs");


```

#### Parameters

| Parameter | Type   | Required | Description                         |
| --------- | ------ | -------- | ----------------------------------- |
| name      | string | Yes      | The name of the instance to delete. |

#### Response

Returns `void`. Throws an error if the instance does not exist.

Warning

Deleting an instance permanently removes all indexed data, including embeddings, chunks, and source files.

## Instance methods

The following methods are available on both the `ai_search_namespaces` and `ai_search` bindings. With the namespace binding, call methods on the handle returned by `get()`. With the instance binding, call methods directly on the binding (for example, `env.MY_SEARCH.info()`).

The examples below use the namespace binding.

### `update()`

Partially updates the instance configuration. Only the fields you pass are modified.

TypeScript

```

const updated = await env.AI_SEARCH.get("my-instance").update({

  ai_search_model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast",

  reranking: true,

});


```

#### Parameters

Accepts a partial version of the [create parameters](#parameters). Only the fields you include are updated.

| Field              | Type    | Description                                                           |
| ------------------ | ------- | --------------------------------------------------------------------- |
| ai\_search\_model  | string  | The text-generation model.                                            |
| embedding\_model   | string  | The embedding model.                                                  |
| index\_method      | object  | Indexing methods: \\{ vector: boolean, keyword: boolean \\}.          |
| fusion\_method     | string  | How vector and keyword scores are combined (rrf or max).              |
| indexing\_options  | object  | Indexing configuration including keyword\_tokenizer.                  |
| retrieval\_options | object  | Retrieval configuration including keyword\_match\_mode and boost\_by. |
| reranking          | boolean | Turn on or off reranking.                                             |
| reranking\_model   | string  | The reranking model.                                                  |
| rewrite\_query     | boolean | Turn on or off query rewriting.                                       |
| rewrite\_model     | string  | The query rewriting model.                                            |
| source             | string  | Update the data source location.                                      |
| cache              | boolean | Turn on or off response caching.                                      |
| chunk\_size        | number  | Token size of each chunk.                                             |
| chunk\_overlap     | number  | Token overlap between chunks.                                         |
| score\_threshold   | number  | Minimum score threshold for results.                                  |
| max\_num\_results  | number  | Maximum number of results per query.                                  |
| custom\_metadata   | array   | Custom metadata field definitions.                                    |
| sync\_interval     | number  | Seconds between automatic data source syncs.                          |

#### Response

Returns the updated instance configuration. Same shape as [info()](#response-2).

### `info()`

Returns the current configuration and metadata for the instance.

TypeScript

```

const info = await env.AI_SEARCH.get("my-instance").info();


```

#### Response

| Field              | Type    | Description                                                           |
| ------------------ | ------- | --------------------------------------------------------------------- |
| id                 | string  | The instance identifier.                                              |
| type               | string  | The data source type (r2, web-crawler, or null).                      |
| source             | string  | The data source location.                                             |
| namespace          | string  | The namespace the instance belongs to.                                |
| status             | string  | The instance status (active, waiting, indexing).                      |
| enable             | boolean | Whether the instance is enabled.                                      |
| created\_at        | string  | Timestamp of when the instance was created.                           |
| modified\_at       | string  | Timestamp of the last modification.                                   |
| ai\_search\_model  | string  | The text-generation model.                                            |
| embedding\_model   | string  | The embedding model.                                                  |
| reranking          | boolean | Whether reranking is enabled.                                         |
| reranking\_model   | string  | The reranking model.                                                  |
| rewrite\_query     | boolean | Whether query rewriting is enabled.                                   |
| rewrite\_model     | string  | The query rewriting model.                                            |
| cache              | boolean | Whether response caching is enabled.                                  |
| cache\_threshold   | string  | The similarity threshold for cache hits.                              |
| index\_method      | object  | Which indexing methods are enabled (vector, keyword).                 |
| fusion\_method     | string  | How vector and keyword scores are combined (rrf or max).              |
| indexing\_options  | object  | Indexing configuration including keyword\_tokenizer.                  |
| retrieval\_options | object  | Retrieval configuration including keyword\_match\_mode and boost\_by. |
| chunk\_size        | number  | Token size of each chunk.                                             |
| chunk\_overlap     | number  | Token overlap between chunks.                                         |
| score\_threshold   | number  | Minimum score threshold for results.                                  |
| max\_num\_results  | number  | Maximum number of results per query.                                  |
| sync\_interval     | number  | Seconds between automatic data source syncs.                          |
| custom\_metadata   | array   | Custom metadata field definitions.                                    |
| last\_activity     | string  | Timestamp of the last indexing activity.                              |

### `stats()`

Returns the current indexing progress for the instance. Use this to poll for completion after creating an instance or uploading files.

TypeScript

```

const stats = await env.AI_SEARCH.get("my-instance").stats();


```

#### Response

| Field                         | Type   | Description                                       |
| ----------------------------- | ------ | ------------------------------------------------- |
| queued                        | number | Items waiting to be processed.                    |
| running                       | number | Items currently being processed.                  |
| completed                     | number | Items successfully indexed.                       |
| error                         | number | Items that failed to index.                       |
| skipped                       | number | Items skipped during indexing.                    |
| outdated                      | number | Items that need re-indexing.                      |
| last\_activity                | string | ISO 8601 timestamp of the last indexing activity. |
| file\_embed\_errors           | object | Map of file IDs to embedding error details.       |
| engine.vectorize.vectorsCount | number | Total number of vectors stored.                   |
| engine.vectorize.dimensions   | number | Dimensions of the vector embeddings.              |
| engine.r2.payloadSizeBytes    | number | Total size of stored payloads in bytes.           |
| engine.r2.metadataSizeBytes   | number | Total size of stored metadata in bytes.           |
| engine.r2.objectCount         | number | Total number of objects in storage.               |

## Local development

Local development is supported by proxying requests to your deployed AI Search instance. Add `remote: true` to your binding configuration to enable local development with `wrangler dev`.

JSONC

```

// wrangler.jsonc

{

  "ai_search": [

    {

      "binding": "MY_SEARCH",

      "instance_name": "my-instance",

      "remote": true,

    },

  ],

}


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/api/","name":"API"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/api/instances/","name":"Instances"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/api/instances/workers-binding/","name":"Workers binding"}}]}
```

---

---
title: REST API
description: Upload, list, and manage documents in AI Search instances using the Items REST API.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# REST API

Use the AI Search REST API to upload, list, and manage individual documents within an instance.

Note

The Items API uploads files to an instance's built-in storage. For more details, refer to [Built-in storage](https://developers.cloudflare.com/ai-search/configuration/data-source/built-in-storage/).

## Authentication

All requests require an API token with **AI Search:Edit** and **AI Search:Run** permissions.

1. In the Cloudflare dashboard, go to **My Profile** \> **API Tokens**.  
[ Go to **API Tokens** ](https://dash.cloudflare.com/profile/api-tokens)
2. Select **Create Token**.
3. Select **Create Custom Token**.
4. Enter a **Token name**, for example `AI Search Manager`.
5. Under **Permissions**, add two permissions:  
   * **Account** \> **AI Search:Edit**  
   * **Account** \> **AI Search:Run**
6. Select **Continue to summary**, then select **Create Token**.
7. Copy and save the token value. This is your `API_TOKEN`.

Include the token in the `Authorization` header for all requests:

```

Authorization: Bearer <API_TOKEN>


```

## API paths

AI Search APIs are available at two base paths:

| Path                                                                     | Description                                                                                                  |
| ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
| /accounts/{account\_id}/ai-search/instances/{id}/                        | Operates on a specific instance                                                                              |
| /accounts/{account\_id}/ai-search/namespaces/{namespace}/instances/{id}/ | Operates on instances within a [namespace](https://developers.cloudflare.com/ai-search/concepts/namespaces/) |

The available operations are the same for both paths. For the namespace-scoped API, refer to the [Namespace API reference](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/namespaces/).

## Items

Upload, list, get, delete, and download items within an instance. For the full specification, refer to the [Items API reference](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/namespaces/subresources/instances/subresources/items/).

| Operation                                                                                                                                                   | Method | Description                    |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------------------------------ |
| [Upload](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/namespaces/subresources/instances/subresources/items/methods/upload/)     | POST   | Upload a document for indexing |
| [List](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/namespaces/subresources/instances/subresources/items/methods/list/)         | GET    | List all items in an instance  |
| [Get](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/namespaces/subresources/instances/subresources/items/methods/get/)           | GET    | Get item info by ID            |
| [Delete](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/namespaces/subresources/instances/subresources/items/methods/delete/)     | DELETE | Delete an item                 |
| [Download](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/namespaces/subresources/instances/subresources/items/methods/download/) | GET    | Download the original file     |

### Example: Upload a document

Upload a file to an instance:

Terminal window

```

curl -X POST "https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai-search/instances/<INSTANCE_NAME>/items" \

  -H "Authorization: Bearer <API_TOKEN>" \

  -F "file=@/path/to/your/file.pdf"


```

### Example: List items

List all items in an instance:

Terminal window

```

curl "https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai-search/instances/<INSTANCE_NAME>/items" \

  -H "Authorization: Bearer <API_TOKEN>"


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/api/","name":"API"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/api/items/","name":"Items"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/api/items/rest-api/","name":"REST API"}}]}
```

---

---
title: Workers binding
description: Upload, list, and manage documents in AI Search instances using the Items Workers binding.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Workers binding

[Workers](https://developers.cloudflare.com/workers/) provides a serverless execution environment that allows you to create new applications or augment existing ones. Use a [Workers binding](https://developers.cloudflare.com/workers/runtime-apis/bindings/) to upload, list, and manage documents in your AI Search instances from a Cloudflare Worker. Access the Items API through the `items` property on an instance handle.

Note

The Items API uploads files to an instance's built-in storage. For more details, refer to [Built-in storage](https://developers.cloudflare.com/ai-search/configuration/data-source/built-in-storage/).

## Configure the binding

To use AI Search with Workers, you must create an AI Search binding. You create bindings by updating your [Wrangler configuration](https://developers.cloudflare.com/workers/wrangler/configuration/). AI Search provides two types of bindings:

* Namespace binding: `ai_search_namespaces`
* Instance binding: `ai_search`

### Namespace binding

Access all instances within a [namespace](https://developers.cloudflare.com/ai-search/concepts/namespaces/). You can get, create, list, and delete instances at runtime.

* [  wrangler.jsonc ](#tab-panel-6456)
* [  wrangler.toml ](#tab-panel-6457)

JSONC

```

{

  "$schema": "./node_modules/wrangler/config-schema.json",

  "compatibility_date": "2026-03-27",

  "ai_search_namespaces": [

    {

      "binding": "AI_SEARCH",

      "namespace": "my-namespace"

    }

  ]

}


```

TOML

```

compatibility_date = "2026-03-27"


[[ai_search_namespaces]]

binding = "AI_SEARCH"

namespace = "my-namespace"


```

| Field     | Type    | Required | Description                                                                                                                                                                                                                   |
| --------- | ------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| binding   | string  | Yes      | The variable name available on env. For example, "AI\_SEARCH" makes it accessible as env.AI\_SEARCH.                                                                                                                          |
| namespace | string  | Yes      | The [namespace](https://developers.cloudflare.com/ai-search/concepts/namespaces/) to bind to. A default namespace is created automatically for every account. If the namespace does not exist, Wrangler creates it on deploy. |
| remote    | boolean | No       | Set to true for local development with wrangler dev.                                                                                                                                                                          |

### Instance binding

Bind directly to a single instance in the `default` namespace. Use this when you know which instance you need at deploy time.

* [  wrangler.jsonc ](#tab-panel-6458)
* [  wrangler.toml ](#tab-panel-6459)

JSONC

```

{

  "$schema": "./node_modules/wrangler/config-schema.json",

  "compatibility_date": "2026-03-27",

  "ai_search": [

    {

      "binding": "MY_SEARCH",

      "instance_name": "my-instance"

    }

  ]

}


```

TOML

```

compatibility_date = "2026-03-27"


[[ai_search]]

binding = "MY_SEARCH"

instance_name = "my-instance"


```

| Field          | Type    | Required | Description                                                                                          |
| -------------- | ------- | -------- | ---------------------------------------------------------------------------------------------------- |
| binding        | string  | Yes      | The variable name available on env. For example, "MY\_SEARCH" makes it accessible as env.MY\_SEARCH. |
| instance\_name | string  | Yes      | The name of the AI Search instance. Must exist in the default namespace at deploy time.              |
| remote         | boolean | No       | Set to true for local development with wrangler dev.                                                 |

## Methods

The Items API methods are available on both the `ai_search_namespaces` and `ai_search` bindings. With the namespace binding, call methods on the handle returned by `get()`. With the instance binding, call methods directly on the binding (for example, `env.MY_SEARCH.items.upload()`).

The examples below use the namespace binding.

TypeScript

```

const instance = env.AI_SEARCH.get("my-instance");


```

### `items.upload()`

Uploads a document for indexing. Returns immediately. The document is queued for processing.

TypeScript

```

// Upload from a string

await instance.items.upload(

  "faq.md",

  "# FAQ\n\nQ: How do I reset my password?\nA: Go to Settings > Security...",

);


// Upload from an ArrayBuffer

const pdfResponse = await fetch("https://example.com/guide.pdf");

const pdfBuffer = await pdfResponse.arrayBuffer();

await instance.items.upload("guide.pdf", pdfBuffer);


// Upload from a ReadableStream

await instance.items.upload("doc.txt", request.body);


```

#### Upload with metadata

Attach [custom metadata](https://developers.cloudflare.com/ai-search/configuration/indexing/metadata/) to a document for filtering in search queries. Custom metadata fields must be defined on the instance first using the [update()](https://developers.cloudflare.com/ai-search/api/instances/workers-binding/#update) method or at creation time.

TypeScript

```

await instance.items.upload("guide.pdf", pdfBuffer, {

  metadata: {

    category: "onboarding",

    language: "en",

    version: "2.0",

  },

});


```

#### Parameters

| Parameter        | Type                                   | Required | Description                                                                                                                                                            |
| ---------------- | -------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name             | string                                 | Yes      | The filename for the uploaded document. Used as the item key.                                                                                                          |
| content          | ReadableStream, ArrayBuffer, or string | Yes      | The document content. Maximum file size is 4 MB. Pass a string for plain text or markdown, an ArrayBuffer for binary files, or a ReadableStream for streaming uploads. |
| options.metadata | Record<string, string>                 | No       | Custom metadata key-value pairs to attach to the item. Use for filtering in search queries. Maximum 5 fields per instance.                                             |

#### Response

| Field | Type   | Description                      |
| ----- | ------ | -------------------------------- |
| id    | string | The unique item identifier.      |
| key   | string | The filename or key of the item. |

### `items.uploadAndPoll()`

Uploads a document and polls until processing completes or the timeout is reached. Use this when you need to search the document immediately after upload.

TypeScript

```

// Wait for a specific document to finish indexing before searching

const item = await instance.items.uploadAndPoll(

  "handbook.txt",

  handbookContent,

);

console.log(`handbook.txt status: ${item.status}`); // "completed"


// Now search across all uploaded documents

const results = await instance.search({

  messages: [{ role: "user", content: "password reset policy" }],

});


```

#### Parameters

Same as [items.upload()](#parameters), with additional polling options:

| Parameter              | Type   | Required | Description                                                                          |
| ---------------------- | ------ | -------- | ------------------------------------------------------------------------------------ |
| options.pollIntervalMs | number | No       | How often to check the item status, in milliseconds. Defaults to 1000.               |
| options.timeoutMs      | number | No       | Maximum time to wait for processing to complete, in milliseconds. Defaults to 30000. |

#### Response

Returns the full item object after polling completes:

| Field          | Type   | Description                                                                  |
| -------------- | ------ | ---------------------------------------------------------------------------- |
| id             | string | The unique item identifier.                                                  |
| key            | string | The filename or key of the item.                                             |
| status         | string | The processing status: queued, running, completed, error, skipped, outdated. |
| chunks\_count  | number | Number of chunks created from the document.                                  |
| file\_size     | number | Size of the uploaded file in bytes.                                          |
| metadata       | object | Item metadata including filename, folder, and timestamp.                     |
| source\_id     | string | The source identifier (for example, builtin for uploaded files).             |
| created\_at    | string | Timestamp of when the item was created.                                      |
| last\_seen\_at | string | Timestamp of when the item was last seen during indexing.                    |

### `items.list()`

Returns a paginated list of items in the instance.

TypeScript

```

const { result, result_info } = await instance.items.list();


for (const item of result) {

  console.log(`${item.key} (${item.status})`);

}

// result_info.total_count contains the total number of items


```

#### Parameters

| Parameter | Type   | Required | Description                                                                           |
| --------- | ------ | -------- | ------------------------------------------------------------------------------------- |
| page      | number | No       | The page number to return. Defaults to 1.                                             |
| per\_page | number | No       | The number of items per page. Defaults to 20. Maximum 50.                             |
| status    | string | No       | Filter by processing status: queued, running, completed, error, skipped, or outdated. |
| sort\_by  | string | No       | Sort order for items: status (default) or modified\_at.                               |
| search    | string | No       | Search items by text content.                                                         |
| source    | string | No       | Filter by source identifier (for example, builtin for uploaded files).                |

#### Response

| Field                     | Type   | Description                                                                  |
| ------------------------- | ------ | ---------------------------------------------------------------------------- |
| result                    | array  | Array of item objects.                                                       |
| result\[\].id             | string | The unique item identifier.                                                  |
| result\[\].key            | string | The filename or key of the item.                                             |
| result\[\].status         | string | The processing status: queued, running, completed, error, skipped, outdated. |
| result\[\].chunks\_count  | number | Number of chunks created from the document.                                  |
| result\[\].file\_size     | number | Size of the uploaded file in bytes.                                          |
| result\[\].metadata       | object | Item metadata including filename, folder, and timestamp.                     |
| result\[\].source\_id     | string | The source identifier (for example, builtin for uploaded files).             |
| result\[\].created\_at    | string | Timestamp of when the item was created.                                      |
| result\[\].last\_seen\_at | string | Timestamp of when the item was last seen during indexing.                    |
| result\_info              | object | Pagination metadata.                                                         |
| result\_info.count        | number | Number of items in the current page.                                         |
| result\_info.total\_count | number | Total number of items in the instance.                                       |
| result\_info.page         | number | The current page number.                                                     |
| result\_info.per\_page    | number | Items per page.                                                              |

### `items.delete()`

Deletes an item and its indexed chunks.

TypeScript

```

await instance.items.delete("item-id-123");


```

#### Parameters

| Parameter | Type   | Required | Description                                  |
| --------- | ------ | -------- | -------------------------------------------- |
| itemId    | string | Yes      | The unique identifier of the item to delete. |

#### Response

Returns `void`. Throws an error if the item does not exist.

### `items.get()`

Returns a handle to a specific item for retrieving its status or downloading the original file.

#### `items.get().info()`

Returns the status and metadata of a specific item.

TypeScript

```

const itemInfo = await instance.items.get("item-id-123").info();


```

##### Parameters

| Parameter | Type   | Required | Description                        |
| --------- | ------ | -------- | ---------------------------------- |
| itemId    | string | Yes      | The unique identifier of the item. |

##### Response

| Field          | Type   | Description                                                                  |
| -------------- | ------ | ---------------------------------------------------------------------------- |
| id             | string | The unique item identifier.                                                  |
| key            | string | The filename or key of the item.                                             |
| status         | string | The processing status: queued, running, completed, error, skipped, outdated. |
| chunks\_count  | number | Number of chunks created from the document.                                  |
| file\_size     | number | Size of the uploaded file in bytes.                                          |
| metadata       | object | Item metadata including filename, folder, and timestamp.                     |
| source\_id     | string | The source identifier (for example, builtin for uploaded files).             |
| created\_at    | string | Timestamp of when the item was created.                                      |
| last\_seen\_at | string | Timestamp of when the item was last seen during indexing.                    |

#### `items.get().download()`

Downloads the original source file for an item.

TypeScript

```

const file = await instance.items.get("item-id-123").download();

// file.body is a ReadableStream


```

##### Parameters

| Parameter | Type   | Required | Description                        |
| --------- | ------ | -------- | ---------------------------------- |
| itemId    | string | Yes      | The unique identifier of the item. |

##### Response

| Field       | Type           | Description                                               |
| ----------- | -------------- | --------------------------------------------------------- |
| filename    | string         | The original filename.                                    |
| contentType | string         | The MIME type of the file (for example, application/pdf). |
| size        | number         | The file size in bytes.                                   |
| body        | ReadableStream | A readable stream of the file contents.                   |

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/api/","name":"API"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/api/items/","name":"Items"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/api/items/workers-binding/","name":"Workers binding"}}]}
```

---

---
title: Metadata filter (legacy)
description: Reference for the legacy AutoRAG metadata filter format used with the previous REST API.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Metadata filter (legacy)

This page documents the filter format used by the legacy AutoRAG REST API. For the new AI Search REST API filter syntax, refer to [Metadata filtering](https://developers.cloudflare.com/ai-search/configuration/indexing/metadata/).

## Comparison filter

Compare a metadata attribute (for example, `folder` or `timestamp`) with a target value:

JavaScript

```

filters: {

  type: "eq",

  key: "folder",

  value: "customer-a/"

}


```

### Operators

| Operator | Description              |
| -------- | ------------------------ |
| eq       | Equals                   |
| ne       | Not equals               |
| gt       | Greater than             |
| gte      | Greater than or equal to |
| lt       | Less than                |
| lte      | Less than or equal to    |

## Compound filter

Combine multiple comparison filters with a logical operator:

JavaScript

```

filters: {

  type: "and",

  filters: [

    { type: "eq", key: "folder", value: "customer-a/" },

    { type: "gte", key: "timestamp", value: "1735689600000" }

  ]

}


```

The available compound operators are `and` and `or`.

### Limitations

* No nested combinations of `and` and `or`. You can only use one compound operator at a time.
* When using `or`, only the `eq` operator is allowed and all conditions must filter on the same key.

## "Starts with" filter for folders

To filter for all files within a folder and its subfolders, use a compound filter with range operators.

For example, consider this file structure:

* customer-a \- profile.md - contracts - property - contract-1.pdf

Using `{ type: "eq", key: "folder", value: "customer-a/" }` only matches files directly in that folder (like `profile.md`), not files in subfolders.

To match all files starting with `customer-a/`, use a compound filter:

JavaScript

```

filters: {

  type: "and",

  filters: [

    { type: "gt", key: "folder", value: "customer-a//" },

    { type: "lte", key: "folder", value: "customer-a/z" }

  ]

}


```

This filter matches all paths starting with `customer-a/` by using:

* `gt` with `customer-a//` to include paths greater than the `/` ASCII character
* `lte` with `customer-a/z` to include paths up to and including the lowercase `z` ASCII character

## Related

* [Metadata filtering](https://developers.cloudflare.com/ai-search/configuration/indexing/metadata/) \- New AI Search REST API filter format
* [Migrate from AutoRAG Search API](https://developers.cloudflare.com/ai-search/api/migration/rest-api/) \- Migration guide with before/after examples

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/api/","name":"API"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/api/migration/","name":"API Migration"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/api/migration/autorag-filter-format/","name":"Metadata filter (legacy)"}}]}
```

---

---
title: REST API migration
description: Migrate from the legacy AutoRAG REST API endpoints to the new AI Search API endpoints.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# REST API migration

The [AutoRAG API endpoints](https://developers.cloudflare.com/api/resources/autorag/) are the legacy REST API for AI Search. They will continue to work, but all new features and improvements are only available through the new [AI Search API endpoints](https://developers.cloudflare.com/ai-search/api/search/rest-api/).

## Endpoint changes

The legacy AutoRAG API endpoints under `/autorag/rags/` have been replaced by new endpoints under `/ai-search/instances/`.

| Description      | New endpoint                                 | Reference                                                                                                                       |
| ---------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| Chat completions | /ai-search/instances/{name}/chat/completions | [API reference](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/instances/methods/chat%5Fcompletions/) |
| Search           | /ai-search/instances/{name}/search           | [API reference](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/instances/methods/search/)             |

The new API also includes endpoints for [instance management](https://developers.cloudflare.com/ai-search/api/instances/rest-api/), [items](https://developers.cloudflare.com/ai-search/api/items/rest-api/), and [namespace-level search](https://developers.cloudflare.com/ai-search/api/search/rest-api/#cross-instance-search-and-chat) that are not available in the legacy API. For the legacy endpoints, refer to the [AutoRAG API reference](https://developers.cloudflare.com/api/resources/autorag/).

## Chat completions

How to migrate from the AutoRAG `/ai-search` endpoint to the new `/chat/completions` endpoint:

**Before (AutoRAG API):**

Terminal window

```

curl -X POST "https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/autorag/rags/<INSTANCE_NAME>/ai-search" \

  -H "Content-Type: application/json" \

  -H "Authorization: Bearer <API_TOKEN>" \

  -d '{

    "query": "What is Cloudflare?"

  }'


```

**After (AI Search API):**

The new API uses the `messages` array format.

Terminal window

```

curl -X POST "https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai-search/instances/<INSTANCE_NAME>/chat/completions" \

  -H "Content-Type: application/json" \

  -H "Authorization: Bearer <API_TOKEN>" \

  -d '{

    "messages": [

      {

        "content": "What is Cloudflare?",

        "role": "user"

      }

    ]

  }'


```

## Search

How to migrate from the AutoRAG `/search` endpoint to the new `/search` endpoint:

**Before (AutoRAG API):**

Terminal window

```

curl -X POST "https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/autorag/rags/<INSTANCE_NAME>/search" \

  -H "Content-Type: application/json" \

  -H "Authorization: Bearer <API_TOKEN>" \

  -d '{

    "query": "What is Cloudflare?"

  }'


```

**After (AI Search API):**

The new API uses the `messages` array format. The `query` string format is also supported.

Terminal window

```

curl -X POST "https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai-search/instances/<INSTANCE_NAME>/search" \

  -H "Content-Type: application/json" \

  -H "Authorization: Bearer <API_TOKEN>" \

  -d '{

    "messages": [

      {

        "content": "What is Cloudflare?",

        "role": "user"

      }

    ]

  }'


```

## Streaming behavior changes

In the old AutoRAG API, when `stream` was set to `true`, you would only receive the streamed response without the retrieved chunks.

In the new AI Search API, streaming responses include the chunks. The retrieved chunks are sent first as a `chunks` event, followed by the streamed response data. This allows you to display the source chunks immediately while streaming the generated response to the user.

## Filter format

The new AI Search REST API uses Vectorize-style metadata filtering, which differs from the AutoRAG API format. Filters are now nested under `ai_search_options.retrieval.filters` in the request body. For full documentation of the old format, refer to [Metadata filter format (legacy)](https://developers.cloudflare.com/ai-search/api/migration/autorag-filter-format/).

### Operator mapping

The filter operators have been renamed to use a `$` prefix:

| AutoRAG API | AI Search API     |
| ----------- | ----------------- |
| eq          | $eq (or implicit) |
| ne          | $ne               |
| gt          | $gt               |
| gte         | $gte              |
| lt          | $lt               |
| lte         | $lte              |
| $in (new)   |                   |
| $nin (new)  |                   |

### Examples

#### Simple filter

Filter by a single metadata field using implicit equality:

**Before (AutoRAG API):**

```

{

  "filters": {

    "type": "eq",

    "key": "folder",

    "value": "customer-a/"

  }

}


```

**After (AI Search API):**

```

{

  "ai_search_options": {

    "retrieval": {

      "filters": { "folder": "customer-a/" }

    }

  }

}


```

#### Compound filter (AND)

Combine multiple conditions where all must match:

**Before (AutoRAG API):**

```

{

  "filters": {

    "type": "and",

    "filters": [

      { "type": "eq", "key": "folder", "value": "customer-a/" },

      { "type": "gte", "key": "timestamp", "value": "1735689600000" }

    ]

  }

}


```

**After (AI Search API):**

```

{

  "ai_search_options": {

    "retrieval": {

      "filters": {

        "folder": "customer-a/",

        "timestamp": { "$gte": 1735689600 }

      }

    }

  }

}


```

## API references

* [REST API documentation](https://developers.cloudflare.com/ai-search/api/search/rest-api/)
* [Chat Completions API reference](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/instances/methods/chat%5Fcompletions/)
* [Search API reference](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/instances/methods/search/)
* [Legacy AutoRAG API reference](https://developers.cloudflare.com/api/resources/autorag/)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/api/","name":"API"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/api/migration/","name":"API Migration"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/api/migration/rest-api/","name":"REST API migration"}}]}
```

---

---
title: Workers binding migration
description: Upgrade from the legacy env.AI.autorag() binding to the new AI Search Workers bindings.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Workers binding migration

The [env.AI.autorag() binding](https://developers.cloudflare.com/ai-search/api/migration/workers-binding-legacy/) is the legacy API for AI Search. It will continue to work, but all new features and improvements are only available through the new AI Search bindings.

## What changed

Here is a summary of the key differences between the legacy and new bindings:

| Legacy              | New                    |                                                |
| ------------------- | ---------------------- | ---------------------------------------------- |
| **Wrangler config** | ai binding             | ai\_search or ai\_search\_namespaces binding   |
| **Access pattern**  | env.AI.autorag("name") | env.MY\_INSTANCE or env.AI\_SEARCH.get("name") |
| **Search format**   | query string           | messages array or query string                 |
| **Response format** | data array             | chunks array                                   |

## AI Search bindings

AI Search provides two new bindings:

**Instance binding (`ai_search`)** binds directly to a single instance. This is the simplest migration path from `env.AI.autorag()`.

JSONC

```

// wrangler.jsonc

{

  "ai_search": [

    {

      "binding": "MY_SEARCH",

      "instance_name": "my-instance",

    },

  ],

}


```

**Namespace binding (`ai_search_namespaces`)** gives you access to all instances within a namespace. Use this if you need dynamic instance management, cross-instance search, or the Items API.

JSONC

```

// wrangler.jsonc

{

  "ai_search_namespaces": [

    {

      "binding": "AI_SEARCH",

      "namespace": "default",

    },

  ],

}


```

For more details on the difference, refer to [Namespaces](https://developers.cloudflare.com/ai-search/concepts/namespaces/).

## Requirements

The new bindings require the following minimum package versions for TypeScript types and local development support.

| Package                   | Minimum version |
| ------------------------- | --------------- |
| @cloudflare/workers-types | 4.20260304.0    |
| wrangler                  | 4.68.1          |

## Step 1: Update Wrangler configuration

Existing instances are in the default namespace. For a simple upgrade path, use the instance binding. For the namespace binding, refer to [AI Search bindings](#ai-search-bindings).

**Before:**

* [  wrangler.jsonc ](#tab-panel-6460)
* [  wrangler.toml ](#tab-panel-6461)

JSONC

```

{

  "$schema": "./node_modules/wrangler/config-schema.json",

  "ai": {

    "binding": "AI"

  }

}


```

TOML

```

[ai]

binding = "AI"


```

**After:**

* [  wrangler.jsonc ](#tab-panel-6462)
* [  wrangler.toml ](#tab-panel-6463)

JSONC

```

{

  "$schema": "./node_modules/wrangler/config-schema.json",

  "compatibility_date": "2026-03-27",

  "ai_search": [

    {

      "binding": "MY_INSTANCE",

      "instance_name": "my-instance"

    }

  ]

}


```

TOML

```

compatibility_date = "2026-03-27"


[[ai_search]]

binding = "MY_INSTANCE"

instance_name = "my-instance"


```

## Step 2: Update the type definition

Update the `Env` interface to use the new binding type.

**Before:**

TypeScript

```

export interface Env {

  AI: Ai;

}


```

**After:**

TypeScript

```

export interface Env {

  MY_INSTANCE: AiSearchInstance;

}


```

## Step 3: Update search calls

Replace `env.AI.autorag()` calls with the new binding.

**Before:**

TypeScript

```

const result = await env.AI.autorag("my-instance").search({

  query: "What is Cloudflare?",

});


```

**After:**

TypeScript

```

const result = await env.MY_INSTANCE.search({

  messages: [{ role: "user", content: "What is Cloudflare?" }],

});


```

## Step 4: Update response handling

The response shape changed from a `data` array to a `chunks` array.

### Field mapping

| Old field                          | New field                 |
| ---------------------------------- | ------------------------- |
| data\[\]                           | chunks\[\]                |
| data\[\].file\_id                  | chunks\[\].id             |
| data\[\].filename                  | chunks\[\].item.key       |
| data\[\].score                     | chunks\[\].score          |
| data\[\].content\[\].text          | chunks\[\].text           |
| data\[\].attributes.modified\_date | chunks\[\].item.timestamp |

## Streaming behavior changes

In the legacy binding, streaming with `env.AI.autorag().aiSearch({ stream: true })` only returned the streamed response without the retrieved chunks.

The new binding sends the retrieved chunks first as a `chunks` event, followed by the streamed response. This allows you to display source chunks immediately while streaming the generated response.

## Filter format changes

The new binding uses Vectorize-style metadata filtering. Filters are now passed inside `ai_search_options.retrieval.filters`.

| Old format | New format        |
| ---------- | ----------------- |
| eq         | $eq (or implicit) |
| ne         | $ne               |
| gt         | $gt               |
| gte        | $gte              |
| lt         | $lt               |
| lte        | $lte              |
| $in (new)  |                   |
| $nin (new) |                   |

### Examples

#### Simple filter

Filter by a single metadata field using implicit equality:

**Before:**

TypeScript

```

const result = await env.AI.autorag("my-instance").search({

  query: "What is Cloudflare?",

  filters: {

    type: "eq",

    key: "folder",

    value: "customer-a/",

  },

});


```

**After:**

TypeScript

```

const result = await env.MY_INSTANCE.search({

  messages: [{ role: "user", content: "What is Cloudflare?" }],

  ai_search_options: {

    retrieval: {

      filters: { folder: "customer-a/" },

    },

  },

});


```

#### Compound filter (AND)

Combine multiple conditions where all must match:

**Before:**

TypeScript

```

const result = await env.AI.autorag("my-instance").search({

  query: "What is Cloudflare?",

  filters: {

    type: "and",

    filters: [

      { type: "eq", key: "folder", value: "customer-a/" },

      { type: "gte", key: "timestamp", value: "1735689600000" },

    ],

  },

});


```

**After:**

TypeScript

```

const result = await env.MY_INSTANCE.search({

  messages: [{ role: "user", content: "What is Cloudflare?" }],

  ai_search_options: {

    retrieval: {

      filters: {

        folder: "customer-a/",

        timestamp: { $gte: 1735689600 },

      },

    },

  },

});


```

## Backwards compatibility

The `env.AI.autorag()` binding will continue to work indefinitely. You do not need to migrate immediately.

For the legacy API reference, refer to [Workers binding (legacy)](https://developers.cloudflare.com/ai-search/api/migration/workers-binding-legacy/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/api/","name":"API"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/api/migration/","name":"API Migration"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/api/migration/workers-binding/","name":"Workers binding migration"}}]}
```

---

---
title: Workers binding (legacy)
description: Reference for the legacy env.AI.autorag() Workers binding used by earlier AI Search instances.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Workers binding (legacy)

The `env.AI.autorag()` binding is the legacy API for AI Search. It will continue to work, but new projects should use the new AI Search bindings instead. For a step-by-step upgrade guide, refer to [Workers binding migration](https://developers.cloudflare.com/ai-search/api/migration/workers-binding/).

### `aiSearch()`

This method searches for relevant results from your data source and generates a response using your default model and the retrieved context:

JavaScript

```

const answer = await env.AI.autorag("my-autorag").aiSearch({

  query: "How do I train a llama to deliver coffee?",

  model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast",

  rewrite_query: true,

  max_num_results: 2,

  ranking_options: {

    score_threshold: 0.3,

  },

  reranking: {

    enabled: true,

    model: "@cf/baai/bge-reranker-base",

  },

  stream: true,

});


```

#### Parameters

`query` ` string ` required

The input query.

---

`model` ` string ` optional

The text-generation model used to generate the response for the query. For a list of valid options, check the AI Search generation model settings. Defaults to the generation model selected in the AI Search settings.

---

`system_prompt` ` string ` optional

The system prompt for generating the answer.

---

`rewrite_query` ` boolean ` optional

Rewrites the original query into a search optimized query to improve retrieval accuracy. Defaults to `false`.

---

`max_num_results` ` number ` optional

The maximum number of results that can be returned from the Vectorize database. Defaults to `10`. Must be between `1` and `50`.

---

`ranking_options` ` object ` optional

Configurations for customizing result ranking. Defaults to `{}`.

* `score_threshold` ` number ` optional  
   * The minimum match score required for a result to be considered a match. Defaults to `0`. Must be between `0` and `1`.

`reranking` ` object ` optional

Configurations for customizing reranking. Defaults to `{}`.

* `enabled` ` boolean ` optional  
   * Enables or disables reranking, which reorders retrieved results based on semantic relevance using a reranking model. Defaults to `false`.
* `model` ` string ` optional  
   * The reranking model to use when reranking is enabled.

`stream` ` boolean ` optional

Returns a stream of results as they are available. Defaults to `false`.

`filters` ` object ` optional

Narrow down search results based on metadata, like folder and date, so only relevant content is retrieved. For more details, refer to [Metadata filtering](https://developers.cloudflare.com/ai-search/configuration/indexing/metadata/).

#### Response

This is the response structure without `stream` enabled.

```

{

  "object": "vector_store.search_results.page",

  "search_query": "How do I train a llama to deliver coffee?",

  "response": "To train a llama to deliver coffee:\n\n1. **Build trust** — Llamas appreciate patience (and decaf).\n2. **Know limits** — Max 3 cups per llama, per `llama-logistics.md`.\n3. **Use voice commands** — Start with \"Espresso Express!\"\n4.",

  "data": [

    {

      "file_id": "llama001",

      "filename": "llama/logistics/llama-logistics.md",

      "score": 0.45,

      "attributes": {

        "modified_date": 1735689600000,

        "folder": "llama/logistics/"

      },

      "content": [

        {

          "id": "llama001",

          "type": "text",

          "text": "Llamas can carry 3 drinks max."

        }

      ]

    },

    {

      "file_id": "llama042",

      "filename": "llama/llama-commands.md",

      "score": 0.4,

      "attributes": {

        "modified_date": 1735689600000,

        "folder": "llama/"

      },

      "content": [

        {

          "id": "llama042",

          "type": "text",

          "text": "Start with basic commands like 'Espresso Express!' Llamas love alliteration."

        }

      ]

    }

  ],

  "has_more": false,

  "next_page": null

}


```

### `search()`

This method searches for results from your corpus and returns the relevant results:

JavaScript

```

const answer = await env.AI.autorag("my-autorag").search({

  query: "How do I train a llama to deliver coffee?",

  rewrite_query: true,

  max_num_results: 2,

  ranking_options: {

    score_threshold: 0.3,

  },

  reranking: {

    enabled: true,

    model: "@cf/baai/bge-reranker-base",

  },

});


```

#### Parameters

`messages` ` array ` required

An array of message objects. Each message has:

* `content` ` string ` \- The search query content.
* `role` ` string ` \- The role: `user`, `system`, or `assistant`.

---

`ai_search_options` ` object ` optional

Per-request overrides for retrieval and model behavior. Supports the following nested options:

* `retrieval.filters` ` object ` \- Narrow down search results based on metadata. Refer to [Metadata filtering](https://developers.cloudflare.com/ai-search/configuration/indexing/metadata/) for syntax and examples.
* `retrieval.max_num_results` ` number ` \- Maximum number of chunks to return. Defaults to `10`, maximum `50`.
* `retrieval.retrieval_type` ` string ` \- One of `vector`, `keyword`, or `hybrid`.
* `retrieval.match_threshold` ` number ` \- Minimum similarity score (0-1). Defaults to `0.4`.
* `cache.enabled` ` boolean ` \- Override the instance-level cache setting for this request.
* `reranking.enabled` ` boolean ` \- Override the instance-level reranking setting for this request.

---

For the full list of optional parameters, refer to the [Search API reference](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/instances/methods/search/).

#### Response

```

{

  "object": "vector_store.search_results.page",

  "search_query": "How do I train a llama to deliver coffee?",

  "data": [

    {

      "file_id": "llama001",

      "filename": "llama/logistics/llama-logistics.md",

      "score": 0.45,

      "attributes": {

        "modified_date": 1735689600000,

        "folder": "llama/logistics/"

      },

      "content": [

        {

          "id": "llama001",

          "type": "text",

          "text": "Llamas can carry 3 drinks max."

        }

      ]

    },

    {

      "file_id": "llama042",

      "filename": "llama/llama-commands.md",

      "score": 0.4,

      "attributes": {

        "modified_date": 1735689600000,

        "folder": "llama/"

      },

      "content": [

        {

          "id": "llama042",

          "type": "text",

          "text": "Start with basic commands like 'Espresso Express!' Llamas love alliteration."

        }

      ]

    }

  ],

  "has_more": false,

  "next_page": null

}


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/api/","name":"API"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/api/migration/","name":"API Migration"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/api/migration/workers-binding-legacy/","name":"Workers binding (legacy)"}}]}
```

---

---
title: MCP
description: Expose AI Search content to AI agents through the Model Context Protocol (MCP) endpoint.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# MCP

The Model Context Protocol (MCP) endpoint allows AI agents to discover and interact with your AI Search content. This endpoint follows the [MCP specification ↗](https://modelcontextprotocol.io/) and provides tools for querying your indexed content.

## Prerequisites

Enable public endpoints for your AI Search instance:

1. Go to **AI Search** in the Cloudflare dashboard.[ Go to **AI Search** ](https://dash.cloudflare.com/?to=/:account/ai/ai-search)
2. Select your AI Search instance.
3. Go to **Settings** \> **Public Endpoint**.
4. Turn on **Enable Public Endpoint**.
5. Copy the public endpoint URL.

## Available tools

The AI Search MCP endpoint exposes a `search` tool that queries your indexed content.

| Tool   | Description                           |
| ------ | ------------------------------------- |
| search | Finds exactly what you're looking for |

You can customize this in your AI Search instance settings. For more details, refer to [Public endpoint configuration](https://developers.cloudflare.com/ai-search/configuration/retrieval/public-endpoint/).

## Test the MCP endpoint

Send a request to the `/mcp` endpoint with the `Accept: application/json, text/event-stream` header:

Terminal window

```

curl https://<INSTANCE_ID>.search.ai.cloudflare.com/mcp \

  -H "Content-Type: application/json" \

  -H "Accept: application/json, text/event-stream" \

  -d '{

    "jsonrpc": "2.0",

    "id": 1,

    "method": "tools/call",

    "params": {

      "name": "search",

      "arguments": {

        "query": "How do I configure AI Search?"

      }

    }

  }'


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/api/","name":"API"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/api/search/","name":"Search"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/api/search/mcp/","name":"MCP"}}]}
```

---

---
title: Public endpoint
description: Integrate AI Search into public-facing applications using unauthenticated public endpoints.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Public endpoint

AI Search public endpoints allow you to expose AI Search capabilities without requiring authentication. This enables you to integrate AI Search into public-facing applications or share it with external users.

For pre-built search and chat components you can embed on your website using the public endpoints, refer to [UI snippets](https://developers.cloudflare.com/ai-search/configuration/retrieval/embed-search-snippets/).

## Prerequisites

Enable public endpoints for your AI Search instance:

1. Go to **AI Search** in the Cloudflare dashboard.[ Go to **AI Search** ](https://dash.cloudflare.com/?to=/:account/ai/ai-search)
2. Select your AI Search instance.
3. Go to **Settings** \> **Public Endpoint**.
4. Turn on **Enable Public Endpoint**.
5. Copy the public endpoint URL.

For configuration options like rate limiting and CORS, refer to [Public endpoint configuration](https://developers.cloudflare.com/ai-search/configuration/retrieval/public-endpoint/).

## Chat completions

The `/chat/completions` endpoint searches your data source and generates a response using the model and retrieved context. It uses the same OpenAI-compatible format as the [REST API](https://developers.cloudflare.com/ai-search/api/search/rest-api/#chat-completions).

Terminal window

```

curl https://<INSTANCE_ID>.search.ai.cloudflare.com/chat/completions \

  -H "Content-Type: application/json" \

  -d '{

    "messages": [

      {

        "content": "How do I configure AI Search?",

        "role": "user"

      }

    ]

  }'


```

For the full list of options, refer to the [Chat Completions API reference](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/instances/methods/chat%5Fcompletions/).

## Search

The `/search` endpoint returns relevant chunks from your data source without generating a response. It uses the same format as the [REST API](https://developers.cloudflare.com/ai-search/api/search/rest-api/#search).

Terminal window

```

curl https://<INSTANCE_ID>.search.ai.cloudflare.com/search \

  -H "Content-Type: application/json" \

  -d '{

    "messages": [

      {

        "content": "How do I configure AI Search?",

        "role": "user"

      }

    ]

  }'


```

For the full list of options, refer to the [Search API reference](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/instances/methods/search/).

## Next steps

* [UI snippets](https://developers.cloudflare.com/ai-search/configuration/retrieval/embed-search-snippets/) \- Add pre-built search and chat components to your website.
* [MCP](https://developers.cloudflare.com/ai-search/api/search/mcp/) \- Connect AI agents using the Model Context Protocol.
* [Public endpoint configuration](https://developers.cloudflare.com/ai-search/configuration/retrieval/public-endpoint/) \- Configure rate limiting, CORS, and security settings.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/api/","name":"API"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/api/search/","name":"Search"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/api/search/public-endpoint/","name":"Public endpoint"}}]}
```

---

---
title: REST API
description: Query AI Search instances over HTTP using the REST API for search and chat completions.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# REST API

Use the AI Search REST API to query your AI Search instances over HTTP.

Note

The previous [AutoRAG API endpoints](https://developers.cloudflare.com/api/resources/autorag/) are no longer recommended for use. Refer to [Migrate from AutoRAG REST API](https://developers.cloudflare.com/ai-search/api/migration/rest-api/) for details.

## Authentication

All requests require an API token with **AI Search:Edit** and **AI Search:Run** permissions.

1. In the Cloudflare dashboard, go to **My Profile** \> **API Tokens**.  
[ Go to **API Tokens** ](https://dash.cloudflare.com/profile/api-tokens)
2. Select **Create Token**.
3. Select **Create Custom Token**.
4. Enter a **Token name**, for example `AI Search Manager`.
5. Under **Permissions**, add two permissions:  
   * **Account** \> **AI Search:Edit**  
   * **Account** \> **AI Search:Run**
6. Select **Continue to summary**, then select **Create Token**.
7. Copy and save the token value. This is your `API_TOKEN`.

Include the token in the `Authorization` header for all requests:

```

Authorization: Bearer <API_TOKEN>


```

## Search and chat

AI Search provides two APIs for querying an instance. Both use an OpenAI-compatible `messages` format.

* **Search** returns relevant content chunks. Use this when you want to handle generation yourself or display results directly.
* **Chat completions** retrieves content and generates a response in one call.

### API paths

AI Search APIs are available at two base paths:

| Path                                                                     | Description                                                                                                  |
| ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
| /accounts/{account\_id}/ai-search/instances/{id}/                        | Operates on a specific instance                                                                              |
| /accounts/{account\_id}/ai-search/namespaces/{namespace}/instances/{id}/ | Operates on instances within a [namespace](https://developers.cloudflare.com/ai-search/concepts/namespaces/) |

The following operations are the same for both paths. For the namespace-scoped API, refer to the [Namespace API reference](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/namespaces/).

### Search

Search a specific instance. The search endpoint also accepts a `query` string parameter. For the full specification, refer to the [Search API reference](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/instances/methods/search/).

Terminal window

```

curl -X POST "https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai-search/instances/<INSTANCE_NAME>/search" \

  -H "Authorization: Bearer <API_TOKEN>" \

  -H "Content-Type: application/json" \

  -d '{

    "messages": [

      {

        "content": "What is Cloudflare?",

        "role": "user"

      }

    ]

  }'


```

### Chat completions

Generate a response from a specific instance. For the full specification, refer to the [Chat completions API reference](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/instances/methods/chat%5Fcompletions/).

Terminal window

```

curl -X POST "https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai-search/instances/<INSTANCE_NAME>/chat/completions" \

  -H "Authorization: Bearer <API_TOKEN>" \

  -H "Content-Type: application/json" \

  -d '{

    "messages": [

      {

        "content": "What is Cloudflare?",

        "role": "user"

      }

    ]

  }'


```

#### Streaming

Set `stream` to `true` to receive responses as Server-Sent Events (SSE). The retrieved chunks are sent first as a `chunks` event, followed by the streamed response.

```

event: chunks

data: [{"id":"chunk-001","type":"text","score":0.85,"text":"...","item":{"key":"about-cloudflare.md","timestamp":1775925540000},"scoring_details":{"vector_score":0.85}}]


data: {"id":"id-1776072781845","created":1776072781,"model":"@cf/meta/llama-3.3-70b-instruct-fp8-fast","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":" document"}}]}


data: {"id":"id-1776072781845","created":1776072781,"model":"@cf/meta/llama-3.3-70b-instruct-fp8-fast","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":" you provided doesn"}}]}


data: {"id":"id-1776072781845","created":1776072781,"model":"@cf/meta/llama-3.3-70b-instruct-fp8-fast","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"'t contain"}}]}


data: {"id":"id-1776072781845","created":1776072781,"model":"@cf/meta/llama-3.3-70b-instruct-fp8-fast","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":" information"}}]}


data: [DONE]


```

## Cross-instance search and chat

The search and chat completions APIs are also available at the namespace level. These work the same as the instance endpoints, but you pass an `instance_ids` array to specify which instances to query. Each chunk in the response includes an `instance_id` field identifying which instance it came from. For the full specification, refer to the [Namespace API reference](https://developers.cloudflare.com/api/resources/ai%5Fsearch/subresources/namespaces/).

Terminal window

```

curl -X POST "https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai-search/namespaces/<NAMESPACE>/search" \

  -H "Authorization: Bearer <API_TOKEN>" \

  -H "Content-Type: application/json" \

  -d '{

    "messages": [

      {

        "role": "user",

        "content": "What is Cloudflare?"

      }

    ],

    "ai_search_options": {

      "instance_ids": ["product-docs", "customer-abc123"]

    }

  }'


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/api/","name":"API"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/api/search/","name":"Search"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/api/search/rest-api/","name":"REST API"}}]}
```

---

---
title: Workers binding
description: Search and chat with AI Search instances from a Cloudflare Worker using the Workers binding.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Workers binding

[Workers](https://developers.cloudflare.com/workers/) provides a serverless execution environment that allows you to create new applications or augment existing ones. Use a [Workers binding](https://developers.cloudflare.com/workers/runtime-apis/bindings/) to search and chat with your AI Search instances from a Cloudflare Worker.

Note

The previous `env.AI.autorag()` binding is no longer recommended for use. Refer to [Workers binding migration](https://developers.cloudflare.com/ai-search/api/migration/workers-binding/) for details.

## Configure the binding

To use AI Search with Workers, you must create an AI Search binding. You create bindings by updating your [Wrangler configuration](https://developers.cloudflare.com/workers/wrangler/configuration/). AI Search provides two types of bindings:

* Namespace binding: `ai_search_namespaces`
* Instance binding: `ai_search`

### Namespace binding

Access all instances within a [namespace](https://developers.cloudflare.com/ai-search/concepts/namespaces/). You can get, create, list, and delete instances at runtime.

* [  wrangler.jsonc ](#tab-panel-6464)
* [  wrangler.toml ](#tab-panel-6465)

JSONC

```

{

  "$schema": "./node_modules/wrangler/config-schema.json",

  "compatibility_date": "2026-03-27",

  "ai_search_namespaces": [

    {

      "binding": "AI_SEARCH",

      "namespace": "my-namespace"

    }

  ]

}


```

TOML

```

compatibility_date = "2026-03-27"


[[ai_search_namespaces]]

binding = "AI_SEARCH"

namespace = "my-namespace"


```

| Field     | Type    | Required | Description                                                                                                                                                                                                                   |
| --------- | ------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| binding   | string  | Yes      | The variable name available on env. For example, "AI\_SEARCH" makes it accessible as env.AI\_SEARCH.                                                                                                                          |
| namespace | string  | Yes      | The [namespace](https://developers.cloudflare.com/ai-search/concepts/namespaces/) to bind to. A default namespace is created automatically for every account. If the namespace does not exist, Wrangler creates it on deploy. |
| remote    | boolean | No       | Set to true for local development with wrangler dev.                                                                                                                                                                          |

### Instance binding

Bind directly to a single instance in the `default` namespace. Use this when you know which instance you need at deploy time.

* [  wrangler.jsonc ](#tab-panel-6466)
* [  wrangler.toml ](#tab-panel-6467)

JSONC

```

{

  "$schema": "./node_modules/wrangler/config-schema.json",

  "compatibility_date": "2026-03-27",

  "ai_search": [

    {

      "binding": "MY_SEARCH",

      "instance_name": "my-instance"

    }

  ]

}


```

TOML

```

compatibility_date = "2026-03-27"


[[ai_search]]

binding = "MY_SEARCH"

instance_name = "my-instance"


```

| Field          | Type    | Required | Description                                                                                          |
| -------------- | ------- | -------- | ---------------------------------------------------------------------------------------------------- |
| binding        | string  | Yes      | The variable name available on env. For example, "MY\_SEARCH" makes it accessible as env.MY\_SEARCH. |
| instance\_name | string  | Yes      | The name of the AI Search instance. Must exist in the default namespace at deploy time.              |
| remote         | boolean | No       | Set to true for local development with wrangler dev.                                                 |

## Instance methods

The following methods are available on both the `ai_search_namespaces` and `ai_search` bindings. With the namespace binding, call methods on the handle returned by `get()`. With the instance binding, call methods directly on the binding (for example, `env.MY_SEARCH.search()`).

The examples below use the namespace binding.

### `search()`

Search for relevant content chunks from your indexed data source. Returns scored chunks with source references.

TypeScript

```

const instance = env.AI_SEARCH.get("my-instance");


const results = await instance.search({

  messages: [{ role: "user", content: "What is Cloudflare?" }],

});


```

#### Parameters

`messages` ` array ` required

An array of message objects representing the conversation. Each message has a `role` and `content` field.

* `role` ` string ` required  
   * The role of the message sender. Valid values: `system`, `developer`, `user`, `assistant`, `tool`.
* `content` ` string ` required  
   * The content of the message.

---

`query` ` string ` optional

A simple text query string. Alternative to `messages`. Provide either `query` or `messages`, not both.

---

`ai_search_options` ` object ` optional

Configuration options for the search operation.

* `retrieval` ` object ` optional  
   * `retrieval_type` ` string ` optional  
         * The type of retrieval to perform. Valid values: `vector`, `keyword`, `hybrid`. Defaults to `hybrid`.  
   * `match_threshold` ` number ` optional  
         * The minimum match score required for a result to be considered a match. Must be between `0` and `1`. Defaults to `0.4`.  
   * `max_num_results` ` integer ` optional  
         * The maximum number of results to return. Must be between `1` and `50`. Defaults to `10`.  
   * `filters` ` object ` optional  
         * Filter search results based on metadata. Supports comparison filters (`eq`, `ne`, `gt`, `gte`, `lt`, `lte`) and compound filters (`and`, `or`). For more details, refer to [Metadata filtering](https://developers.cloudflare.com/ai-search/configuration/indexing/metadata/).  
   * `context_expansion` ` integer ` optional  
         * The number of surrounding chunks to include for additional context. Must be between `0` and `3`. Defaults to `0`.  
   * `fusion_method` ` string ` optional  
         * Controls how vector and keyword scores are combined when using hybrid retrieval. Valid values: `rrf` (Reciprocal Rank Fusion), `max` (takes the maximum score). Defaults to the instance-level setting.  
   * `keyword_match_mode` ` string ` optional  
         * Controls how keyword (BM25) matching selects candidate documents. `and` requires all terms to match. `or` requires any term to match. Defaults to `and`.  
   * `boost_by` ` array ` optional  
         * Boost results by metadata fields. Maximum 3 items. Each item has:  
                  * `field` ` string ` required \- The metadata field name to boost by (for example, `timestamp`). Maximum 64 characters.  
                  * `direction` ` string ` optional \- The boost direction. Valid values: `asc`, `desc`, `exists`, `not_exists`. Defaults to `asc` for numeric fields and `exists` for text fields.  
   * `metadata_only` ` boolean ` optional  
         * Return only metadata for each chunk without the text content.  
   * `return_on_failure` ` boolean ` optional  
         * Whether to return partial results if some processing steps fail. Defaults to `true`.
* `query_rewrite` ` object ` optional  
   * `enabled` ` boolean ` optional  
         * Rewrites the query to improve retrieval accuracy. Defaults to `false`.  
   * `model` ` string ` optional  
         * The model to use for query rewriting.  
   * `rewrite_prompt` ` string ` optional  
         * A custom prompt to guide query rewriting.
* `reranking` ` object ` optional  
   * `enabled` ` boolean ` optional  
         * Reorders retrieved results based on semantic relevance using a reranking model. Defaults to `false`.  
   * `model` ` string ` optional  
         * The reranking model to use. Valid value: `@cf/baai/bge-reranker-base`.  
   * `match_threshold` ` number ` optional  
         * The minimum score for reranked results. Must be between `0` and `1`. Defaults to `0.4`.
* `cache` ` object ` optional  
   * `enabled` ` boolean ` optional  
         * Override the instance-level cache setting for this request.  
   * `cache_threshold` ` string ` optional  
         * The similarity threshold for cache hits. Valid values: `super_strict_match`, `close_enough`, `flexible_friend`, `anything_goes`.

#### Response

The response contains the following fields:

| Field                                        | Type   | Description                                                                          |
| -------------------------------------------- | ------ | ------------------------------------------------------------------------------------ |
| search\_query                                | string | The query used for the search, which may be rewritten if query rewriting is enabled. |
| chunks                                       | array  | An array of matching content chunks.                                                 |
| chunks\[\].id                                | string | The unique identifier for the chunk.                                                 |
| chunks\[\].type                              | string | The type of content, typically text.                                                 |
| chunks\[\].score                             | number | The overall match score between 0 and 1.                                             |
| chunks\[\].text                              | string | The text content of the chunk.                                                       |
| chunks\[\].item                              | object | Information about the source item.                                                   |
| chunks\[\].item.key                          | string | The file path or URL of the source document.                                         |
| chunks\[\].item.timestamp                    | number | Unix timestamp of when the item was last modified.                                   |
| chunks\[\].item.metadata                     | object | Custom metadata associated with the source item.                                     |
| chunks\[\].scoring\_details                  | object | Breakdown of how the chunk was scored.                                               |
| chunks\[\].scoring\_details.vector\_score    | number | The semantic similarity score (0 to 1).                                              |
| chunks\[\].scoring\_details.keyword\_score   | number | The keyword (BM25) match score. Present when using hybrid or keyword retrieval.      |
| chunks\[\].scoring\_details.keyword\_rank    | number | The keyword rank position.                                                           |
| chunks\[\].scoring\_details.vector\_rank     | number | The vector rank position.                                                            |
| chunks\[\].scoring\_details.reranking\_score | number | The reranking score (0 to 1). Present when reranking is enabled.                     |
| chunks\[\].scoring\_details.fusion\_method   | string | The fusion method used (rrf or max). Present when using hybrid retrieval.            |

### `chatCompletions()`

Generate chat completions using your AI Search instance as context. This method retrieves relevant content and uses it to generate a response.

TypeScript

```

const instance = env.AI_SEARCH.get("my-instance");


const response = await instance.chatCompletions({

  messages: [

    { role: "system", content: "You are a helpful documentation assistant." },

    { role: "user", content: "What is Cloudflare?" },

  ],

  model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast",

  ai_search_options: {

    retrieval: {

      max_num_results: 5,

    },

    query_rewrite: {

      enabled: true,

    },

  },

});


```

#### Stream responses

Set `stream: true` to receive responses as Server-Sent Events (SSE) as they are generated:

TypeScript

```

const instance = env.AI_SEARCH.get("my-instance");


const stream = await instance.chatCompletions({

  messages: [{ role: "user", content: "What is Cloudflare?" }],

  stream: true,

});


return new Response(stream, {

  headers: {

    "content-type": "text/event-stream",

    "cache-control": "no-cache",

  },

});


```

When `stream` is enabled, the method returns a `ReadableStream` of SSE events. Each event contains a JSON object with `choices[0].delta.content` for incremental text. The stream ends with a `data: [DONE]` event.

#### Parameters

`messages` ` array ` required

An array of message objects representing the conversation. Each message has a `role` and `content` field.

* `role` ` string ` required  
   * The role of the message sender. Valid values: `system`, `developer`, `user`, `assistant`, `tool`.
* `content` ` string ` required  
   * The content of the message.

---

`model` ` string ` optional

The text-generation model used to generate responses. Defaults to the generation model configured in the AI Search instance settings. For a list of supported models, refer to [Supported models](https://developers.cloudflare.com/ai-search/configuration/models/supported-models/).

---

`stream` ` boolean ` optional

Returns a stream of results as they are generated. When enabled, returns a `Response` object with a readable stream. Defaults to `false`.

---

`ai_search_options` ` object ` optional

Configuration options for the search and generation operation.

* `retrieval` ` object ` optional  
   * `retrieval_type` ` string ` optional  
         * The type of retrieval to perform. Valid values: `vector`, `keyword`, `hybrid`. Defaults to `hybrid`.  
   * `match_threshold` ` number ` optional  
         * The minimum match score required for a result to be considered a match. Must be between `0` and `1`. Defaults to `0.4`.  
   * `max_num_results` ` integer ` optional  
         * The maximum number of results to return. Must be between `1` and `50`. Defaults to `10`.  
   * `filters` ` object ` optional  
         * Filter search results based on metadata. Supports comparison filters (`eq`, `ne`, `gt`, `gte`, `lt`, `lte`) and compound filters (`and`, `or`). For more details, refer to [Metadata filtering](https://developers.cloudflare.com/ai-search/configuration/indexing/metadata/).  
   * `context_expansion` ` integer ` optional  
         * The number of surrounding chunks to include for additional context. Must be between `0` and `3`. Defaults to `0`.  
   * `fusion_method` ` string ` optional  
         * Controls how vector and keyword scores are combined when using hybrid retrieval. Valid values: `rrf` (Reciprocal Rank Fusion), `max` (takes the maximum score). Defaults to the instance-level setting.  
   * `keyword_match_mode` ` string ` optional  
         * Controls how keyword (BM25) matching selects candidate documents. `and` requires all terms to match. `or` requires any term to match. Defaults to `and`.  
   * `boost_by` ` array ` optional  
         * Boost results by metadata fields. Maximum 3 items. Each item has:  
                  * `field` ` string ` required \- The metadata field name to boost by (for example, `timestamp`). Maximum 64 characters.  
                  * `direction` ` string ` optional \- The boost direction. Valid values: `asc`, `desc`, `exists`, `not_exists`. Defaults to `asc` for numeric fields and `exists` for text fields.  
   * `metadata_only` ` boolean ` optional  
         * Return only metadata for each chunk without the text content.  
   * `return_on_failure` ` boolean ` optional  
         * Whether to return partial results if some processing steps fail. Defaults to `true`.
* `query_rewrite` ` object ` optional  
   * `enabled` ` boolean ` optional  
         * Rewrites the query to improve retrieval accuracy. Defaults to `false`.  
   * `model` ` string ` optional  
         * The model to use for query rewriting.  
   * `rewrite_prompt` ` string ` optional  
         * A custom prompt to guide query rewriting.
* `reranking` ` object ` optional  
   * `enabled` ` boolean ` optional  
         * Reorders retrieved results based on semantic relevance using a reranking model. Defaults to `false`.  
   * `model` ` string ` optional  
         * The reranking model to use. Valid value: `@cf/baai/bge-reranker-base`.  
   * `match_threshold` ` number ` optional  
         * The minimum score for reranked results. Must be between `0` and `1`. Defaults to `0.4`.
* `cache` ` object ` optional  
   * `enabled` ` boolean ` optional  
         * Override the instance-level cache setting for this request.  
   * `cache_threshold` ` string ` optional  
         * The similarity threshold for cache hits. Valid values: `super_strict_match`, `close_enough`, `flexible_friend`, `anything_goes`.

#### Response (non-streaming)

| Field                       | Type   | Description                                                                         |
| --------------------------- | ------ | ----------------------------------------------------------------------------------- |
| id                          | string | Unique identifier for the completion.                                               |
| object                      | string | Always chat.completion.                                                             |
| created                     | number | Unix timestamp of when the completion was created.                                  |
| model                       | string | The model used to generate the response.                                            |
| choices                     | array  | Array of completion choices.                                                        |
| choices\[\].message.role    | string | Always assistant.                                                                   |
| choices\[\].message.content | string | The generated response text.                                                        |
| choices\[\].finish\_reason  | string | Why the model stopped generating. Typically stop.                                   |
| usage.prompt\_tokens        | number | Number of tokens in the prompt.                                                     |
| usage.completion\_tokens    | number | Number of tokens in the generated response.                                         |
| usage.total\_tokens         | number | Total tokens used.                                                                  |
| chunks                      | array  | The source chunks used as context. Same format as the [search response](#response). |

#### Response (streaming)

When `stream: true`, the method returns a `ReadableStream` of Server-Sent Events. The retrieved chunks are sent first as a `chunks` event, followed by the streamed response.

```

event: chunks

data: [{"id":"chunk-001","type":"text","score":0.85,"text":"...","item":{"key":"about-cloudflare.md","timestamp":1775925540000},"scoring_details":{"vector_score":0.85}}]


data: {"id":"id-1776072781845","created":1776072781,"model":"@cf/meta/llama-3.3-70b-instruct-fp8-fast","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":" document"}}]}


data: {"id":"id-1776072781845","created":1776072781,"model":"@cf/meta/llama-3.3-70b-instruct-fp8-fast","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":" you provided doesn"}}]}


data: {"id":"id-1776072781845","created":1776072781,"model":"@cf/meta/llama-3.3-70b-instruct-fp8-fast","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"'t contain"}}]}


data: {"id":"id-1776072781845","created":1776072781,"model":"@cf/meta/llama-3.3-70b-instruct-fp8-fast","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":" information"}}]}


data: [DONE]


```

## Namespace methods

The following methods are only available when using the `ai_search_namespaces` binding. Search and chat across multiple instances in a single call using the namespace handle directly (`env.AI_SEARCH`).

### `search()`

Pass `instance_ids` in `ai_search_options` to specify which instances to query. Results are merged and ranked, and each chunk includes an `instance_id` field identifying which instance it came from.

TypeScript

```

const results = await env.AI_SEARCH.search({

  messages: [{ role: "user", content: "What is Cloudflare?" }],

  ai_search_options: {

    instance_ids: ["product-docs", "customer-abc123"],

  },

});


```

#### Parameters

Same as [instance-level search](#parameters), with one additional required field:

| Parameter                         | Type   | Required | Description                                           |
| --------------------------------- | ------ | -------- | ----------------------------------------------------- |
| ai\_search\_options               | object | Yes      | Required for namespace-level search.                  |
| ai\_search\_options.instance\_ids | array  | Yes      | Instance IDs to search across. Minimum 1, maximum 10. |

#### Response

Same as [instance-level search](#response), with additional fields:

| Field                   | Type   | Description                                                                            |
| ----------------------- | ------ | -------------------------------------------------------------------------------------- |
| chunks\[\].instance\_id | string | The instance this chunk came from.                                                     |
| errors                  | array  | Per-instance errors if any instances failed. Each object has instance\_id and message. |

### `chatCompletions()`

Generate chat completions using context retrieved from multiple instances.

TypeScript

```

const response = await env.AI_SEARCH.chatCompletions({

  messages: [{ role: "user", content: "What is Cloudflare?" }],

  ai_search_options: {

    instance_ids: ["product-docs", "customer-abc123"],

  },

});


```

Streaming is supported with `stream: true`.

#### Parameters

Same as [instance-level chat completions](#parameters-1), with one additional required field:

| Parameter                         | Type   | Required | Description                                           |
| --------------------------------- | ------ | -------- | ----------------------------------------------------- |
| ai\_search\_options               | object | Yes      | Required for namespace-level chat completions.        |
| ai\_search\_options.instance\_ids | array  | Yes      | Instance IDs to search across. Minimum 1, maximum 10. |

#### Response

Same as [instance-level chat completions](#response-non-streaming), with additional fields on each chunk:

| Field                   | Type   | Description                                                                            |
| ----------------------- | ------ | -------------------------------------------------------------------------------------- |
| chunks\[\].instance\_id | string | The instance this chunk came from.                                                     |
| errors                  | array  | Per-instance errors if any instances failed. Each object has instance\_id and message. |

## Local development

Local development is supported by proxying requests to your deployed AI Search instance. Add `remote: true` to your binding configuration to enable local development with `wrangler dev`.

JSONC

```

// wrangler.jsonc

{

  "ai_search": [

    {

      "binding": "MY_SEARCH",

      "instance_name": "my-instance",

      "remote": true,

    },

  ],

}


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/api/","name":"API"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/api/search/","name":"Search"}},{"@type":"ListItem","position":5,"item":{"@id":"/ai-search/api/search/workers-binding/","name":"Workers binding"}}]}
```

---

---
title: How AI Search works
description: Understand how AI Search indexes your content and retrieves results using vector and keyword search.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# How AI Search works

AI Search is a managed search service. Connect a website, an R2 bucket, or upload your own documents, and AI Search indexes your content for natural language queries.

AI Search consists of two core processes:

* **Indexing:** An asynchronous process that converts your content into vectors and keyword indexes for search. Indexing runs automatically when you connect a data source or upload files.
* **Querying:** A synchronous process triggered by user queries. It retrieves the most relevant content using vector search, keyword search, or both, and optionally generates a response.

## How indexing works

Indexing begins automatically when you connect a data source or upload files through the [Items API](https://developers.cloudflare.com/ai-search/api/items/workers-binding/).

![Indexing](https://developers.cloudflare.com/_astro/indexing.CQ13F9Js_2Tvxs.webp) 

Here is what happens during indexing:

1. **Data ingestion:** AI Search reads from your connected data source or receives files uploaded through the [Items API](https://developers.cloudflare.com/ai-search/api/items/workers-binding/).
2. **Markdown conversion:** AI Search uses [Workers AI's Markdown Conversion](https://developers.cloudflare.com/workers-ai/features/markdown-conversion/) to convert [supported data types](https://developers.cloudflare.com/ai-search/configuration/data-source/) into structured Markdown. This ensures consistency across diverse file types. For images, Workers AI is used to perform object detection followed by vision-to-language transformation to convert images into Markdown text.
3. **Chunking:** The extracted text is [chunked](https://developers.cloudflare.com/ai-search/configuration/indexing/chunking/) into smaller pieces to improve retrieval granularity.
4. **Embedding:** Each chunk is embedded using Workers AI's embedding model to transform the content into vectors.
5. **Keyword indexing:** When keyword search is enabled, each chunk is also indexed for BM25 keyword matching.
6. **Storage:** The vectors, keyword index, and content are stored and ready for search.

For instances with a connected data source, AI Search regularly checks for updates and indexes changes automatically. For instances using [built-in storage](https://developers.cloudflare.com/ai-search/configuration/data-source/built-in-storage/), new files are indexed as they are uploaded.

## How querying works

Once indexing is complete, AI Search is ready to respond to end-user queries in real time.

![Querying](https://developers.cloudflare.com/_astro/querying.c_RrR1YL_1ECh9s.webp) 

Here is how the querying pipeline works:

1. **Receive query from AI Search API:** The query workflow begins when you send a request to either the AI Search's [Chat Completions](https://developers.cloudflare.com/ai-search/api/search/rest-api/#chat-completions) or [Search](https://developers.cloudflare.com/ai-search/api/search/rest-api/#search) endpoints.
2. **Query rewriting (optional):** AI Search provides the option to [rewrite the input query](https://developers.cloudflare.com/ai-search/configuration/retrieval/query-rewriting/) using one of Workers AI's LLMs to improve retrieval quality by transforming the original query into a more effective search query.
3. **Embedding the query:** The rewritten (or original) query is transformed into a vector using the same embedding model used to embed your data.
4. **Vector search:** The query vector is matched against stored vectors to find semantically similar content.
5. **Keyword search (optional):** When hybrid search is enabled, a BM25 keyword search runs in parallel with vector search.
6. **Fusion (optional):** When using hybrid search, vector and keyword results are combined using the configured fusion method.
7. **Reranking (optional):** A cross-encoder model re-scores results by evaluating the query and document together. Refer to [Reranking](https://developers.cloudflare.com/ai-search/configuration/retrieval/reranking/) for details.
8. **Content retrieval:** The most relevant chunks and their source content are returned. If you are using the Search endpoint, the content is returned at this point.
9. **Response generation:** If you are using the Chat Completions endpoint, a text-generation model generates a response using the retrieved content. Refer to [System prompt](https://developers.cloudflare.com/ai-search/configuration/retrieval/system-prompt/) for details.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/concepts/","name":"Concepts"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/concepts/how-ai-search-works/","name":"How AI Search works"}}]}
```

---

---
title: Namespaces
description: Group AI Search instances into namespaces and manage them dynamically from a Workers binding.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Namespaces

Every AI Search instance belongs to a **namespace**. A namespace is a logical grouping of instances within your account.

## Requirements

The namespace binding requires the following minimum package versions for TypeScript types and local development support.

| Package                   | Minimum version |
| ------------------------- | --------------- |
| @cloudflare/workers-types | 4.20260304.0    |
| wrangler                  | 4.68.1          |

## How namespaces work

When you add an `ai_search_namespaces` binding to your Wrangler configuration, you specify which namespace the binding has access to. The binding grants full access to all instances within that namespace. You can get, list, create, and delete instances at runtime.

* [  wrangler.jsonc ](#tab-panel-6468)
* [  wrangler.toml ](#tab-panel-6469)

JSONC

```

{

  "$schema": "./node_modules/wrangler/config-schema.json",

  "ai_search_namespaces": [

    {

      "binding": "AI_SEARCH",

      "namespace": "my-namespace"

    }

  ]

}


```

TOML

```

[[ai_search_namespaces]]

binding = "AI_SEARCH"

namespace = "my-namespace"


```

At runtime, `env.AI_SEARCH` is the namespace handle. Use `env.AI_SEARCH.get("my-instance")` to get a handle to a specific instance:

TypeScript

```

const instance = env.AI_SEARCH.get("my-instance");

const results = await instance.search({

  messages: [{ role: "user", content: "How does caching work?" }],

});


```

The `get()` method is synchronous and does not make a network call. The instance is resolved lazily when you call a method like `search()` or `chatCompletions()`.

## Default namespace

A `default` namespace is automatically created for every account. If you do not need multiple namespaces, use `default` for all your instances.

You can also bind directly to specific instances in the default namespace using the `ai_search` binding. This binds each entry to a single pre-existing instance without needing to call `get()`.

* [  wrangler.jsonc ](#tab-panel-6470)
* [  wrangler.toml ](#tab-panel-6471)

JSONC

```

{

  "$schema": "./node_modules/wrangler/config-schema.json",

  "ai_search": [

    {

      "binding": "PROD_SEARCH",

      "instance_name": "production"

    },

    {

      "binding": "STAGING_SEARCH",

      "instance_name": "staging"

    }

  ]

}


```

TOML

```

[[ai_search]]

binding = "PROD_SEARCH"

instance_name = "production"


[[ai_search]]

binding = "STAGING_SEARCH"

instance_name = "staging"


```

The `ai_search` binding provides the same instance methods (`search()`, `chatCompletions()`, `info()`, `stats()`, `items`) but does not support namespace-level operations like `list()`, `create()`, or `delete()`.

## Multiple namespaces

You can declare multiple namespace bindings in the same Worker. Each binding maps to a different namespace and provides isolated access to its instances.

* [  wrangler.jsonc ](#tab-panel-6472)
* [  wrangler.toml ](#tab-panel-6473)

JSONC

```

{

  "$schema": "./node_modules/wrangler/config-schema.json",

  "ai_search_namespaces": [

    {

      "binding": "BLOG_SEARCH",

      "namespace": "blog"

    },

    {

      "binding": "SUPPORT_SEARCH",

      "namespace": "support"

    }

  ]

}


```

TOML

```

[[ai_search_namespaces]]

binding = "BLOG_SEARCH"

namespace = "blog"


[[ai_search_namespaces]]

binding = "SUPPORT_SEARCH"

namespace = "support"


```

### Common reasons to use multiple namespaces

* **Domain separation**: Separate instances by product area, for example `blog`, `support`, and `docs`.
* **Tenant isolation**: Assign each tenant their own namespace so that instance names do not collide across tenants.
* **Agent isolation**: Give each agent its own namespace for independent context management.

## Namespaces and instance uniqueness

An instance name must be unique within a namespace. This means you can have an instance named `docs` in both the `blog` and `support` namespaces without conflict.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/concepts/","name":"Concepts"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/concepts/namespaces/","name":"Namespaces"}}]}
```

---

---
title: Search modes
description: Compare AI Search vector, keyword, and hybrid search modes to choose the right retrieval strategy.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Search modes

AI Search supports three search modes: vector, keyword, and hybrid. By default, new instances use vector search only. You can enable keyword or hybrid search when creating or updating an instance.

## Vector search

Vector search converts your query into a vector embedding and finds chunks with similar meaning, even when the exact words differ. It knows that "deployment guide" and "how to ship my app" mean similar things. However, it can lose specifics. In a query like "ERR\_CONNECTION\_REFUSED timeout," vector search captures the broad concept of connection failures but might not surface the page that contains that exact error string.

## Keyword search

Keyword search matches chunks that contain your query terms exactly using BM25 full-text search. When you search "ERR\_CONNECTION\_REFUSED timeout," BM25 finds documents that actually contain "ERR\_CONNECTION\_REFUSED" as a term. However, it may miss a page about "troubleshooting network connections" that describes the same problem. Refer to [Keyword search](https://developers.cloudflare.com/ai-search/configuration/indexing/keyword-search/) for setup.

## Hybrid search

Hybrid search runs vector and keyword search in parallel and merges the results using a fusion method. Vector search understands intent, keyword search matches specific terms. Together, a query like "ERR\_CONNECTION\_REFUSED timeout" finds the exact error page and related troubleshooting content. Refer to [Hybrid search](https://developers.cloudflare.com/ai-search/configuration/indexing/hybrid-search/) for setup.

![Hybrid search](https://developers.cloudflare.com/_astro/hybrid-search.CJ9Cuw7h_13NTs.webp) 

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/concepts/","name":"Concepts"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/concepts/search-modes/","name":"Search modes"}}]}
```

---

---
title: Bring your own generation model
description: Use AI Search for retrieval while generating responses with an external model like OpenAI.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Bring your own generation model

When using AI Search, AI Search uses a Workers AI model to generate the response. If you want to use a model outside of Workers AI, you can use AI Search for `search` while using a different model to generate responses.

This example uses an OpenAI model to generate responses from AI Search results. It uses the [Workers binding](https://developers.cloudflare.com/ai-search/api/search/workers-binding/).

Note

AI Search supports [bringing your own models natively](https://developers.cloudflare.com/ai-search/configuration/models/). You can attach provider keys through AI Gateway and select third-party models directly in your AI Search settings. The example below still works, but the recommended approach is to configure your external model through AI Gateway.

* [  JavaScript ](#tab-panel-6479)
* [  TypeScript ](#tab-panel-6480)

JavaScript

```

import { openai } from "@ai-sdk/openai";

import { generateText } from "ai";


export default {

  async fetch(request, env) {

    const url = new URL(request.url);


    const userQuery = url.searchParams.get("query") ?? "What is Cloudflare?";


    // Search for documents in AI Search

    const searchResult = await env.AI_SEARCH.get("my-instance").search({

      messages: [{ role: "user", content: userQuery }],

    });


    if (searchResult.chunks.length === 0) {

      return Response.json({ text: `No data found for query "${userQuery}"` });

    }


    // Join all document chunks into a single string

    const chunks = searchResult.chunks

      .map((chunk) => {

        return `<file name="${chunk.item.key}">${chunk.text}</file>`;

      })

      .join("\n\n");


    // Send the user query + matched documents to OpenAI for answer

    const generateResult = await generateText({

      model: openai("gpt-4o-mini"),

      messages: [

        {

          role: "system",

          content:

            "You are a helpful assistant and your task is to answer the user question using the provided files.",

        },

        { role: "user", content: chunks },

        { role: "user", content: userQuery },

      ],

    });


    return Response.json({ text: generateResult.text });

  },

};


```

TypeScript

```

import { openai } from "@ai-sdk/openai";

import { generateText } from "ai";


export interface Env {

  AI_SEARCH: AiSearchNamespace;

  OPENAI_API_KEY: string;

}


export default {

  async fetch(request, env): Promise<Response> {

    const url = new URL(request.url);


    const userQuery = url.searchParams.get("query") ?? "What is Cloudflare?";


    // Search for documents in AI Search

    const searchResult = await env.AI_SEARCH.get("my-instance").search({

      messages: [{ role: "user", content: userQuery }],

    });


    if (searchResult.chunks.length === 0) {

      return Response.json({ text: `No data found for query "${userQuery}"` });

    }


    // Join all document chunks into a single string

    const chunks = searchResult.chunks

      .map((chunk) => {

        return `<file name="${chunk.item.key}">${chunk.text}</file>`;

      })

      .join("\n\n");


    // Send the user query + matched documents to OpenAI for answer

    const generateResult = await generateText({

      model: openai("gpt-4o-mini"),

      messages: [

        {

          role: "system",

          content:

            "You are a helpful assistant and your task is to answer the user question using the provided files.",

        },

        { role: "user", content: chunks },

        { role: "user", content: userQuery },

      ],

    });


    return Response.json({ text: generateResult.text });

  },

} satisfies ExportedHandler<Env>;


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/how-to/","name":"How to"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/how-to/bring-your-own-generation-model/","name":"Bring your own generation model"}}]}
```

---

---
title: NLWeb
description: Deploy NLWeb with AI Search to enable conversational natural language queries on your website.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# NLWeb

Enable conversational search on your website with NLWeb and Cloudflare AI Search. This template crawls your site, indexes the content, and deploys NLWeb-standard endpoints to serve both people and AI agents.

Note

This is a public preview ideal for experimentation. If you're interested in running this in production workflows, please contact us at [nlweb@cloudflare.com](mailto:nlweb@cloudflare.com).

## What is NLWeb

[NLWeb ↗](https://github.com/nlweb-ai/NLWeb) is an open project developed by Microsoft that defines a standard protocol for natural language queries on websites. Its goal is to make every website as accessible and interactive as a conversational AI app, so both people and AI agents can reliably query site content. It does this by exposing two key endpoints:

* `/ask`: Conversational endpoint for user queries
* `/mcp`: Structured Model Context Protocol (MCP) endpoint for AI agents

## How to use it

You can deploy NLWeb on your website directly through the AI Search dashboard:

1. Log in to your [Cloudflare dashboard ↗](https://dash.cloudflare.com/).
2. Go to **AI** \> **AI Search**.  
[ Go to **AI Search** ](https://dash.cloudflare.com/?to=/:account/ai/ai-search)
3. Select **Create AI Search**.
4. Select **Website** as a data source.
5. Follow the instructions to create an AI Search instance.
6. Go to the **Settings** for the instance
7. Find **NLWeb Worker** and select "Enable AI Search for your website".

Once complete, AI Search will deploy an NLWeb Worker for you that enables you to use the NLWeb API endpoints.

## What this template includes

Choosing the NLWeb Website option extends a normal AI Search by tailoring it for content‑heavy websites and giving you everything that is required to adopt NLWeb as the standard for conversational search on your site. Specifically, the template provides:

* **Website as a data source:** Uses [Website](https://developers.cloudflare.com/ai-search/configuration/data-source/website/) as data source option to crawl and ingest pages with the Rendered Sites option.
* **Defaults for content-heavy websites:** Applies tuned embedding and retrieval configurations ideal for publishing and content‑rich websites.
* **NLWeb Worker deployment:** Automatically spins up a Cloudflare Worker from the [NLWeb Worker template ↗](https://github.com/cloudflare/templates).

## What the Worker includes

Your deployed Worker provides two endpoints:

* `/ask` — NLWeb’s standard conversational endpoint  
   * Powers the conversational UI at the root (`/`)  
   * Powers the embeddable preview widget (`/snippet.html`)
* `/mcp` — NLWeb’s MCP server endpoint for trusted AI agents

These endpoints give both people and agents structured access to your content.

## Using it on your website

You can use the embeddable snippet to add a search UI directly into your website. For example:

```

<!-- Add css on head -->

    <link rel="stylesheet" href="https://ask.example.com/nlweb-dropdown-chat.css">

    <link rel="stylesheet" href="https://ask.example.com/common-chat-styles.css">


    <!-- Add container on body -->

    <div id="docs-search-container"></div>


    <!-- Include JavaScript -->

    <script type="module">

      import { NLWebDropdownChat } from 'https://ask.example.com/nlweb-dropdown-chat.js';


      const chat = new NLWebDropdownChat({

        containerId: 'docs-search-container',

        site: 'https://ask.example.com',

        placeholder: 'Search for docs...',

        endpoint: 'https://ask.example.com'

      });

    </script>


```

This lets you serve conversational AI search directly from your own domain, with control over how people and agents access your content.

## Modifying or updating the Worker

You may want to customize your Worker, for example, to adjust the UI for the embeddable snippet. In those cases, we recommend calling the `/ask` endpoint for queries, and building your own UI on top of it. However, you may also choose to modify the Worker's code for the embeddable UI.

If the NLWeb standard is updated, you can update your Worker to stay compatible and receive the latest updates.

The simplest way to apply changes or updates is to redeploy the Worker template:

[![Deploy to Cloudflare](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/cloudflare/templates/tree/main/nlweb-template)

1. Use the **Deploy to Cloudflare** button from above to deploy the Worker template to your Cloudflare account.
2. Enter the name of your AI Search in the `RAG_ID` environment variable field.
3. Click **Deploy**.
4. Select the **GitHub/GitLab** icon on the Workers Dashboard.
5. Clone the repository that is created for your Worker.
6. Make your modifications, then commit and push changes to the repository to update your Worker.

Now you can use this Worker as the new NLWeb endpoint for your website.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/how-to/","name":"How to"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/how-to/nlweb/","name":"NLWeb"}}]}
```

---

---
title: Build per-tenant search
description: Isolate search results per tenant in AI Search using separate instances or metadata filtering.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Build per-tenant search

AI Search supports per-tenant search isolation. You can either create a separate instance for each tenant or use a shared instance with metadata filtering.

## Instance per tenant

Create isolated AI Search instances for each tenant at runtime using the [namespace binding](https://developers.cloudflare.com/ai-search/concepts/namespaces/). Each tenant gets its own instance with separate storage and a search index.

* [  wrangler.jsonc ](#tab-panel-6481)
* [  wrangler.toml ](#tab-panel-6482)

JSONC

```

{

  "$schema": "./node_modules/wrangler/config-schema.json",

  "ai_search_namespaces": [

    {

      "binding": "TENANTS",

      "namespace": "default"

    }

  ]

}


```

TOML

```

[[ai_search_namespaces]]

binding = "TENANTS"

namespace = "default"


```

* [  JavaScript ](#tab-panel-6485)
* [  TypeScript ](#tab-panel-6486)

JavaScript

```

export default {

  async fetch(request, env) {

    const url = new URL(request.url);


    // Identify the tenant from the request header

    const tenantId = request.headers.get("x-tenant-id");


    if (!tenantId) {

      return new Response("Missing x-tenant-id header", { status: 400 });

    }


    // Create a new instance for the tenant

    if (url.pathname === "/onboard" && request.method === "POST") {

      const instance = await env.TENANTS.create({

        id: `tenant-${tenantId}`,

      });

      return Response.json({ success: true, instance: await instance.info() });

    }


    // Upload a document to the tenant's instance

    if (url.pathname === "/upload" && request.method === "POST") {

      const formData = await request.formData();

      const file = formData.get("file");


      // Upload the file to the tenant's built-in storage

      const item = await env.TENANTS.get(`tenant-${tenantId}`).items.upload(

        file.name,

        await file.arrayBuffer(),

      );

      return Response.json({ success: true, item });

    }


    // Search the tenant's instance

    if (url.pathname === "/search") {

      const query = url.searchParams.get("q") || "";


      // Each tenant's search is isolated to their own instance

      const results = await env.TENANTS.get(`tenant-${tenantId}`).search({

        messages: [{ role: "user", content: query }],

      });

      return Response.json(results);

    }


    // Delete the tenant's instance and all its data

    if (url.pathname === "/offboard" && request.method === "DELETE") {

      await env.TENANTS.delete(`tenant-${tenantId}`);

      return Response.json({ success: true });

    }


    return new Response("Not found", { status: 404 });

  },

};


```

TypeScript

```

export type Env = {

  TENANTS: AiSearchNamespace;

};


export default {

  async fetch(request, env): Promise<Response> {

    const url = new URL(request.url);


    // Identify the tenant from the request header

    const tenantId = request.headers.get("x-tenant-id");


    if (!tenantId) {

      return new Response("Missing x-tenant-id header", { status: 400 });

    }


    // Create a new instance for the tenant

    if (url.pathname === "/onboard" && request.method === "POST") {

      const instance = await env.TENANTS.create({

        id: `tenant-${tenantId}`,

      });

      return Response.json({ success: true, instance: await instance.info() });

    }


    // Upload a document to the tenant's instance

    if (url.pathname === "/upload" && request.method === "POST") {

      const formData = await request.formData();

      const file = formData.get("file") as File;


      // Upload the file to the tenant's built-in storage

      const item = await env.TENANTS.get(`tenant-${tenantId}`).items.upload(

        file.name,

        await file.arrayBuffer(),

      );

      return Response.json({ success: true, item });

    }


    // Search the tenant's instance

    if (url.pathname === "/search") {

      const query = url.searchParams.get("q") || "";


      // Each tenant's search is isolated to their own instance

      const results = await env.TENANTS.get(`tenant-${tenantId}`).search({

        messages: [{ role: "user", content: query }],

      });

      return Response.json(results);

    }


    // Delete the tenant's instance and all its data

    if (url.pathname === "/offboard" && request.method === "DELETE") {

      await env.TENANTS.delete(`tenant-${tenantId}`);

      return Response.json({ success: true });

    }


    return new Response("Not found", { status: 404 });

  },

} satisfies ExportedHandler<Env>;


```

## Shared instance with metadata filtering

Use a single AI Search instance and organize content by tenant using folder paths. This approach works with both [R2 buckets](https://developers.cloudflare.com/ai-search/configuration/data-source/r2/) and [built-in storage](https://developers.cloudflare.com/ai-search/configuration/data-source/built-in-storage/). Apply [metadata filters](https://developers.cloudflare.com/ai-search/configuration/indexing/metadata/) at query time to ensure each tenant only retrieves their own documents.

* [  wrangler.jsonc ](#tab-panel-6483)
* [  wrangler.toml ](#tab-panel-6484)

JSONC

```

{

  "$schema": "./node_modules/wrangler/config-schema.json",

  "ai_search": [

    {

      "binding": "SHARED_INSTANCE",

      "instance_name": "shared-instance"

    }

  ]

}


```

TOML

```

[[ai_search]]

binding = "SHARED_INSTANCE"

instance_name = "shared-instance"


```

Organize your content by tenant using unique folder paths:

* Directorycustomer-a  
   * Directorylogs/  
         * …  
   * Directorycontracts/  
         * …
* Directorycustomer-b  
   * Directorycontracts/  
         * …

When searching, filter by the tenant's folder to restrict results:

TypeScript

```

// Filter results to only return documents from this tenant's folder

const results = await env.SHARED_INSTANCE.search({

  messages: [{ role: "user", content: "When did I sign my agreement?" }],

  ai_search_options: {

    retrieval: {

      filters: {

        folder: { $gte: "customer-a/", $lt: "customer-a0" },

      },

    },

  },

});


```

This example uses a ["starts with" filter](https://developers.cloudflare.com/ai-search/configuration/indexing/metadata/#starts-with-filter-for-folders) to match all files under `customer-a/` including subfolders.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/how-to/","name":"How to"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/how-to/per-tenant-search/","name":"Build per-tenant search"}}]}
```

---

---
title: Create a simple search engine
description: Build a simple search engine using the AI Search Workers binding and the search method.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Create a simple search engine

Use the `search()` method to implement a simple search engine. This example uses the [Workers binding](https://developers.cloudflare.com/ai-search/api/search/workers-binding/), but can be adapted to use the [REST API](https://developers.cloudflare.com/ai-search/api/search/rest-api/) instead.

To replicate this example:

* Disable query rewriting so that the original user query is matched directly
* Configure your AI Search instance to have small chunk sizes (256 tokens is usually enough)

* [  JavaScript ](#tab-panel-6487)
* [  TypeScript ](#tab-panel-6488)

JavaScript

```

export default {

  async fetch(request, env) {

    const url = new URL(request.url);

    const userQuery = url.searchParams.get("query") ?? "What is Cloudflare?";


    const searchResult = await env.AI_SEARCH.get("my-instance").search({

      messages: [{ role: "user", content: userQuery }],

    });


    return Response.json({

      files: searchResult.chunks.map((chunk) => chunk.item.key),

    });

  },

};


```

TypeScript

```

export interface Env {

  AI_SEARCH: AiSearchNamespace;

}


export default {

  async fetch(request, env): Promise<Response> {

    const url = new URL(request.url);

    const userQuery = url.searchParams.get("query") ?? "What is Cloudflare?";


    const searchResult = await env.AI_SEARCH.get("my-instance").search({

      messages: [{ role: "user", content: userQuery }],

    });


    return Response.json({

      files: searchResult.chunks.map((chunk) => chunk.item.key),

    });

  },

} satisfies ExportedHandler<Env>;


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/how-to/","name":"How to"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/how-to/simple-search-engine/","name":"Create a simple search engine"}}]}
```

---

---
title: Limits &amp; pricing
description: View AI Search usage limits and pricing details for Free and Paid Workers plans.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Limits & pricing

Instances created after **April 16, 2026** include [built-in storage](https://developers.cloudflare.com/ai-search/configuration/data-source/built-in-storage/), a [built-in vector index](https://developers.cloudflare.com/ai-search/configuration/indexing/vector-search/#built-in-vector-index), and web crawling. You can see if your instance was created after the new release by checking if it has built-in storage and vector index. You can check by going on the dashboard under **AI** \> **AI Search**. Select your instance and check the **Overview** tab to see if it includes built-in storage and built-in vector database.

## New instances

If your instance was created after **April 16, 2026**, it includes built-in storage, a built-in vector index, and web crawling. During the open beta, AI Search is free within the limits below. [Workers AI](https://developers.cloudflare.com/workers-ai/platform/pricing/) and [AI Gateway](https://developers.cloudflare.com/ai-gateway/reference/pricing/) usage is billed separately. Pricing details will be communicated at least 30 days before any billing begins.

The following limits apply based on your [Workers plan](https://developers.cloudflare.com/workers/platform/pricing/):

| Limit                           | Workers Free             | Workers Paid                 |
| ------------------------------- | ------------------------ | ---------------------------- |
| AI Search instances per account | 100                      | 5,000                        |
| Files per instance              | 100,000                  | 1M or 500K for hybrid search |
| Max file size                   | 4 MB                     | 4 MB                         |
| Queries per month               | 20,000                   | Unlimited                    |
| Maximum pages crawled per day   | 500                      | Unlimited                    |
| Max custom metadata fields      | 5 per AI Search instance | 5 per AI Search instance     |
| Max text metadata value length  | 500 characters           | 500 characters               |

Need a higher limit?

To request an adjustment to a limit, complete the [Limit Increase Request Form ↗](https://forms.gle/wnizxrEUW33Y15CT8). If the limit can be increased, Cloudflare will contact you with next steps.

## Previous instances

If your instance was created before **April 16, 2026**, it provisions and runs on top of Cloudflare services in your account. These instances will be automatically migrated to managed infrastructure on **June 3, 2026** and the [limits for new instances](#new-instances) will apply. You are billed for the underlying services until migration is completed:

| Service                                                                       | Description                                                 |
| ----------------------------------------------------------------------------- | ----------------------------------------------------------- |
| [R2](https://developers.cloudflare.com/r2/pricing/)                           | Stores your source data                                     |
| [Vectorize](https://developers.cloudflare.com/vectorize/platform/pricing/)    | Stores vector embeddings and powers semantic search         |
| [Workers AI](https://developers.cloudflare.com/workers-ai/platform/pricing/)  | Handles embedding, query rewriting, and response generation |
| [AI Gateway](https://developers.cloudflare.com/ai-gateway/reference/pricing/) | Monitors and controls model usage                           |
| [Browser Run](https://developers.cloudflare.com/browser-run/pricing/)         | Loads dynamic JavaScript content during website crawling    |

The following limits apply to these instances:

| Limit                               | Value                    |
| ----------------------------------- | ------------------------ |
| Max AI Search instances per account | 100                      |
| Max files per AI Search             | 1,000,000                |
| Max file size                       | 4 MB                     |
| Max custom metadata fields          | 5 per AI Search instance |
| Max text metadata value length      | 500 characters           |

### Migration to managed infrastructure

The migration will begin on **June 3, 2026** and may take up to three days. No downtime is expected and no action is required. The following changes will apply:

* **Vectorize database**: Vectors generated by an AI Search instance will be automatically moved from the associated Vectorize database in your account to a managed vector database in the instance. Once the migration is verified, the legacy Vectorize database will be deleted from your account automatically.
* **R2 as data source**: If your instance uses an R2 bucket as a data source, this remains unchanged. Your instance will also get built-in managed storage for direct file uploads.
* **Website as data source**: If your instance uses a website as a data source, previously crawled webpages will be moved to built-in storage, and all future crawls will be stored there. The previous R2 bucket will remain in your account. Browser Run is now built into the product so you will no longer be billed separately for Browser Run usage from AI Search.
* **Workers AI and AI Gateway**: These remain separate services. Your existing usage, configurations, and billing for Workers AI and AI Gateway are unchanged.

You can identify which instance is still on legacy infrastructure in the dashboard under **AI** \> **AI Search**. If the instance does not have a **Built-in Storage** label, it will be migrated to the new infrastructure.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/platform/","name":"Platform"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/platform/limits-pricing/","name":"Limits & pricing"}}]}
```

---

---
title: Release note
description: Review recent changes to Cloudflare AI Search.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Release note

This release notes section covers regular updates and minor fixes. For major feature releases or significant updates, see the [changelog](https://developers.cloudflare.com/changelog).

## 2026-06-10

**Manage AI Search namespaces with Wrangler CLI**

AI Search now supports namespace-level Wrangler commands to create, list, update, and delete [namespaces](https://developers.cloudflare.com/ai-search/concepts/namespaces/) from the command line. Instance-level commands also accept a `--namespace` flag to target instances within a specific namespace, and `--json` output is available for automation and agent workflows. Refer to [Wrangler commands](https://developers.cloudflare.com/ai-search/wrangler-commands/) for full usage details.

## 2026-05-12

**Automatic migration to managed infrastructure on June 3, 2026**

Instances created before April 16, 2026 will be automatically migrated to managed infrastructure on **June 3, 2026**. The migration may take up to three days with no service downtime expected. No action is required. After migration, instances will include built-in storage, a built-in vector index, and built-in web crawling, and [new limits](https://developers.cloudflare.com/ai-search/platform/limits-pricing/#new-instances) will apply. For full migration details, refer to [Limits & pricing](https://developers.cloudflare.com/ai-search/platform/limits-pricing/#previous-instances).

## 2026-04-16

**Hybrid search**

AI Search now supports [hybrid search](https://developers.cloudflare.com/ai-search/configuration/indexing/hybrid-search/), combining vector and BM25 keyword search in a single query. Configure the tokenizer, keyword match mode, and fusion method per instance. Refer to [Search modes](https://developers.cloudflare.com/ai-search/concepts/search-modes/) for an overview.

## 2026-04-16

**Relevance boosting**

Boost search results by metadata fields like timestamp or priority using [relevance boosting](https://developers.cloudflare.com/ai-search/configuration/retrieval/boosting/). Configure up to 3 boost fields per instance or per request.

## 2026-04-16

**Cross-instance search**

Search across multiple AI Search instances in a single call using [namespace-level search](https://developers.cloudflare.com/ai-search/api/search/workers-binding/#namespace-level). Results are merged and ranked, with each chunk identifying which instance it came from.

## 2026-04-16

**Built-in storage and vector index**

New AI Search instances come with [built-in storage](https://developers.cloudflare.com/ai-search/configuration/data-source/built-in-storage/) and a [built-in vector index](https://developers.cloudflare.com/ai-search/configuration/indexing/vector-search/#built-in-vector-index). Upload files directly to an instance using the Items API or the dashboard without setting up external infrastructure.

## 2026-04-16

**New AI Search Workers bindings**

Two new [Workers bindings](https://developers.cloudflare.com/ai-search/api/search/workers-binding/) for AI Search. The `ai_search_namespaces` binding gives access to all instances within a [namespace](https://developers.cloudflare.com/ai-search/concepts/namespaces/) and supports dynamic instance management at runtime. The `ai_search` binding binds directly to a single instance for simpler use cases.

## 2026-04-01

**Wrangler CLI support for AI Search**

Manage AI Search instances from the command line with the `wrangler ai-search` command namespace. Create, list, update, delete, search, and get usage statistics for instances without leaving your terminal. All commands support `--json` for structured output that scripts and AI agents can parse directly. Refer to [Wrangler commands](https://developers.cloudflare.com/ai-search/wrangler-commands/) for full usage details.

## 2026-03-23

**Custom metadata filtering**

Define up to 5 custom metadata fields per AI Search instance and filter search results by category, version, or any custom attribute. Attach metadata via R2 custom headers or HTML meta tags.

## 2026-03-23

**Public endpoint, UI snippets, and MCP support**

AI Search now supports [public endpoints](https://developers.cloudflare.com/ai-search/configuration/retrieval/public-endpoint/), [UI snippets](https://developers.cloudflare.com/ai-search/configuration/retrieval/embed-search-snippets/), and [MCP](https://developers.cloudflare.com/ai-search/api/search/mcp/), making it easy to add search to your website or connect AI agents.

## 2026-03-23

**New REST API endpoints**

AI Search introduces new [REST API](https://developers.cloudflare.com/ai-search/api/search/rest-api/) endpoints for search that use an OpenAI-compatible format. You can use the familiar `messages` array structure that works with existing OpenAI SDKs and tools. The previous AutoRAG API endpoints will continue working as expected. New features will only be added to the new API. See the [migration guide](https://developers.cloudflare.com/ai-search/api/migration/rest-api/) for instructions.

## 2026-02-09

**Crawler user agent renamed**

The AI Search crawler user agent has been renamed from `Cloudflare-AutoRAG` to `Cloudflare-AI-Search`. You can continue using the previous user agent name, `Cloudflare-AutoRAG`, in your `robots.txt`. The Bot Detection ID, `122933950` for WAF rules remains unchanged.

## 2026-02-09

**Specify a single sitemap for website crawling**

You can now specify a single sitemap URL in **Parser options** to limit which pages are crawled. By default, AI Search crawls all sitemaps listed in your `robots.txt` from top to bottom.

## 2026-02-09

**Sync individual files**

You can now trigger a sync for a specific file from the dashboard. Go to **Overview** \> **Indexed Items** and select the sync icon next to the file you want to reindex.

## 2026-01-22

**New file type support**

AI Search now supports EMACS Lisp (`.el`) files and the `.htm` extension for HTML documents.

## 2026-01-19

**Path filtering for website and R2 data sources**

You can now filter which paths to include or exclude from indexing for both website and R2 data sources.

## 2026-01-19

**Simplified API instance creation**

API instance creation is now simpler with optional token\_id and model fields.

## 2026-01-16

**Website crawler improvements**

Website instances now respect sitemap `<priority>` for indexing order and `<changefreq>` for re-crawl frequency. Added support for `.gz` compressed sitemaps and partial URLs in robots.txt and sitemaps.

## 2026-01-16

**Improved indexing performance**

We have improved indexing performance for all AI Search instances. Support for more and larger files is coming.

## 2025-12-10

**Query rewrite visibility in AI Gateway logs**

Fixed a bug where query rewrites were not visible in the AI Gateway logs.

## 2025-11-19

**Custom HTTP headers for website crawling**

AI Search now supports custom HTTP headers for website crawling, allowing you to index content behind authentication or access controls.

## 2025-10-28

**Reranking and API-based system prompts**

You can now enable reranking to reorder retrieved documents by semantic relevance and set system prompts directly in API requests for per-query control.

## 2025-09-25

**AI Search (formerly AutoRAG) now supports more models**

Connect your provider keys through AI Gateway to use models from OpenAI, Anthropic, and other providers for both embeddings and inference.

## 2025-09-23

**Support document file types in AutoRAG**

Our [conversion utility](https://developers.cloudflare.com/workers-ai/features/markdown-conversion/) can now convert `.docx` and `.odt` files to Markdown, making these files available to index inside your AutoRAG instance.

## 2025-09-19

**Metrics view for AI Search**

AI Search now includes a Metrics tab to track file indexing, search activity, and top retrievals.

## 2025-08-28

**Website data source and NLWeb integration**

AI Search now supports websites as a data source. Connect your domain to automatically crawl and index your site content with continuous re-crawling. Also includes NLWeb integration for conversational search with `/ask` and `/mcp` endpoints.

## 2025-08-20

**Increased maximum query results to 50**

The maximum number of results returned from a query has been increased from **20** to **50**. This allows you to surface more relevant matches in a single request.

## 2025-07-16

**Deleted files now removed from index on next sync**

When a file is deleted from your R2 bucket, its corresponding chunks are now automatically removed from the Vectorize index linked to your AI Search instance during the next sync.

## 2025-07-08

**Faster indexing and new Jobs view**

Indexing is now 3-5x faster. A new Jobs view lets you monitor indexing progress, view job status, and inspect real-time logs.

## 2025-07-08

**Reduced cooldown between syncs**

The cooldown period between sync jobs has been reduced to 3 minutes, allowing you to trigger syncs more frequently.

## 2025-06-19

**Filter search by file name**

You can now filter AI Search queries by file name using the `filename` attribute for more control over which files are searched.

## 2025-06-19

**Custom metadata in search responses**

AI Search now returns custom metadata in search responses. You can also add a `context` field to guide AI-generated answers.

## 2025-06-16

**Rich format file size limit increased to 4 MB**

You can now index rich format files (e.g., PDF) up to 4 MB in size, up from the previous 1 MB limit.

## 2025-06-12

**Index processing status displayed on dashboard**

The dashboard now includes a new “Processing” step for the indexing pipeline that displays the files currently being processed.

## 2025-06-12

**Sync AI Search REST API published**

You can now trigger a sync job for an AI Search using the [Sync REST API](https://developers.cloudflare.com/api/resources/ai-search/subresources/rags/methods/sync/). This scans your data source for changes and queues updated or previously errored files for indexing.

## 2025-06-10

**Files modified in the data source will now be updated**

Files modified in your source R2 bucket will now be updated in the AI Search index during the next sync. For example, if you upload a new version of an existing file, the changes will be reflected in the index after the subsequent sync job. Please note that deleted files are not yet removed from the index. We are actively working on this functionality.

## 2025-05-31

**Errored files will now be retried in next sync**

Files that failed to index will now be automatically retried in the next indexing job. For instance, if a file initially failed because it was oversized but was then corrected (e.g. replaced with a file of the same name/key within the size limit), it will be re-attempted during the next scheduled sync.

## 2025-05-31

**Fixed character cutoff in recursive chunking**

Resolved an issue where certain characters (e.g. '#') were being cut off during the recursive chunking and embedding process. This fix ensures complete character processing in the indexing process.

## 2025-05-25

**EU jurisdiction R2 buckets now supported**

AI Search now supports R2 buckets configured with European Union (EU) jurisdiction restrictions. Previously, files in EU-restricted R2 buckets would not index when linked. This issue has been resolved, and all EU-restricted R2 buckets should now function as expected.

## 2025-04-23

**Metadata filtering and multitenancy support**

Filter search results by `folder` and `timestamp` to enable multitenancy and control the scope of retrieved results.

## 2025-04-23

**Response streaming in AI Search binding added**

AI Search now supports response streaming in the `AI Search` method of the [Workers binding](https://developers.cloudflare.com/ai-search/api/search/workers-binding/), allowing you to stream results as they're retrieved by setting `stream: true`.

## 2025-04-07

**AI Search is now in open beta!**

AI Search allows developers to create fully-managed retrieval-augmented generation (RAG) pipelines powered by Cloudflare allowing developers to integrate context-aware AI into their applications without managing infrastructure. Get started today on the [Cloudflare Dashboard](https://dash.cloudflare.com/?to=/:account/ai/autorag).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-search/","name":"AI Search"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-search/platform/","name":"Platform"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-search/platform/release-note/","name":"Release note"}}]}
```
