Workers binding
Workers provides a serverless execution environment that allows you to create new applications or augment existing ones. Use a Workers binding 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.
To use AI Search with Workers, you must create an AI Search binding. You create bindings by updating your Wrangler configuration. AI Search provides two types of bindings:
- Namespace binding:
ai_search_namespaces - Instance binding:
ai_search
Access all instances within a namespace. You can get, create, list, and delete instances at runtime.
{ "$schema": "./node_modules/wrangler/config-schema.json", "compatibility_date": "2026-03-27", "ai_search_namespaces": [ { "binding": "AI_SEARCH", "namespace": "my-namespace" } ]}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 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. |
Bind directly to a single instance in the default namespace. Use this when you know which instance you need at deploy time.
{ "$schema": "./node_modules/wrangler/config-schema.json", "compatibility_date": "2026-03-27", "ai_search": [ { "binding": "MY_SEARCH", "instance_name": "my-instance" } ]}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. |
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.
const instance = env.AI_SEARCH.get("my-instance");Uploads a document for indexing. Returns immediately. The document is queued for processing.
// Upload from a stringawait instance.items.upload( "faq.md", "# FAQ\n\nQ: How do I reset my password?\nA: Go to Settings > Security...",);
// Upload from an ArrayBufferconst pdfResponse = await fetch("https://example.com/guide.pdf");const pdfBuffer = await pdfResponse.arrayBuffer();await instance.items.upload("guide.pdf", pdfBuffer);
// Upload from a ReadableStreamawait instance.items.upload("doc.txt", request.body);Attach custom metadata to a document for filtering in search queries. Custom metadata fields must be defined on the instance first using the update() method or at creation time.
await instance.items.upload("guide.pdf", pdfBuffer, { metadata: { category: "onboarding", language: "en", version: "2.0", },});| 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. |
| Field | Type | Description |
|---|---|---|
id | string | The unique item identifier. |
key | string | The filename or key of the item. |
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.
// Wait for a specific document to finish indexing before searchingconst item = await instance.items.uploadAndPoll( "handbook.txt", handbookContent,);console.log(`handbook.txt status: ${item.status}`); // "completed"
// Now search across all uploaded documentsconst results = await instance.search({ messages: [{ role: "user", content: "password reset policy" }],});Same as items.upload(), 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. |
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. |
Returns a paginated list of items in the instance.
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| 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). |
| 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. |
Deletes an item and its indexed chunks.
await instance.items.delete("item-id-123");| Parameter | Type | Required | Description |
|---|---|---|---|
itemId | string | Yes | The unique identifier of the item to delete. |
Returns void. Throws an error if the item does not exist.
Returns a handle to a specific item for retrieving its status or downloading the original file.
Returns the status and metadata of a specific item.
const itemInfo = await instance.items.get("item-id-123").info();| Parameter | Type | Required | Description |
|---|---|---|---|
itemId | string | Yes | The unique identifier of the item. |
| 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. |
Downloads the original source file for an item.
const file = await instance.items.get("item-id-123").download();// file.body is a ReadableStream| Parameter | Type | Required | Description |
|---|---|---|---|
itemId | string | Yes | The unique identifier of the item. |
| 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. |