# The Ultimate Guide to Salesforce Files: Architecture, Features Walk-Through, & Real-World Best Practices

> Salesforce Files explained: architecture (ContentDocument/Version/Link), sharing, versions, Files Connect, APIs, and smart tips to cut storage costs.

*2025-11-24 · by Sharmi*

**Tags:** Salesforce

*

## **Introduction**

If you’ve ever uploaded a contract, attached a presentation to an Opportunity, or shared a report inside Salesforce, you’ve already worked with [**Salesforce Files**.](https://www.cloudfiles.io/blog/salesforce-files-vs-documents-the-ultimate-guide-for-admins-architects#salesforce-files-the-modern-standard:~:text=Lightning%2Dfirst%20orgs.-,Salesforce%20Files%20(The%20Modern%20Standard),-Salesforce%20Files%20represent) They’re the modern document system in [Salesforce Lightning,](https://www.salesforce.com/in/campaign/lightning/) designed to handle everything from uploads and sharing to version control and access management - across records, users, and even connected external platforms. But behind that simple “Upload File” button lies a powerful ecosystem of objects, permissions, and APIs. Understanding how it all fits together is what separates basic users from true Salesforce pros.

This guide walks you through the complete Salesforce Files framework - from the user experience and data model to APIs, automation, versioning, and storage optimization. By the end, you’ll know exactly how every file works, connects, and can be leveraged in your org.

## What to expect in this Blog

You can explore this guide in the order above, or jump straight to any section that interests you most.

[A Brief History of Salesforce Files](https://www.cloudfiles.io/blog/salesforce-file-ultimate-guide-architecture-features-history-automation#a-brief-history-of-salesforce-files) → A quick timeline of how Salesforce evolved from Documents + Attachments to CRM Content and finally Files - and what problems each shift solved.

[Where You’ll Find Salesforce Files: Tabs, Records & Chatter](https://www.cloudfiles.io/blog/salesforce-file-ultimate-guide-architecture-features-history-automation#where-youll-find-salesforce-filestabs-records-chatter) → Explains how Files show up in real life: the Files tab, Files related list on records, and Chatter uploads — and how these experiences differ.

[Architecture of Salesforce Files: Core Objects, Relationships & Upload Lifecycle](https://www.cloudfiles.io/blog/salesforce-file-ultimate-guide-architecture-features-history-automation#architecture-of-salesforce-files-core-objects-relationships-upload-lifecycle) → Breaks down the backend model (ContentDocument, ContentVersion, ContentDocumentLink) and what actually gets created when a file is uploaded or updated.

[Files Connect](https://www.cloudfiles.io/blog/salesforce-file-ultimate-guide-architecture-features-history-automation#files-connect-extending-salesforce-files-beyond-native-storage) → Extending Salesforce Files Beyond Native Storage -Covers how Salesforce connects to SharePoint/Google Drive/OneDrive using Files Connect and what “external files in Salesforce” really mean.

[Working with Salesforce Files: A Complete Front-End Walkthrough](https://www.cloudfiles.io/blog/salesforce-file-ultimate-guide-architecture-features-history-automation#https://www.cloudfiles.io/blog/salesforce-file-ultimate-guide-architecture-features-history-automation#files-connect-extending-salesforce-files-beyond-native-storage)  → A user-first walkthrough of the Lightning UI — upload, preview, share, versioning, remove vs delete — mapped to what happens behind the scenes.

[Working with Salesforce Files Programmatically (Apex & APIs)](https://www.cloudfiles.io/blog/salesforce-file-ultimate-guide-architecture-features-history-automation#working-with-salesforce-files-programmatically-apex-apis) → Shows how developers automate and integrate Files using Apex, REST APIs, and Flow — with real patterns for upload, link, version, and download.

[Further Reading](https://www.cloudfiles.io/blog/salesforce-file-ultimate-guide-architecture-features-history-automation#further-reading-references) →  A curated list of CloudFiles and Salesforce official documents for deeper dives, setup guides, and advanced use cases.

## A Brief History of Salesforce Files

Salesforce hasn’t always had the modern, flexible file system we rely on today. What we now know as Salesforce Files* is the result of more than a decade of evolution — and understanding that journey explains **why the current architecture works the way it does**.

Long before Lightning, file storage lived in two disconnected worlds:

- [**Documents**](https://www.cloudfiles.io/blog/salesforce-files-vs-documents-the-ultimate-guide-for-admins-architects#salesforce-documents-the-classic-legacy:~:text=with%20Salesforce%E2%80%99s%20roadmap.-,Salesforce%20Documents%20(The%20Classic%20Legacy),-Salesforce%20Documents%20belong) — stored in the Documents tab for org-wide assets like logos, templates, and graphics. These weren’t tied to records and often relied on static public URLs.
- [**Attachments**](https://www.cloudfiles.io/blog/salesforce-files-vs-notes-and-attachments-complete-guide#what-is-salesforce-notes-attachments:~:text=modernize%20document%20management.-,What%20is%20Salesforce%20Notes%20%26%20Attachments%3F,-Before%20Salesforce%20Files) — uploaded directly to records like Opportunities and Cases. Every upload created a **separate physical copy**, meaning the same contract attached five times consumed storage *five times*.

This setup worked in the early CRM era but quickly broke down as organizations grew. Admins had no way to track versions, encourage reuse, or prevent storage bloat.

To bridge the gap, Salesforce introduced [CRM Content](https://help.salesforce.com/s/articleView?id=experience.content_parent.htm&type=5) & Libraries — bringing folder-like structure, granular permissions, and early version control. It was a significant improvement (especially for marketing teams), but the system still lived in its own silo. Libraries weren’t fully searchable, weren’t mobile-friendly, and still didn’t support one-file-to-many-records linking.

*
Everything changed with Lightning Experience and the launch of **Salesforce Files**.

Files introduced a unified, content-based architecture built on:

- **ContentDocument** — a single master file record
- **ContentVersion** — each version of the file over time
- **ContentDocumentLink** — the mapping that lets one file appear on multiple records without duplication

Suddenly, one file could belong to an **Account + Opportunity + Case**, support version history, embed in Chatter, generate public links, surface in search, and even be accessed from mobile — all while storing the binary only once.

Salesforce made this shift intentionally:

| Old World | New World |
|---|---|
| Static | Collaborative |
| Duplicate copies | Version-controlled, single source of truth |
| Siloed storage systems | Unified storage across CRM |
| Limited preview and search | Lightning-native previews, global search |
| Higher cost per GB | Optimized File Storage utilization |

Today, **Salesforce Files is the standard**, and Attachments/Documents exist only for legacy Classic-era needs. Any new implementation, integration, or automation should assume Files as the foundation — especially as Salesforce continues to build collaboration, AI, and external content access on top of it.

## Where You’ll Find Salesforce Files: Tabs, Records & Chatter

Before diving into objects and APIs, it helps to see how Salesforce Files appear in everyday use. Whether you’re uploading a contract, sharing a slide deck, or commenting on a post in Chatter, you’re already working within this framework - just without seeing the layers underneath.

### **The Files Tab - Your Personal Library in the Cloud**

Think of the **Files tab** as your personal workspace inside Salesforce - a central place to store and manage documents that might not be tied to a record yet.

You can upload, rename, or share files directly from here. Behind the scenes, Salesforce tracks ownership, versions, and [sharing permissions](https://help.salesforce.com/s/articleView?id=platform.security_data_access.htm&type=5) automatically.

Here’s what you can do here:

- Upload files directly (they’re not tied to any record yet)
- View all files you own or that others have shared with you
- Sort files by *Owned by Me*, *Shared with Me*, *Recent*, or *All Files*
- Rename, delete, or share files directly from this view

This area is especially useful for work-in-progress materials like presentations, templates, or reference sheets. Once finalized, you can attach them to any record without re-uploading - a small but efficient time saver.

### **Files on Records - The **['Files' Related List](https://admin.salesforce.com/blog/2017/5-reasons-use-files-related-list)** (or Record Widget)**

This is where most users interact with Salesforce Files day-to-day. On any record - whether it’s an Opportunity, Account, Case, or Custom Object - you’ll see a Files related list or Files widget. This shows only the files that are linked to that record.

When you upload a file here, Salesforce automatically creates and connects three records behind the scenes:

- **ContentVersion** – the actual file you uploaded
- **ContentDocument** – the master file record that represents the file as a whole
- **ContentDocumentLink** – the connection that ties the file to the specific record you uploaded it on

This structure is what makes Salesforce Files so powerful. It allows the same document to be shared across multiple records without creating duplicates or wasting storage. We’ll unpack these three in more detail in an upcoming section, but for now, the key idea is that this structure allows a single file to exist once and be linked anywhere it’s needed.

In simpler terms: The **Files tab** is your personal library and the **Files related list** is where those files connect to business records and become part of your workflow.

### Files in [Chatter ](https://help.salesforce.com/s/articleView?id=experience.collab_setting_up.htm&type=5)- Collaboration Meets Storage

Ever uploaded a file in a Chatter post or comment? That’s also a Salesforce File. Chatter simply adds a collaboration layer on top of the standard file framework. When you share a file in a Chatter feed, it’s still stored as a **ContentDocument** behind the scenes, just like any other file in Salesforce.

The difference is in how it’s shared. Chatter automatically manages visibility based on the post’s audience. From there, the file can still be linked to records, versioned, or even shared externally if permissions allow.

Chatter Files bridge the gap between collaboration and storage, making it easy for teams to discuss, edit, and manage documents all within Salesforce.

In Summary, Salesforce Files are designed to work wherever you do - in personal storage, on records, or inside conversations. The Files tab is your private workspace, the Files related list keeps record data and documents connected, and Chatter adds collaboration to the mix. Together, they create a unified document experience across Salesforce: simple for users, structured for admins, and consistent for everyone.

## Architecture of Salesforce Files: Core Objects, Relationships & Upload Lifecycle

Now that we’ve seen how files appear in tabs, records, and Chatter, let’s look under the hood. Every time you upload a file in Salesforce, three tightly linked objects come together to handle everything — **ContentDocument, ContentVersion**, and **ContentDocumentLink.** These three form the foundation of Salesforce Files, powering uploads, versioning, sharing, and efficient storage across the platform.

At the heart of Salesforce Files are three interconnected objects:

| Object | Description | Stores |
|---|---|---|
| [**ContentDocument**](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_contentdocument.htm) | Represents the file as a whole | Metadata like name, owner, type |
| [**ContentVersion**](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_contentversion.htm) | Stores actual file data | Binary content, title, version number |
| [**ContentDocumentLink**](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_contentdocumentlink.htm) | Links the file to records/users/groups | Relationship, share type, visibility |

Together, they handle everything from versioning to sharing to storage efficiency. Let’s break them down in plain English.

### **1. ContentDocument - The Main File Record**

Think of ContentDocument as the identity card of your file. It represents the file as a whole - not the content itself, but all the metadata around it: the file name, size, type, owner, and so on. Whenever you upload something new, Salesforce automatically creates a ContentDocument to anchor it. From that point on, every version or link traces back to this parent record.

Note: If you ever delete a ContentDocument, Salesforce also removes all related versions and links - because it’s the parent in the hierarchy. So, if you upload Proposal.pdf, Salesforce creates one ContentDocument record for it - and everything else (versions, links) hangs off that.

### **2. ContentVersion - Every Update You Make**

Next comes ContentVersion which is where Salesforce stores the actual file data - the binary content. Each time you upload or replace a file, a new ContentVersion is created.

Let’s say you upload Proposal.pdf today - that’s Version 1. Next week, you upload an updated version with pricing changes - Salesforce doesn’t overwrite it; it creates Version 2 under the same ContentDocument. That’s how version control works in Salesforce Files. You can always track, preview, or roll back to earlier versions.

### **3. ContentDocumentLink - The Invisible Connector**

ContentDocumentLink is what ties your file to Salesforce records, users, or groups. Each link record defines:

- **ContentDocumentId:** Which file it points to
- **LinkedEntityId:** Who or what it’s connected to (a record, user, or group)
- [**ShareType**](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_contentdocumentlink.htm#:~:text=WorkType%2C%20WorkTypeGroup%2C%20WorkTypeGroupMember-,ShareType,-Type): Whether the person can view or collaborate on it
- [**Visibility:**](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_contentdocumentlink.htm#:~:text=36.0%20and%20later.-,Visibility,-Type) Whether it’s visible to everyone with record access or just specific users

A single file can be linked to multiple records without creating duplicates. Upload Contract.pdf to an Opportunity, then link it to the related Account. Behind the scenes, Salesforce just adds another ContentDocumentLink pointing to the same ContentDocument. That means less clutter, less storage use, and a single version of truth.

### **How They Work Together - The Lifecycle of a File Upload**

Now that we’ve met the key players - ContentDocument, ContentVersion, and ContentDocumentLink - let’s see how they [work in sync](https://help.salesforce.com/s/articleView?id=000393095&type=1) every time a file enters Salesforce.

### **Step 1: Upload and File Creation**

It all begins the moment a user uploads a file - whether through the Files tab, a record page, or Chatter. Behind the scenes, Salesforce instantly creates a new **ContentVersion** record to store the file’s binary data, its title, and uploader information.

If this is the first time that particular file is being added, Salesforce also generates a **ContentDocument** - the master file record that represents the file as a whole. Every future version of that file will point back to this single record, keeping your file’s identity consistent across uploads and updates.

### **Step 2: Linking the File to Where It Belongs**

Once the file exists, Salesforce needs to decide where it lives and who can see it. That’s where **ContentDocumentLink** comes in. This object establishes the relationships between the file and its environment.

- Uploading from the **Files tab** links the file to the uploader (so it appears in “My Files”).
- Uploading directly on a **record** links it to that specific record - and, by extension, everyone with access to that record.

Each ContentDocumentLink also defines visibility and access level, determining who can view or collaborate on the file.

### **Step 3: Updating and Versioning**

When someone replaces or updates a file, Salesforce doesn’t overwrite the old one. Instead, it quietly creates a new ContentVersion tied to the same ContentDocument. This design preserves the full version history - letting users roll back, compare, or audit changes without losing past iterations.

The latest upload automatically becomes the active version visible everywhere the file is shared, while older versions remain archived for reference.

### **Step 4: The Final Picture**

By the time the upload process completes, three records are working together in perfect coordination:

- **ContentDocument** acts as the anchor - the single identity of the file.
- **ContentVersion** stores the file’s content and version details.
- **ContentDocumentLink** connects the file to users, records, or groups and manages visibility.

This design is what makes Salesforce Files efficient and scalable. Instead of duplicating files across records, Salesforce creates relationships — saving storage, preserving version integrity, and maintaining a clear trail of where each file lives and who can access it.

### Common Fields to Know (for Reports & APIs)

While working with these objects, you’ll often come across fields like:

- [**LinkedEntityId**](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_contentdocumentlink.htm#:~:text=ContentDocument-,LinkedEntityId,-Type): The record or user the file is linked to
- **FirstPublishLocationId:** Where the file was first shared or uploaded
- **OwnerId:** Who owns the file (often the uploader)
- **CreatedById / LastModifiedById:** Standard audit fields you can use in reports

These become super useful when you’re building automations or integrations that reference files programmatically.

### Other Supporting Objects You Should Know

While the three core objects handle most file operations, a few supporting objects extend the Salesforce Files model to include sharing, tracking, and external storage.

| Object | Represents | Common Use | Why It Matters |
|---|---|---|---|
| [**ContentDistribution**](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_contentdistribution.htm) | Public/external sharing link | Share files with customers or external users | Controls URLs, download permissions, and expiry |
| [**ContentDistributionView**](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_contentdistributionview.htm) | File engagement data | Track who viewed or downloaded files | Adds analytics to external sharing |
| [**ContentWorkspace**](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_contentworkspace.htm?utm_source=chatgpt.com#:~:text=39.0%20and%20later.-,Usage,-Use%20this%20object) | Libraries from [CRM Content](https://help.salesforce.com/s/articleView?id=experience.content_parent.htm&type=5) | Group or organize files into collections | Useful for legacy and structured storage |
| [**ContentHubItem**](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_contenthubitem.htm) | Externally stored file reference | Integrations with SharePoint, Google Drive, Box | Allows Salesforce to display and manage external files |

Together, these objects expand Salesforce Files beyond just internal storage - into a full ecosystem for sharing, analytics, and integration with external systems.

### [Files Connect](https://help.salesforce.com/s/articleView?id=experience.collab_files_connect_share.htm&type=5) – Extending Salesforce Files Beyond Native Storage

Files Connect is Salesforce’s native bridge between Salesforce and external file repositories. It allows users to access, search, and attach files from these external systems without uploading or duplicating them inside Salesforce. Instead of creating new ContentDocument records for every upload, Salesforce creates ContentHubItem entries — lightweight references that point directly to the external file.

From a user’s perspective, these external files behave just like native Salesforce Files. You can attach them to records, share them with colleagues, or preview them inside Lightning — all while the actual data stays securely in your connected storage. This not only helps with storage optimization but also maintains compliance and data consistency across systems.

Files Connect supports two main connection types:

- Identity-Based Authentication (e.g., OAuth with SharePoint or Google Drive)
- Named Principal Authentication (a single service account for org-wide access)

Admins can configure it from Setup → Files Connect, and users see the connected sources appear directly in the Files tab and file picker when attaching files to records.

In short, Files Connect extends Salesforce Files into an enterprise content hub — where teams can collaborate across multiple storage systems, without ever leaving Salesforce.

For setup and supported systems, see:[ Ultimate Guide to Salesforce SharePoint Integration](https://www.cloudfiles.io/blog/the-ultimate-guide-to-salesforce-sharepoint-integration#what-is-files-connect)

## Working with Salesforce Files: A Complete Front-End Walkthrough

Salesforce Files looks simple at first glance: an Upload button, a Files related list, and a File Details screen. But every click you make runs through a sophisticated engine of versions, visibility, and links. This section walks through the Lightning experience from a user’s point of view, while quietly pointing to what’s happening under the hood - so you can use Files confidently and troubleshoot like an admin.

### **1. Upload from anywhere**

The Upload Files button appears almost everywhere in Salesforce - on record pages, in the global Files tab, and inside Chatter posts. When you upload a file:

- Salesforce immediately creates a **ContentVersion** record for the binary file data.
- If this is the first upload of that file, it also creates a **ContentDocument**, which becomes the file’s master record.
- If you’re uploading it from a record (say, an Opportunity), Salesforce links it to that record using **ContentDocumentLink**.

Each file can be up to **2 GB**, and you can upload multiple at once. If you upload a file with the same name as an existing one, Salesforce doesn’t overwrite it - it adds a [new version](https://help.salesforce.com/s/articleView?id=experience.collab_files_versioning.htm&type=5) of the same file, keeping your previous versions intact.

### 2. The File Details Page

Clicking on a file’s name opens the [File Details page](https://help.salesforce.com/s/articleView?id=experience.collab_files_previewing.htm&type=5), which is essentially Salesforce’s built-in file manager. This is where most file-related actions take place.

| **Feature** | **Description** | **What Happens Behind the Scenes** |
|---|---|---|
| **Preview** | Opens the file in a built-in viewer (supports 300+ file types) | Fetches the latest ContentVersion record for viewing |
| **Download** | Saves the current file to your system | Retrieves binary data from VersionData in ContentVersion |
| **Share** | Lets you share the file with users, groups, or records | Creates or updates ContentDocumentLink records |
| **Follow** | Subscribes you to file updates | Adds the file to your “Followed Files” feed |
| **Public Link** (if enabled) | Generates an external sharing link | Creates a ContentDistribution record with URL and expiry settings |
| **Upload New Version** | Replaces the file content with a new one | Creates a new ContentVersion, marks it as IsLatest = TRUE |
| **Edit Details** | Change file name, description, or owner | Updates metadata on the ContentDocument record |
| **View File Versions** | Lists all versions with timestamps and authors | Queries all ContentVersion records tied to the same document |
| **Delete File** | Removes the file (only if you own it or have rights) | Deletes the ContentDocument, all versions, and related links |

This page gives you a complete picture of a file’s lifecycle - who owns it, where it’s shared, and how it has evolved over time.

### 3. The Files Related List

On an Opportunity, Account, Case, or any custom record, the **Files** related list shows the documents that matter for that record. You’ll see the file name, owner, last modified date, and quick actions like **Preview**, **Download**, and [**Remove**](https://help.salesforce.com/s/articleView?id=experience.collab_files_remove_from_record.htm&type=5).

“Remove” is gentle: it only unlinks the file from this record. The file still exists (and may remain linked to other records or your Files tab). Use “Remove” when you’re tidying a record, not retiring a document.

**Behind the scenes:** “Remove” deletes just the **ContentDocumentLink** for that record. Nothing else is touched.

### **4. Managing** [Sharing and Access](https://help.salesforce.com/s/articleView?id=platform.managing_the_sharing_model.htm&type=5)

When you click ‘**Share’** and you’ll see three practical paths:

- **Share with people or groups** when you want targeted access.
- **Attach to additional records** when the same file should appear in multiple places (Account + Opportunity + Case) without duplication.
- **Create a **[**public link**](https://help.salesforce.com/s/articleView?id=experience.collab_files_sharing_via_link.htm&type=5) (if enabled) to collaborate outside the org, with optional expiry and download controls.

When you share a file in Salesforce, each action creates or updates a **ContentDocumentLink** (for internal sharing) or a **ContentDistribution** (for public links). You can choose the **Access Level** ‘Viewer’* or ‘*Collaborator’* - right from the UI, but the **Visibility** field works a bit differently. It’s managed automatically by Salesforce rather than being editable in the “Share” dialog.

The platform decides the [**Visibility**](https://help.salesforce.com/s/articleView?id=platform.security_sharing_users.htm&type=5) value based on context: files attached to records default to *AllUsers*, uploads made directly in the Files tab default to *SharedUsers* (visible only to the owner), and files shared through Experience Cloud sites are automatically set to *InternalUsers* or *AllUsers*, depending on site configuration. This field is intentionally hidden in the UI because it’s tightly linked to record-level security and user type (internal vs. community).

If you ever need to override or inspect these settings, you’ll have to use the **API, Apex**, or tools like **Data Loader** - the only ways to explicitly query or modify the Visibility field. This design ensures that Salesforce maintains consistent, secure file access behavior across different sharing contexts.

| **Visibility Option** | **Who Can See the File** | **Typical Use Case** |
|---|---|---|
| **AllUsers** | Everyone with record access | Contracts or sales proposals |
| **InternalUsers** | Only employees | Internal docs, policies |
| **SharedUsers** | Only directly shared users | Confidential files or partner docs |

**External Sharing & Tracking**

When you enable public links, Salesforce uses **ContentDistribution** to manage:

- Public URLs
- Access expiration
- Download permissions
- Engagement metrics via **ContentDistributionView**
- Admins can disable or restrict public link generation in Setup for compliance.

### **6. Working with Versions**

Click **View File Versions** to see your document’s [full history](https://help.salesforce.com/s/articleView?id=experience.collab_files_history.htm&type=5#:~:text=file.%20View%20the-,Version%20History%20list,-to%20see%20all). Each line represents a **ContentVersion** with details like:

- Version number (V1, V2, V3…)
- Uploaded by (user)
- Date and size
- Comments (if added)

*
Each entry corresponds to a ContentVersion record. Salesforce automatically marks the most recent one as ‘IsLatest = TRUE’. You can preview or download older versions, but only the latest version appears in record views.

### **7. Managing file actions - Remove, Replace, or Delete**

Once you start working with versions, it’s easy to confuse removing*, *replacing,* and [deleting](https://help.salesforce.com/s/articleView?id=experience.collab_files_deleting.htm&type=5) a file. They all change what you see on screen - but each one acts at a different level of the file model.

| **Action** | **When to use it** | **Effect** | **Behind the Scenes** |
|---|---|---|---|
| **Remove from record** | When a file no longer belongs on a particular record | Unlinks the file from that record only | Deletes the ContentDocumentLink for that record |
| **Replace** | When uploading an updated draft or final version | Adds a new version under the same file | Inserts a new ContentVersion and marks it as latest |
| **Delete** | When the file should disappear everywhere | Removes the file and all its history | Deletes the ContentDocument, all ContentVersion entries, and all links |

Keeping this mental model prevents accidental data loss and keeps your library organized. If you manage shared files across multiple teams, Replace should be your default action - it keeps history intact and avoids creating duplicate documents.

### **8. Reports and Monitoring**

Admins can create **File and Content Reports** to monitor file activity, owners, and storage usage.

You can report on:

- File size, type, and owner (from **ContentDocument**)
- Upload history (from **ContentVersion**)
- Record linkage (from **ContentDocumentLink**)
- External link usage (from **ContentDistribution**)

These reports help identify heavy file users, shared assets, and potential storage optimization opportunities.

### **9. File Limits & Storage Management**

Each file can be **up to 2 GB** in size. All file content (binary data in ContentVersion.VersionData) counts toward **File Storage**, not **Data Storage**.

| **Storage Type** | **Includes** | **Used For** |
|---|---|---|
| **File Storage** | Files, Attachments, ContentVersions | Document management |
| **Data Storage** | Records (Accounts, Contacts, etc.) | Core CRM data |

Typical Salesforce storage pricing: **~$5 per GB/month**.

To manage space:

- **Delete or prune older versions** to reduce redundant ContentVersions.
- **Offload heavy assets** (PDF libraries, videos, proposals, scans) to external storage like SharePoint, Google Drive, or OneDrive.
- **Integrate CloudFiles**: Connects Salesforce to external storage, keeping files accessible in Salesforce while reducing internal storage use.

For a deeper breakdown of costs and reduction strategies, check out CloudFiles’ guide on

[**Reducing Salesforce File Storage Costs**](https://www.cloudfiles.io/blog/salesforce-file-storage-cost#how-to-reduce-the-file-storage-cost-in-salesforce)

### **In Summary**

Salesforce Files is more than an upload utility - it’s a versioned, shareable, and auditable file system built for enterprise collaboration. Understanding the link between front-end actions and backend objects like **ContentDocument**, **ContentVersion**, and **ContentDocumentLink** helps admins and users manage files effectively, prevent duplication, and maintain compliance - all without leaving Salesforce.

## Working with Salesforce Files Programmatically (Apex & APIs)

So far, we’ve looked at how Salesforce Files behave in the UI - uploading, versioning, and sharing.But what if you want to automate it? Or [integrate Salesforce Files](https://www.cloudfiles.io/blog/the-ultimate-guide-to-salesforce-sharepoint-integration?ref=cloudfiles.ghost.io#why-is-salesforce-sharepoint-integration-required:~:text=begin%20our%20journey.-,Why%20is%20Salesforce%20SharePoint%20Integration%20required%3F,-In%20this%20section) with your custom apps, document generators, or external repositories like SharePoint or Drive?

That’s where **Apex** and **Salesforce APIs** come in.This section walks through how developers can work with Salesforce Files behind the scenes - using the same three core objects: **ContentVersion**, **ContentDocument**, and **ContentDocumentLink** — and how they map to every file action that happens in the UI.

### **1. The Core File Model**

Here’s how every file is structured behind the scenes:

| Object | Description | Common Fields |
|---|---|---|
| [**ContentDocument**](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_contentdocument.htm) | Master record for a file. Represents the logical file and its metadata. | Id, Title, FileType, OwnerId |
| [**ContentVersion**](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_contentversion.htm?utm_source=chatgpt.com) | Holds the actual file data and version information. | Id, ContentDocumentId, VersionData, Title, IsLatest |
| [**ContentDocumentLink**](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_contentdocumentlink.htm?utm_source=chatgpt.com) | Connects a file to a record, user, or group. | ContentDocumentId, LinkedEntityId, ShareType, Visibility |

Whenever a user uploads or replaces a file:

1. Salesforce creates a **ContentVersion**.
2. If it’s new, it creates a **ContentDocument**.
3. It links the file using **ContentDocumentLink**.

That’s the pattern you’ll use in code too:

Upload → Version → Link

### **2. Uploading and Linking Files with Apex**

Apex gives you complete control over how files are created, versioned, or attached to records.

### Example 1: Upload a new file and auto-link to a record

ContentVersion cv = new ContentVersion(**    Title = 'Signed_Agreement.pdf',
    PathOnClient = 'Signed_Agreement.pdf',
    VersionData = Blob.valueOf('BinaryFileContentHere'),
    FirstPublishLocationId = '006XXXXXXXXXXXX' // Opportunity Id
);
insert cv;

This single DML call:

- Creates the ContentVersion
- Auto-generates a ContentDocument
- Links it to the Opportunity record

Salesforce Docs: Upload Files via Apex → [relevant read](https://www.apexhours.com/file-upload-with-preview-in-lwc-apex/)

### Example 2: Add a new version of an existing file

ContentVersion newVersion = new ContentVersion(
    ContentDocumentId = '069XXXXXXXXXXXX', // Existing file
    Title = 'Signed_Agreement_v2.pdf',
    PathOnClient = 'Signed_Agreement.pdf',
    VersionData = Blob.valueOf('UpdatedBinaryContent')
);
insert newVersion;

Every new upload adds a ContentVersion** but retains the same **ContentDocumentId**, ensuring seamless version history.

Docs: File Versioning → [official guide](https://help.salesforce.com/s/articleView?id=experience.collab_files_versioning.htm&type=5)

### Example 3: Link an existing file to another record

ContentDocumentLink link = new ContentDocumentLink(**    ContentDocumentId = '069XXXXXXXXXXXX',
    LinkedEntityId   = '001YYYYYYYYYYYY', // Account Id
    ShareType        = 'V',               // V = Viewer, C = Collaborator
    Visibility       = 'AllUsers'
);
insert link;

Official [Docs: ContentDocumentLink](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_contentdocumentlink.htm?utm_source=chatgpt.com)

### Example 4: Retrieve and download a file from Apex

ContentVersion cv = [
    SELECT Id, Title, VersionData
    FROM ContentVersion
    WHERE Id = :versionId
];
Blob fileBlob = cv.VersionData;

// Convert to Base64 or attach to an outbound email
Messaging.EmailFileAttachment attachment = new Messaging.EmailFileAttachment();
attachment.setFileName(cv.Title);
attachment.setBody(fileBlob);

💡 Note:** Apex heap size is limited (~6 MB). For large files, use REST API.

### **3. Working with Files via the REST API**

For integrations, middleware, or web apps, the [Salesforce REST API](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_what_is_rest_api.htm) is the best way to manage files.

### Example 1: Upload a new file

curl <https://yourInstance.salesforce.com/services/data/v65.0/sobjects/ContentVersion> \\**  -H "Authorization: Bearer <ACCESS_TOKEN>" \\
  -H "Content-Type: multipart/form-data" \\
  -F 'entity_content={"Title":"Proposal.pdf","PathOnClient":"Proposal.pdf","FirstPublishLocationId":"006XXXXXXXXXXXX"};type=application/json' \\
  -F "VersionData=@/path/to/Proposal.pdf"

This creates both ContentVersion and ContentDocument, and links it automatically.

REST API – Upload Files →[ official document](https://developer.salesforce.com/docs/atlas.en-us.uiapi.meta/uiapi/ui_api_features_records_content_document.htm)

### Example 2: Add a new version

curl <https://yourInstance.salesforce.com/services/data/v65.0/sobjects/ContentVersion> \\
  -H "Authorization: Bearer <ACCESS_TOKEN>" \\
  -H "Content-Type: multipart/form-data" \\
  -F 'entity_content={"ContentDocumentId":"069XXXXXXXXXXXX","Title":"Proposal_v2.pdf"};type=application/json' \\
  -F "VersionData=@/path/to/Proposal_v2.pdf"

### Example 3: Link file to another record

curl <https://yourInstance.salesforce.com/services/data/v65.0/sobjects/ContentDocumentLink> \\
  -H "Authorization: Bearer <ACCESS_TOKEN>" \\
  -H "Content-Type: application/json" \\
  -d '{"ContentDocumentId":"069XXXXXXXXXXXX","LinkedEntityId":"001YYYYYYYYYYYY","ShareType":"V","Visibility":"AllUsers"}'

### Example 4: Download file content

curl -L <https://yourInstance.salesforce.com/services/data/v65.0/sobjects/ContentVersion/068XXXXXXXXXXXX/VersionData> \\
  -H "Authorization: Bearer <ACCESS_TOKEN>" -o Proposal.pdf

Download Files → [official document](https://help.salesforce.com/s/articleView?id=000381137&type=1)

### **4. Composite API - Create and Link in One Call**

If you want to create and link a file atomically, use [Salesforce Composite API](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_composite.htm).

It lets you upload (ContentVersion) and immediately link (ContentDocumentLink) within a single request.

### **5. Using Files in Automation (Flow & Triggers)**

You can trigger file uploads or links via:

- **Flows:** Using “Create Records” for ContentVersion
- **Apex Triggers:** Example – after generating a quote PDF
- **Process Builder (Legacy):** To call Apex for file actions

Example trigger: Automatically attach a contract when an Opportunity closes.

trigger AttachContract on Opportunity (after update) {
    for (Opportunity opp : Trigger.new) {
        if (opp.StageName == 'Closed Won' && Trigger.oldMap.get(opp.Id).StageName != 'Closed Won') {
            ContentVersion file = new ContentVersion(
                Title = opp.Name + '_Contract.pdf',
                PathOnClient = opp.Name + '_Contract.pdf',
                VersionData = Blob.valueOf('Auto-generated contract content'),
                FirstPublishLocationId = opp.Id
            );
            insert file;
        }
    }
}

Docs: [Files in Flow and Apex](https://help.salesforce.com/s/articleView?id=platform.flow_ref_elements_screencmp_fileupload.htm&type=5)

### **6. Integrating Salesforce Files with External Systems**

Files can sync or live in external storage like SharePoint**, **Google Drive**, or **OneDrive** using Files Connect.

However, third-party connectors like **CloudFiles** go further - letting you:

- Store large files externally
- Access them natively inside Salesforce
- Preserve versioning and visibility (see: [How CloudFiles Enhances Salesforce Files](https://www.cloudfiles.io/blog/salesforce-files-vs-notes-and-attachments-complete-guide#how-cloudfiles-extends-the-value-of-migration:~:text=automation%20and%20space-,Salesforce%20Files%20vs.%20Salesforce%20Files%20%2B%20CloudFiles,-See%20how%20CloudFiles))

### **7. File Access & Visibility in APIs**

APIs follow the same visibility rules:

- Visibility = AllUsers, InternalUsers, or SharedUsers
- ShareType = V (Viewer) or C (Collaborator)
- External sharing is managed through [ContentDistribution](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_contentdistribution.htm)

If a user can’t see a file via API, check both:

1. Their record access
2. The file’s ContentDocumentLink.Visibility

### 8. Troubleshooting Common Issues

| Problem | Likely Cause | Fix |
|---|---|---|
| File not visible on record | No ContentDocumentLink created | Create or check the link |
| File upload fails via Apex | File > 6 MB (heap limit) | Use REST API |
| File not visible to users | Visibility = InternalUsers | Change to AllUsers |
| Duplicate files appearing | Each version uses same Title | Query by ContentDocumentId |
| “MALFORMED_MULTIPART_REQUEST” error | Incorrect multipart format | Follow REST docs example |

### **In Short**

Working with Salesforce Files programmatically boils down to mastering three objects —**ContentVersion**, **ContentDocument**, and **ContentDocumentLink** - and choosing the right interface (Apex, REST, or Flow) for your automation or integration. Once you’ve nailed that, managing documents in Salesforce becomes just as flexible as any other data model - whether you’re uploading PDFs, auto-linking reports, or integrating with CloudFiles for external storage.

### Summary

Salesforce Files brings structure and intelligence to something as simple as file storage. From uploads and versioning to automation and APIs, every click and line of code follows a well-architected model that balances usability with control. Understanding how ContentDocument, ContentVersion, and ContentDocumentLink interact across the UI and backend helps admins, developers, and users alike manage documents more efficiently - without duplication, confusion, or chaos. Whether you’re building automations, integrating with external platforms, or just keeping your records clean, Salesforce Files ensures every document stays connected, compliant, and ready when you need it most.

## FAQs & Troubleshooting for Salesforce Files

### Why can’t users see a file I uploaded to a record?

The most common visibility issue happens when Salesforce doesn’t create (or creates a restricted) **ContentDocumentLink**. Even though a file is uploaded, it won’t appear for others unless the link exists with appropriate access. Simply sharing the file again using **Share → Attach to Record** usually fixes it. For automated solutions, flows and Apex can set Visibility = AllUsers when files are added to records.

### Why do I see duplicates of the same file?

Salesforce doesn’t duplicate storage when you upload **a new version** — it duplicates only when users **upload the same file separately instead of replacing it**. Teaching users to click **Upload New Version** instead of **Upload File** prevents clutter and storage waste. Admins can track duplicate uploads through content reports.

### What really happens when I Remove, Replace, or Delete a file?

- **Remove from Record** only detaches the file from that one record — the file stays elsewhere.
- **Upload New Version / Replace** keeps one master file and adds a new version everyone can access.
- **Delete File** removes the file everywhere and deletes all its versions. Understanding this distinction helps prevent accidental data loss in collaboration-heavy teams.

### Why don’t I see the “Generate Public Link” option?

Public links are controlled by an org-level setting. When disabled, the button doesn’t appear. Industries with strict compliance rules (finance, healthcare, etc.) often turn this off. If enabled, Salesforce creates a **ContentDistribution** record each time — adding access expiry and download logging.

### File upload vs storage — what counts where?

All files — including PDFs, images, spreadsheets, and even ContentVersions — count toward **File Storage**, not Data Storage. Large orgs run out of File Storage much faster than Data Storage. Reports can help identify big contributors; “old version cleanup” and offloading heavy media are the fastest cost-savers.

### Why can’t I upload large files via Apex?

Apex can’t handle large binary data because of heap limits. REST APIs are the only scalable method for large uploads (especially video, manuals, contracts, or scanned PDFs). Automations that rely on Apex should be aware of this before enabling file upload workflows.

### How do I attach the same file to multiple records without reuploading?

A single file can appear across Accounts, Opportunities, Cases, etc. without duplicating storage. In the UI, use **Share → Attach to Record**. In automation, simply create new **ContentDocumentLink** records using the same ContentDocumentId. This is the core reason Salesforce Files scale better than Attachments.

### Files uploaded from Experience Cloud aren’t visible internally. Why?

Files uploaded by community/portal users are often marked by Salesforce as **SharedUsers** or **InternalUsers**, which can prevent visibility for internal teams. Visibility isn’t editable via the “Share” dialog, so API/Flow automations are the best place to enforce AllUsers when Experience Cloud is involved.

### What’s the old “Libraries” thing doing here, isn’t it deprecated?

Libraries (ContentWorkspace) originate from CRM Content and still exist for legacy orgs, especially marketing teams who stored assets this way before Salesforce Files became standard. They’re not required today, but they won’t be retired — many enterprises still rely on them for structured file governance.

### Can I track external viewers and download activity?

Yes. Whenever a public link is shared, Salesforce logs engagement using **ContentDistribution** and **ContentDistributionView**. Reports can show who opened, downloaded, and when. This is useful for sales collateral, proposals, contracts, and document compliance workflows.

## **Further Reading & References**

If you'd like to go deeper into Salesforce Files architecture, APIs, and integration strategies, the resources below build on the concepts covered in this blog:

### 📌 **CloudFiles Knowledge Hub - Recommended Reads**

- [**Salesforce Files vs Documents: The Ultimate Guide for Admins & Architects** ](https://www.cloudfiles.io/blog/salesforce-files-vs-documents-the-ultimate-guide-for-admins-architects)— A full breakdown of object differences, limitations, and why Salesforce standardized on the ContentDocument model for scalability and sharing control.
- [**Salesforce Files vs Notes & Attachments Explained**](https://www.cloudfiles.io/blog/salesforce-files-vs-notes-and-attachments-complete-guide) — Ideal for legacy orgs transitioning from Attachments and Notes to Salesforce Files, with practical migration considerations.
- [**The Ultimate Guide to Salesforce SharePoint Integration**](https://www.cloudfiles.io/blog/the-ultimate-guide-to-salesforce-sharepoint-integration) — Covers secure external file storage with bi-directional sync and permission mapping.
- [**Google Drive, OneDrive & Dropbox Integrations for Salesforce Compared**](https://www.cloudfiles.io/blog/salesforce-google-drive-integration-made-easy) — Deep dive into cloud storage use cases for sales, service, and partner portals.

### **📌 Salesforce Official Documentation**

If you want to go deeper into the internal objects, APIs, and architecture behind Salesforce Files, these are the most relevant official guides:

- [**ContentVersion Object Reference**](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_contentversion.htm) — Complete field-level documentation, including VersionData, previews, publishing behaviour, and API constraints.
- [**ContentDocument Object Reference** ](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_contentdocument.htm)— Master record of a file including ownership, title, sharing controls, and lifecycle metadata.
- [**ContentDocumentLink Object Reference**](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_contentdocumentlink.htm) — Schema and usage for linking a single file to multiple records without duplication.
- [**Salesforce Files Developer Guide (Apex Integration)**](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_salesforce_files.htm) — How to create, update, and retrieve Files through Apex, including sample code and best practices.
- [**Salesforce Files End-User Help Article** ](https://help.salesforce.com/s/articleView?id=experience.collab_salesforce_files_parent.htm&type=5)— High-level overview of functionality, sharing, sync, and user adoption of Files across the org.
