Salesforce Documents
Attach Generated PDFs Back to Salesforce: Naming, Versioning, and Files API
- Salesforce Files
- ContentVersion
- document automation
- Salesforce admin
- DocForge
The mess that arrives in six months
Without naming and versioning discipline, the Files tab on every Opportunity becomes a graveyard: Proposal.pdf, Proposal (1).pdf, Proposal-final.pdf, Proposal-FINAL-v2.pdf. Nobody can tell which was sent or signed. Audit takes hours, not minutes.
The fix is two decisions made on day one: a deterministic naming convention and explicit use of the Salesforce Files versioning model.
A naming convention that scales
- Pattern:
{record_type}-{record_number}-{template_code}-v{version}.pdf. - Example:
OPP-00042-PROPOSAL-v3.pdf. - Why: sortable, searchable, immediately understandable, never collides.
- Avoid: spaces, customer names in file names, "FINAL" labels, manual suffixes.
Files API model: ContentVersion vs Attachment
Salesforce has two attachment models:
- Attachments (legacy): simple but no versioning; avoid for new automation.
- ContentVersion + ContentDocument: versioning built in; preferred for any modern document automation.
Always write to ContentVersion. Same file name with a new version creates a new ContentVersion linked to the same ContentDocument—exactly what you want for "v2 of the proposal."
The minimum metadata to set per upload
- Title: the file name following the convention.
- VersionData: the PDF bytes.
- PathOnClient: the file name with extension.
- ContentDocumentId: link to the existing ContentDocument for versioning.
- FirstPublishLocationId: on first version, the Opportunity ID for sharing.
- Custom fields: template version, generator run ID, signer status.
Linking and sharing
Use ContentDocumentLink to attach to multiple records (Opportunity, Account, custom Document object). Set the right ShareType (V for viewer, C for collaborator, I for inferred) and Visibility (AllUsers, InternalUsers, SharedUsers) per use case.
Governor limits to design around
- ContentVersion inserts count against DML rows—batch large jobs.
- VersionData size limit per file (Salesforce-defined); compress before upload when possible.
- Heap size for large PDFs—stream rather than load fully into memory.
- Asynchronous patterns (Queueable, Batch Apex) for bulk operations.
What to log per generation
- Run ID, template version, mapping version.
- Source record IDs (Opportunity, Account, related objects).
- Output ContentDocument ID and version number.
- Timestamp and user.
- Status: success, partial, failure with reason.
Cleanup is part of the design
- Mark abandoned versions (draft never sent) for purge after N days.
- Never delete versions tied to signed documents—legal hold.
- Provide a search by template + status to find specific versions fast.
- Export and archive after closed-won/lost based on retention policy.
Automated attach is more than ContentDocumentLink
Uploading a PDF to Files is the easy part. Durable automation also sets filename convention, writes version metadata to custom fields, prevents duplicate attachments on Flow retry, and notifies downstream systems that the document exists.
Use idempotent keys: {OpportunityId}_{templateVersion}_{generationTimestamp} so a retried Flow does not create five identical PDFs named proposal.pdf.
Attachment automation layers
| Layer | Implementation | Failure if skipped |
|---|---|---|
| Generate | Invocable action / API | Empty attach |
| Name + path | Formula on Opportunity fields | Unsearchable Files clutter |
| Link record | ContentDocumentLink | Orphan file in library |
| Metadata stamp | Custom fields on Opportunity | No audit trail |
| Downstream notify | Platform event / webhook | ERP never sees doc |
Flow design patterns that survive retries
- Check custom field
Last_Proposal_Hash__cbefore generate—skip if input unchanged. - Store generation job ID; treat duplicate job ID as no-op.
- On failure, write error code to Opportunity—not silent rollback.
- Grant Files access via standard sharing, not "Modify All Data" service user.
- Archive superseded PDFs to subfolder instead of delete for legal retention.
Example: Stage 3 proposal on Opportunity update
Flow triggers when Stage moves to Proposal. Action generates PDF, names it OPP-2026-0142_Proposal_v3.pdf, links to Opportunity, sets Proposal_Generated_At__c, fires platform event ProposalReady. CPQ integration listens and unlocks send-for-signature button. Retry after transient timeout sees same job ID and exits without duplicate attach—Files tab stays clean.
Sharing rules and customer community visibility
Auto-attached PDFs inherit parent Opportunity sharing—verify partner community users cannot see draft proposals meant for direct customers only. Use separate subfolders or content document link visibility flags when Experience Cloud is in play.
Log which automation user owns the attach; audits ask who had access at generation time, not just who clicked send later.
Include file size in generation log—oversized proposals over 25 MB fail silently on some mobile email clients when reps forward Files links to customers.
Write integration tests that simulate Flow fault and retry paths—duplicate ContentDocumentLink records are the most common silent clutter on high-volume Opportunity records.
Alert when attach latency exceeds 60 seconds so admins catch governor-limit pressure before reps flood support.
Review high-volume Opportunities weekly so duplicate proposal attachments never clutter the Files tab unnoticed.
Document automation earns trust when ops owns the pipeline: weekly batch reviews, mapping change control, and a single owner who can explain every failed row to finance without opening three tools. Treat the generator like payroll—silent success, loud failures, zero mystery duplicates in numbering or filenames.
Where DocForge for Salesforce fits
DocForge for Salesforce writes generated PDFs to ContentVersion with deterministic naming, version control, generator metadata, and proper sharing—your Opportunity Files tab stays clean six months in. Sign in and inspect the file structure on a test record.
Related articles
Salesforce Documents
From Salesforce Opportunity to Branded PDF Proposal in One Click
The reliable way to turn Opportunity line items into a branded proposal PDF attached back to the record—without exporting to Word or pasting into PandaDoc.
Salesforce Documents
EU Invoices in Salesforce: ZUGFeRD & Factur-X Without Conga
How to produce compliant ZUGFeRD/Factur-X hybrid PDF/XML invoices straight from a Salesforce Opportunity—what the standards require and what most orgs get wrong.
Salesforce Documents
Replacing Conga Composer in Salesforce: When and How
Conga is powerful and expensive. The cases where it's still the right call—and the ones where a focused alternative ships faster, costs less, and reduces admin pain.