R2
You can connect a Cloudflare R2 bucket as a data source for your AI Search instance. AI Search indexes the files stored in your bucket automatically.
You can connect an R2 bucket when creating a new instance through the dashboard, the REST API, or Wrangler. R2 is an optional data source that you can add alongside 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 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 for setup instructions.
To get started, configure an R2 bucket containing your data. Files that are unsupported or exceed the size limit will be skipped during indexing and logged as errors.
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 for pattern syntax, filtering behavior, and more examples.
For supported file types and size limits, refer to Data source.
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 in your AI Search configuration.
Use the customMetadata option when uploading objects with the R2 Workers binding:
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:
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 to set x-amz-meta-* headers:
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"When a file is fetched from R2 during indexing:
- All
x-amz-meta-*headers are read from the object. - The
x-amz-meta-prefix is stripped (for example,x-amz-meta-categorybecomescategory). - Field names are matched against your schema (case-insensitive).
- Values are cast to the configured data type.
- Invalid values (for example, a non-numeric string for a
numbertype) are silently ignored.
Metadata values support Unicode characters through MIME-Word encoding (RFC 2047). Most S3-compatible tools handle this encoding automatically.