# Exporting Recordings to Your Own Cloud

> Export your call recordings from Edesy as permanent links and bulk-upload them to your own Google Cloud Storage or Amazon S3 bucket.

Source: https://edesy.in/docs/voice-agent/features/exporting-recordings

You own your call data. This page is the canonical reference for getting your recordings off the platform and into **your own** Google Cloud Storage (GCS) or Amazon S3 bucket — for compliance archives, analytics, or long-term backup.

The workflow is self-service and needs no platform-side engineering:

1. **Export** a CSV of permanent recording links from the dashboard.
2. **Upload** every recording to your bucket with a short script.

> Looking for the full, copy-paste walkthrough with the complete Python script, an S3 variant, and automation tips? See the step-by-step tutorial: [How to Export AI Call Recordings to Google Cloud Storage & Amazon S3](https://edesy.in/blog/export-call-recordings-google-cloud-storage-s3-2026).

## Step 1: Export permanent recording links

From the **Campaigns** page in your dashboard (`voice-agent.edesy.in`):

1. Select the campaign(s) you want (date filters apply).
2. Click **Export**.
3. Tick **Recordings** and **Permanent links**.
4. Download the CSV (`campaigns-export-<date>.csv`).

The same option is available per agent under **Call Logs → Export** for calls that aren't part of a campaign.

### Permanent vs. 7-day links

| Option | Link lifetime | Use it for |
|--------|---------------|------------|
| Recordings only | 7 days (presigned) | Quick, one-off integrations |
| Recordings + **Permanent links** | **Never expires** | Migrating to your own cloud, long archives |

Always enable **Permanent links** for a migration — a large upload job that processes the CSV days later won't fail on dead URLs.

## Step 2: Read the CSV

Each row is one call. The relevant column is **`Recording URL`**:

```
https://voice-agent.edesy.in/api/public/recordings/<conversation-id>?token=v1.<signature>
```

| Detail | Notes |
|--------|-------|
| File extension | Not in the URL. Determined by the call's telephony path. |
| Get a filename | Append `&download=true` → server returns `Content-Disposition: filename="recording-<id>.<ext>"`. |
| Formats | `mp3` (Twilio/Plivo), `wav` (Exotel), `ogg` (LiveKit native audio). |
| Encoding | The CSV is UTF-8 with a BOM (for Excel) — read it as `utf-8-sig` in scripts. |

Export caps: **200,000** rows per campaign export, **50,000** per agent Call Logs export. For larger archives, export in batches by date.

## Step 3: Upload to your bucket

This script streams each recording straight from Edesy into a **GCS** bucket (no local disk), preserves the correct extension, and skips files already uploaded so it's safe to re-run.

```bash
pip install requests google-cloud-storage
gcloud auth application-default login
```

```python
import csv, re, requests
from google.cloud import storage

CSV_PATH   = "campaigns-export.csv"
GCS_BUCKET = "my-call-recordings"
GCS_PREFIX = "edesy-recordings/"

bucket = storage.Client().bucket(GCS_BUCKET)

def filename_for(resp):
    cd = resp.headers.get("Content-Disposition", "")
    m = re.search(r'filename="?([^"]+)"?', cd)
    return m.group(1) if m else "recording.mp3"

with open(CSV_PATH, newline="", encoding="utf-8-sig") as f:
    for row in csv.DictReader(f):
        url = (row.get("Recording URL") or "").strip()
        if not url:
            continue
        resp = requests.get(url + "&download=true", stream=True, timeout=180)
        if resp.status_code != 200:
            continue  # recording not available for this call
        blob = bucket.blob(GCS_PREFIX + filename_for(resp))
        if blob.exists():
            continue  # already uploaded — idempotent
        blob.upload_from_file(resp.raw, content_type=resp.headers.get("Content-Type"))
        print("OK", blob.name)
```

**Amazon S3?** Swap the GCS client for `boto3` and use `s3.upload_fileobj(resp.raw, bucket, key, ...)`. The CSV handling, permanent links, and extension logic are identical — full S3 code is in the [tutorial](https://edesy.in/blog/export-call-recordings-google-cloud-storage-s3-2026#amazon-s3-instead-change-one-block).

### No-script alternative

Download recordings to a local folder, then push the whole folder in one command:

```bash
gcloud storage cp --recursive ./recordings gs://my-call-recordings/edesy-recordings/   # GCS
aws s3 sync ./recordings s3://my-call-recordings/edesy-recordings/                      # S3
```

## Automating ongoing backups

Schedule the export + upload script on a nightly cron with a rolling date filter, or trigger it from a post-call [webhook](https://edesy.in/docs/voice-agent/features/webhooks). Because the upload step is idempotent, re-running only adds what's new — giving you a self-maintaining mirror of your call audio.

## Next Steps

- [Call Recording](https://edesy.in/docs/voice-agent/features/recording) — enable and configure recording
- [Transcripts](https://edesy.in/docs/voice-agent/features/transcripts) — export call transcripts alongside audio
- [Security Best Practices](https://edesy.in/docs/voice-agent/advanced/security) — encryption and access control for your archive
- [Full tutorial: Export recordings to GCS & S3](https://edesy.in/blog/export-call-recordings-google-cloud-storage-s3-2026)
