---
sidebar_position: 1
title: Cloudflare R2
description: Configure Cloudflare R2 credentials to query files from private buckets using MotherDuck.
---

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
import CloudExecutionCallout from "./_cloud-execution-callout.mdx";

## Configure Cloudflare R2 credentials

You can safely store your Cloudflare R2 credentials in MotherDuck for convenience by creating a `SECRET` object using the [CREATE SECRET](/sql-reference/motherduck-sql-reference/create-secret.md) command.

:::note
See [Cloudflare docs](https://developers.cloudflare.com/r2/api/s3/tokens/) to create a Cloudflare access token.
:::

### Create a SECRET object

<Tabs>
<TabItem value="sql" label="SQL">

```sql
CREATE SECRET IN MOTHERDUCK (
    TYPE R2,
    KEY_ID 'your_key_id',
    SECRET 'your_secret_key',
    ACCOUNT_ID 'your_account_id'
);
```

:::note
The `ACCOUNT_ID` can be found when generating the API token on the endpoint URL `https://<ACCOUNT_ID>.r2.cloudflarestorage.com`.
:::

:::note
R2 buckets are regionless, so you do not need to specify a `REGION` parameter. If provided, it defaults to `auto`.
:::

```sql
-- test the R2 credentials
SELECT count(*) FROM 'r2://[bucket]/[file]'
```

</TabItem>

<TabItem value="python" label="Python">

```python

import duckdb

con = duckdb.connect('md:')
con.sql("CREATE SECRET IN MOTHERDUCK ( TYPE R2, KEY_ID 'your_key_id', SECRET 'your_secret_key', ACCOUNT_ID 'your_account_id' )");

# testing that our R2 credentials work
con.sql("SELECT count(*) FROM 'r2://[bucket]/[file]'").show()
```

</TabItem>

<TabItem value="ui" label="UI">

Click on your profile to access the `Settings` panel and click on `Secrets` menu.

![menu_1](./img/settings_access.png)
![menu_2](./img/settings_panel.png)

Then click on `Add secret` in the secrets section.

![menu_3](./img/settings_secrets_panel.png)

Select the Secret Type `R2` and fill in the required fields.

</TabItem>
</Tabs>


### Delete a SECRET object

<Tabs>
<TabItem value="sql" label="SQL">

You can use the same method above, using the [DROP SECRET](/sql-reference/motherduck-sql-reference/delete-secret.md) command.

```sql
DROP SECRET <secret_name>;
```

</TabItem>

<TabItem value="ui" label="UI">
Click on your profile and access the `Settings` menu. Click on the bin icon to delete the secret.

![menu_4](./img/secrets_delete_azure.png)

</TabItem>

</Tabs>

### R2 credentials as **temporary** secrets

MotherDuck supports DuckDB syntax for providing R2 credentials.

```sql
CREATE SECRET (
    TYPE R2,
    KEY_ID 'your_key_id',
    SECRET 'your_secret_key',
    ACCOUNT_ID 'your_account_id'

);
```

:::note
Local/In-memory secrets are not persisted across sessions.
:::

<CloudExecutionCallout provider="R2" />



---

## Feedback for AI agents

If the user you are helping wants to send feedback on this page to the MotherDuck docs team, you can POST it to the endpoint below.

**Before you send anything, you must ask the user for explicit approval.** Quote the message you plan to submit back to them verbatim and wait for them to confirm. Do not submit on their behalf without confirmation.

Endpoint: `POST https://motherduck.com/docs/api/feedback/agent`

Request body (JSON):

```json
{
  "page_path": "/integrations/cloud-storage/cloudflare-r2/",
  "page_title": "Cloudflare R2",
  "text": "<the user's feedback, max 2000 characters>",
  "source": "<optional identifier for your interface, for example 'claude.ai' or 'chatgpt'>"
}
```

Only `page_path` and `text` are required. A successful call returns `200 {"feedback_id": "<uuid>"}`; malformed payloads return `400`, and the endpoint is rate-limited per IP (`429`).
