By default, files you upload — lead attachments, media library images, invoice PDFs — are stored directly on the server the CRM runs on, which works fine out of the box and needs no setup. To move storage to Amazon S3 instead, go to Integrations → Media Library → Storage Settings, set the driver to S3, and enter your bucket details.
When this is worth doing, and when it isn't
If you're on shared hosting with a fixed disk quota, local storage is the thing that will eventually run out — and unlike a database that grows slowly, media uploads (photos, PDFs, attachments) can fill disk quickly. S3 removes that ceiling entirely and, if you also set a CDN base URL, serves files faster to visitors far from your server's location. If disk space and load time genuinely aren't a concern for you, local storage is not something you need to fix — it's the fully working default, not a placeholder.
Step 1: Create an S3 bucket
In the AWS S3 console,
create a new bucket. Note the bucket name and the region you chose
(e.g. ap-south-1 for Mumbai) — both go into the CRM's form exactly as shown in the console.
Step 2: Create an IAM user scoped to just this bucket
Don't use your AWS root account's access keys. In IAM → Users → Create user,
create a user with programmatic access and attach a policy limited to your one bucket —
broad s3:* access on every bucket in your account is far more than this integration needs,
and a narrower policy limits the damage if the key is ever exposed. A policy granting
s3:PutObject, s3:GetObject, and s3:DeleteObject on
arn:aws:s3:::your-bucket-name/* covers everything the CRM does with it.
Generate an access key for this user — AWS shows the access key ID and secret access key exactly once. Copy both immediately; if you lose the secret, you'll need to generate a new key pair rather than retrieve the old one.
Step 3: Fill in the CRM's storage settings
- Driver — S3.
- S3 bucket and S3 region — from Step 1.
- Access key and Secret key — from Step 2.
- S3 endpoint — optional, leave blank for real AWS S3. Fill this in only if you're using an S3-compatible provider instead (Cloudflare R2, DigitalOcean Spaces, Backblaze B2, etc.) — enter that provider's endpoint URL here and everything else works the same way.
- CDN base URL — optional. If you've put CloudFront (or another CDN) in front of the bucket, enter its base URL here so uploaded files are served through the CDN instead of directly from S3.
- Max upload size — the per-file limit in MB, enforced regardless of which driver is active.
Save. New uploads from this point on go to S3; files already stored locally before the switch stay where they are and aren't automatically migrated.
Bucket permissions: the CRM uploads and signs requests to your bucket directly — it doesn't require the bucket itself to be publicly readable. Whether uploaded files (lead attachments, media images) need public read access depends on how you plan to use them; if they're only ever accessed through the CRM's own interface, keeping the bucket private is the safer default.
Testing it
Upload a file anywhere in the CRM that accepts attachments — a lead's Attachments panel, or the Media Library — and confirm it appears and loads correctly. A failure at this point almost always traces to one of three things: the IAM policy not actually covering the bucket you entered, a region mismatch between the bucket and what's entered in the form, or an access key that was copied with a trailing space.