> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dmly.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom media storage

> Keep the photos, videos and files your customers send in your own AWS S3 or S3-compatible bucket instead of DMLY's storage.

By default, the media that arrives in your conversations is stored by DMLY. **Custom storage**
sends it to a bucket you own instead, on AWS S3 or any S3-compatible provider. Use it when your
privacy policy, a client contract or local data rules say customer files must stay in storage
you control.

## What goes to your bucket

Once it's on, these are saved to your bucket:

* Photos, videos, voice notes and documents customers send you on WhatsApp, Facebook,
  Instagram, Telegram and Live Chat.
* Media brought across from the WhatsApp Business app when a number connects in
  [co-existence](/channels/whatsapp).
* Files your team sends from the [mobile app](/getting-started/mobile-app).

Two things to know before you switch it on:

* **It applies to new media only.** Files already stored stay where they are. Nothing is moved.
* **Files in your bucket stay private.** DMLY never makes them public. When someone opens one in
  the Inbox, DMLY creates a short-lived link for that view, so your bucket doesn't need public
  access.

## Before you start

* **You need to be the workspace owner.** Only the owner can open or change this page.
* **Create a bucket** with your storage provider, and note its name and region.
* **Create an access key** that can read, write and delete objects in that bucket. On AWS, an
  IAM user with a policy like this is enough (swap in your bucket name):

```json theme={"dark"}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:PutObject", "s3:GetObject", "s3:DeleteObject"],
      "Resource": "arn:aws:s3:::your-bucket-name/*"
    }
  ]
}
```

On another provider, create a key with read, write and delete rights on the bucket in its own
dashboard.

## What to enter

Here's what each field looks like on AWS. Use your own values, not these.

| Field | Example | Where to find it |
| - | - | - |
| **Bucket name** | `acme-salon-media` | The name you gave the bucket when you created it, exactly as shown in the S3 console. |
| **Region** | `eu-west-2` | The bucket's region code, shown next to it in the S3 console. For example `us-east-1` (N. Virginia), `eu-west-2` (London), `eu-central-1` (Frankfurt) or `af-south-1` (Cape Town). Use the code, not the city name. |
| **S3 endpoint URL** | Leave blank | Only needed for providers other than AWS. |
| **Path-style addressing** | Off | Leave it off on AWS. |
| **Access key ID** | `AKIAIOSFODNN7EXAMPLE` | 20 characters, starting `AKIA`. Shown when you create the IAM user's access key. |
| **Secret access key** | `wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY` | 40 characters. AWS shows it only once, when you create the key, so copy it then. |

On an S3-compatible provider, the bucket and keys work the same way. The region and endpoint
come from your provider:

| Provider | Region | S3 endpoint URL |
| - | - | - |
| Cloudflare R2 | `auto` | `https://ACCOUNT_ID.r2.cloudflarestorage.com`, with your Cloudflare account ID |
| DigitalOcean Spaces | `nyc3` | `https://nyc3.digitaloceanspaces.com` |
| Wasabi | `eu-central-1` | `https://s3.eu-central-1.wasabisys.com` |
| Backblaze B2 | `us-west-004` | `https://s3.us-west-004.backblazeb2.com` |

These show one region each. Use the region your bucket is actually in, and the endpoint that
matches it. If saving fails with a provider like these, try turning on **Path-style
addressing**.

## Set it up

<Steps>
  <Step title="Open Custom storage">
    Go to **Workspace Settings → Custom storage** and turn on **Use custom storage**.
  </Step>

  <Step title="Enter the connection details">
    Fill in **Bucket name** and **Region**. On AWS, leave **S3 endpoint URL** blank.

    On any other provider, paste its HTTPS endpoint into **S3 endpoint URL**. Your provider's
    dashboard lists it. If the provider asks for it, turn on **Path-style addressing**.
  </Step>

  <Step title="Enter your access key">
    Paste the **Access key ID** and **Secret access key**. Both are stored encrypted.
  </Step>

  <Step title="Save">
    Select **Save storage settings**. DMLY writes a small test file to your bucket, reads it
    back and deletes it before it switches anything over. If all three work, you'll see
    **Storage settings saved.** and new media goes to your bucket from then on.
  </Step>
</Steps>

<Note>
  Changing the bucket, region or endpoint later doesn't need the keys again. Leave both key
  fields blank to keep the saved ones.
</Note>

## If saving fails

Nothing changes until the test passes, so media keeps going to the same place as before.

* *Could not verify storage. Check the endpoint, credentials, and bucket read/write/delete
  permissions.* The test file couldn't be written, read back or deleted. Check the bucket name
  and region, and that the key has all three permissions.
* *Use a publicly reachable HTTPS S3 endpoint without credentials or query parameters.* The
  endpoint must start with `https://`, be reachable from the internet, and contain nothing but
  the address. DMLY doesn't follow redirects, and won't connect to a private or internal
  address.

## Switching back, or changing bucket

Turn off **Use custom storage** and save, and new media goes to DMLY storage again. Connect a
different bucket, and new media goes there.

Either way, DMLY keeps the old connection so it can still show the files already in that
bucket.

<Warning>
  **Keep old buckets and their keys working.** Files saved to a bucket stay there. If you delete
  the bucket or revoke its key, those files stop showing in your conversations. DMLY can't bring
  them back.

  **DMLY doesn't fall back to its own storage.** If your bucket stops accepting uploads, for
  example because the key was revoked, new media isn't saved anywhere else. Check this page
  after any change to your storage account.
</Warning>
