# Managed knowledge

Upload and search an app-owned AI Search knowledge base with the DeepSpace worker helper.

DeepSpace can provision one managed Cloudflare AI Search instance per app. Declare it in `wrangler.toml`; the app calls it through the typed `knowledge(env)` worker helper, and usage is charged to the app owner.

## Configure the binding

```toml
[[ai_search]]
binding = "KNOWLEDGE"
instance_name = "auto"
```

`instance_name` must be `"auto"`, and an app may declare only one `ai_search` binding. DeepSpace owns provisioning and app isolation. The `KNOWLEDGE` name is manifest metadata rather than an AI Search object you call directly from application code.

## Use it from the worker

```ts
import { knowledge } from 'deepspace/worker'

const kb = knowledge(env)

const added = await kb.add(
  new File(
    ['DeepSpace keeps records in app-owned Durable Objects.'],
    'architecture.md',
    {
      type: 'text/markdown',
    },
  ),
  { folder: 'docs' },
)

const results = await kb.search('Where are records stored?', {
  folder: 'docs',
  mode: 'hybrid',
  limit: 5,
})
```

The helper uses the app's signed platform transport. It does not read `env.KNOWLEDGE` as a provider binding.

## API

```ts
const kb = knowledge(env)

await kb.add(file, { folder: 'docs' })
await kb.list({ folder: 'docs', page: 1, perPage: 20, status: 'completed' })
await kb.remove(itemId)
await kb.search(query, { folder: 'docs', mode: 'hybrid', limit: 5 })

const docs = kb.scoped({ folder: 'docs' })
await docs.add(file)
await docs.list({ page: 1, perPage: 20 })
await docs.search(query, { mode: 'semantic', limit: 5 })
```

`scoped` fixes the folder for add, list, and search. Remove remains on the root client because it addresses a provider item ID directly.

Items report one of these statuses: `queued`, `running`, `completed`, `error`, `skipped`, or `outdated`. Upload completion means the provider accepted the item; use `list` to observe indexing status before assuming it is searchable.

## Limits and validation

* A provider upload part may be at most 4 MiB. The SDK safely splits oversized text files on UTF-8 boundaries; oversized non-text files are rejected so application code can use a format-aware splitter.
* A query may contain at most 4,096 characters.
* `limit` and `perPage` must be integers from 1 through 50.
* Folders are relative forward-slash paths. Empty segments, `.` / `..`, backslashes, control characters, and leading slashes are rejected. Folder plus filename must fit the provider's 128-character item-key limit.
* `mode` is `hybrid`, `semantic`, or `fulltext`.

## Pricing

The amounts below include the 10% managed-binding markup:

| Operation                 |                                                           Price |
| ------------------------- | --------------------------------------------------------------: |
| Text ingestion            |                   $0.825 per 1 million provider-reported tokens |
| Image ingestion           | $0.55 per 1 million image tokens, in addition to text ingestion |
| Storage                   |                                              $2.20 per GB-month |
| Hybrid or semantic search |                                        $0.825 per 1,000 queries |
| Full-text search          |                                         $0.11 per 1,000 queries |

Charges settle against actual provider usage when it is available. Uploads reserve a conservative amount first, so a rejected or smaller operation does not become an unbounded charge. DeepSpace credits use 100 credits per US dollar, and managed-knowledge usage appears in the account-wide usage surfaces.

## Errors

Failures throw `KnowledgeError`, which includes `status` and a machine-readable `code`. A split text upload can partially succeed; in that case `uploadedItems` names the accepted parts so you can avoid uploading them twice.

```ts
import { KnowledgeError, knowledge } from 'deepspace/worker'

try {
  await knowledge(env).add(file)
} catch (error) {
  if (error instanceof KnowledgeError) {
    console.error(error.code, error.uploadedItems)
  }
}
```

## See also

* [Bindings reference](/sdk-reference/worker/bindings)
* [Custom bindings](/guides/custom-bindings)
* [App usage](/cli-reference/commands#app-usage)
