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.

Exporting Recordings to Your Own Cloud

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.

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.

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.

pip install requests google-cloud-storage
gcloud auth application-default login
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.

No-script alternative

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

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. 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