Content Version
A Content Version in Salesforce (ContentVersion in the API) is the child object in the Salesforce Files framework that holds the actual binary content for one specific version of a Content Document.
Definition
A Content Version in Salesforce (ContentVersion in the API) is the child object in the Salesforce Files framework that holds the actual binary content for one specific version of a Content Document. Each Content Version record contains the file binary data in the VersionData field (stored base64-encoded over the API), along with metadata like Title, FileType, FileExtension, ContentSize, VersionNumber, IsLatest flag, ReasonForChange (free-text explanation), and a parent ContentDocumentId pointing back to the persistent Content Document parent.
When a file is first uploaded, Salesforce creates one Content Version record (the initial version, VersionNumber = 1, IsLatest = true) plus its parent Content Document. Subsequent uploads under the same Content Document insert new Content Version records that increment VersionNumber and flip IsLatest on the prior version. Apex and API code that uploads files always inserts Content Version, not Content Document; the platform automatically creates the Content Document parent and the initial Content Document Link to the inserting user.
How Content Version works in the Salesforce Files framework
The role of Content Version inside the Files model
The Salesforce Files framework has three objects working together. Content Document is the persistent parent that represents the file. Content Version holds the actual binary and per-version metadata. Content Document Link connects the Content Document to whatever records the file is attached to. Content Version is where the file payload actually lives; everything else is structural metadata around it.
Key fields on a Content Version record
The VersionData field holds the binary content. Title is the display name. FileType (high-level type) and FileExtension differ in granularity. ContentSize is the size in bytes. VersionNumber increments per version. IsLatest is a boolean that flips to true on the newest version and to false on every prior version when a new one uploads. ReasonForChange is a free-text field for users to explain what changed in this version. ContentDocumentId is the foreign key to the parent Content Document.
How IsLatest and LatestPublishedVersionId stay in sync
Two pointers exist for the same concept: IsLatest on Content Version (true on one version per Content Document) and LatestPublishedVersionId on Content Document (foreign key to that one version). Salesforce keeps them consistent automatically. When a new Content Version inserts, IsLatest flips on the new record, IsLatest flips off the old, and LatestPublishedVersionId updates. The two are redundant by design so queries can target either side without a join.
Inserting a Content Version through Apex
ContentVersion cv = new ContentVersion(Title = My File, PathOnClient = file.pdf, VersionData = bodyBytes); insert cv. This creates a new Content Document automatically (because ContentDocumentId is not set), a new Content Version, and a Content Document Link to the inserting user. The new Content Document Id is on cv.ContentDocumentId after the insert.
Inserting a new version of an existing Content Document
To add a version, set ContentDocumentId on the new Content Version before insert. Example: ContentVersion cv = new ContentVersion(ContentDocumentId = existingDocId, Title = My File v2, PathOnClient = file.pdf, VersionData = newBodyBytes, ReasonForChange = Updated logo); insert cv. Salesforce flips IsLatest on the prior version, increments VersionNumber, and updates the parent Content Document LatestPublishedVersionId.
VersionData limits and the chunked upload pattern
VersionData is a Blob field with a single-record size cap (currently 2 GB through the API, with smaller limits depending on entry point). For files near or above 38 MB through standard Apex calls, use the Files REST API chunked upload, which streams the file in pieces and assembles them server-side. The chunked API also supports resumable uploads, which the standard insert does not.
Querying Content Version: the latest vs all versions
SELECT Id, Title, VersionData, VersionNumber FROM ContentVersion WHERE ContentDocumentId = :docId. This returns every version. To get only the current version, add WHERE IsLatest = true. To get the current version for many documents at once, query LatestPublishedVersionId on Content Document and join. Different code paths use different patterns; pick the one that fits the use case.
How to work with Content Version programmatically
Most Content Version work is API or Apex driven. The UI handles version uploads transparently, but for developers integrating files into custom flows, knowing the insert patterns matters.
- Upload a new file through Apex
Create a ContentVersion record with Title, PathOnClient, and VersionData fields. Insert it. Salesforce creates the Content Document and the initial Content Document Link automatically.
- Link the file to a parent record
After insert, query ContentDocumentId from the inserted ContentVersion. Create a ContentDocumentLink with ContentDocumentId, LinkedEntityId (the parent record), and ShareType (V for Viewer, C for Collaborator, I for Inferred from sharing rules).
- Upload a new version of an existing file
Insert a new ContentVersion with ContentDocumentId set to the existing Content Document Id. Optionally set ReasonForChange to explain what changed.
- Read a specific version
SELECT Id, Title, VersionData FROM ContentVersion WHERE Id = :versionId. The VersionData blob can be passed to a webhook or written to disk in a callout.
- List all versions of a document
SELECT VersionNumber, Title, ContentSize, CreatedDate, ReasonForChange FROM ContentVersion WHERE ContentDocumentId = :docId ORDER BY VersionNumber DESC. Useful for building a version-history component.
- Delete a specific version
Delete the ContentVersion record. Salesforce updates IsLatest and LatestPublishedVersionId on the parent automatically if the latest version is deleted. Do not delete the only version; that orphans the Content Document.
- VersionData over the API is base64-encoded. Apex Blob fields are decoded automatically, but raw REST callers need to handle encoding.
- Inserting a Content Version without ContentDocumentId creates a new Content Document, not a new version. Forgetting to set the parent Id is a common source of unintended Content Document proliferation.
- Single-record file size cap is 2 GB through the chunked API, with lower limits for standard insert (38 MB pre-2026, larger in modern releases). Check the latest limits in the Files REST API docs.
- Deleting the only Content Version on a Content Document leaves an orphan Content Document with no payload. Salesforce does not auto-clean this; delete the parent Content Document instead.
- Content Version size is counted against your org file storage. Frequent versioning of large files can exhaust storage quickly; have a retention policy.
Trust & references
Cross-checked against the following references.
- ContentVersion Object ReferenceSalesforce Developers
- Salesforce Files OverviewSalesforce Help
Straight from the source - Salesforce's reference material on Content Version.
- Files REST APISalesforce Developers
- ContentDocument Object ReferenceSalesforce Developers
Hands-on resources to go deeper on Content Version.
About the Author
Dipojjal Chakrabarti is a B2C Solution Architect with 29 Salesforce certifications and over 13 years in the Salesforce ecosystem. He runs salesforcedictionary.com to help admins, developers, architects, and cert/interview candidates sharpen their fundamentals. More about Dipojjal.
Discussion
Loading discussion…