Skip to content
AgentSDR

Cloudflare R2 integration

Cloudflare R2 storage for call recordings

Cloudflare R2 is the file storage AgentSDR uses for WhatsApp call recordings and contact photos. The bucket is yours and private, and files are reached only through presigned links that expire.

Cloudflare R2

Private object storage in your own bucket

Connected in
Settings, WhatsApp, Integrations
Powers
Call recordingsContact photos
Credentials
Verified with one live call, then stored encrypted

What it powers

Two kinds of file, one private bucket

You need R2 before you place recorded calls. Without it those two features are off.

  • Call recordings

    One file per call under calls/YYYY/MM/, as Opus audio in a .webm or .ogg container.
  • Contact photos

    Stored under photos/people/ and shown in the app through a link that is valid for one hour.
  • Playback

    A recording plays in the app through a presigned link that expires after five minutes.

What you need

A Cloudflare account with R2, about 10 minutes

  • A Cloudflare account with an R2 subscription. Cloudflare bills R2 usage to you directly, with a free allowance each month; check Cloudflare's R2 pricing for current terms.
  • A private bucket (the default), with a name of 3 to 63 lowercase letters, numbers and hyphens.
  • An R2 API token with Object Read & Write, scoped to that bucket.
  • The owner or admin role in AgentSDR.

Setup

Four values and one test

The short version. You do not need to set up CORS on the bucket.

  1. 01

    Create a private bucket

    In the Cloudflare dashboard, under R2 object storage, create a bucket and leave it private.
  2. 02

    Copy your account ID

    AgentSDR builds the storage address from it.
  3. 03

    Create an R2 API token

    Choose Object Read & Write, scope it to your bucket, and copy the access key ID and secret access key. The secret is shown only once.
  4. 04

    Connect & test

    On the Cloudflare R2 card in Settings, WhatsApp, Integrations, enter the four values. AgentSDR sends one HeadBucket request to confirm they work.

The full step-by-step guide with screenshots and troubleshooting

Security and data

Nothing in the bucket is public

The Cloudflare key you save stays on the server. Browsers and the recorder extension only ever receive links that expire.

  • Presigned links only

    The recorder extension uploads each recording with a presigned URL created for that one file, which expires after 15 minutes. Playback links expire after 5 minutes.
  • A private bucket

    You keep the bucket private. The Cloudflare key never leaves the server.
  • Encrypted at rest

    Saved credentials are encrypted with AES-256-GCM using your instance's INTEGRATION_CREDENTIALS_KEY and are never sent back to the browser. Leave a secret field blank when editing to keep the saved value.
  • Verified before saving

    Each credential is checked with one live call before it is saved. If the check fails, nothing is stored and the form shows the reason.

FAQ

Questions, answered

What does AgentSDR store in R2?

Two things: WhatsApp call recordings, and contact photos. Recordings go under calls/YYYY/MM/ and photos under photos/people/.

Is my recording public?

No. Nothing in the bucket is public. Uploads and playback both use presigned links created for one file, which expire after 15 minutes and 5 minutes respectively.

Do I need to configure CORS?

No. Recordings are uploaded by the recorder extension's background service worker, which has its own host permissions, so the browser does not apply CORS to those requests.

Who pays for the storage?

You do. Cloudflare bills R2 usage directly to your Cloudflare account, and AgentSDR adds nothing. Check Cloudflare's R2 pricing for current terms.

What permissions should the token have?

Object Read & Write, scoped to the one bucket you created for AgentSDR.

How do I check that it works?

The Cloudflare R2 card shows Connected and a Last verified time. To test end to end, place a short recorded WhatsApp call: after it ends an object appears in your bucket under calls/ and the recording plays on the call.

Keep your call recordings in your own bucket

Connect R2, place a recorded WhatsApp call and play it back, with no public files in between.