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

# Bring your own storage (BYOS)

> Stream from your own cloud — S3 or an rclone remote.

By default torrin caches content in its own shared store and evicts it over time. With
**bring-your-own-storage**, content you stream is also written to *your* cloud, encrypted,
and served back through torrin — so it's permanent, private, and counts against your space,
not torrin's.

## How it works

When BYOS is connected, a completed stream is copied to your backend under an encrypted
key (torrin never stores your filenames in the clear). Playback still goes through torrin's
signed, geo-routed URLs, so the origin and your credentials stay hidden — the client can't
tell BYOS content from shared-cache content.

## Connecting

Two shapes, depending on the backend:

* **S3-compatible** (S3, Backblaze, Wasabi, Garage...) — pass the endpoint and keys directly:

  ```bash theme={null}
  curl -X POST https://api.torrin.app/api/storage/connect \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "provider": "s3",
      "endpoint": "https://s3.example.com",
      "region": "us-east-1",
      "bucket": "my-torrin",
      "access_key": "...",
      "secret_key": "..."
    }'
  ```

* **OAuth backends** (Google Drive, Dropbox, OneDrive, pCloud) — start the consent flow at
  `GET /api/storage/oauth/{provider}/start` and torrin finishes the connection on callback.

## Managing it

| Call | Does |
| - | - |
| `GET /api/storage` | Whether BYOS is connected, plus the provider count and pool policy. |
| `POST /api/storage/connect` | Connect the primary backend. |
| `DELETE /api/storage` | Disconnect. Existing content stays in your cloud. |
| `PUT /api/storage/providers` | Add providers to the pool and set the policy (`epmfs` pool or `all` mirror). |
| `DELETE /api/storage/providers/{idx}` | Remove one provider from the pool. |
| `GET /api/storage/rclone-config` | Download your `rclone.conf` to mount the storage yourself. |
| `PUT /api/storage/evict-policy` | Set cleanup rules: `evict_after_days`, `evict_max_gb` (0 = keep everything). |
| `POST /api/storage/evict` | Remove one release (`info_hash`) from your storage. |

## Pooling and mirroring

Add more providers to act as one encrypted pool. `union_policy` picks placement:
`epmfs` (default) spreads files across providers by free space; `all` mirrors every
file to every provider for redundancy.

```bash theme={null}
curl -X PUT https://api.torrin.app/api/storage/providers \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "union_policy": "all",
    "providers": [
      { "endpoint": "https://s3.example.com", "bucket": "backup", "access_key": "...", "secret_key": "..." }
    ]
  }'
```

<Note>
  Everything written to your storage is encrypted with a key torrin holds, so a raw browse of
  your bucket shows opaque blobs, not media.
</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.