Dynamic Contract Generation in Salesforce: Beyond Filling an Existing PDF

Populating a fixed PDF contract with Salesforce data works until a clause becomes conditional. Here is why the approach breaks, what dynamic really requires, and the one case where filling a PDF is still correct.
The request sounds simple. "We have a contract PDF. Populate it with Salesforce data automatically." So you look for a way to inject data into the existing PDF: form fields, a coordinate overlay, some Apex. It works for the first version. Then legal adds a clause that applies only to certain deals, a schedule needs to disappear when a term is zero, and the approach starts to creak.
The problem is not your implementation. It is that a static PDF is the wrong source of truth for a document whose content is conditional.
Why filling a fixed PDF breaks down
There are three common ways to populate a fixed PDF, and they share a ceiling.
AcroForm form fields. If the PDF has named fields, you can set their values. But a form field is a fixed box at a fixed position. It cannot grow a table, repeat a row per line item, or remove a clause. The layout is frozen at design time, which is fine for data and fatal for structure.
Coordinate overlays. Drawing text at x and y positions works right up until the document reflows. A longer address, an extra signatory, one more line of a description, and every coordinate below it is now wrong. This is the most brittle option available, and it fails silently: the PDF still generates, it is just incorrect.
Apex or Visualforce regeneration. You can rebuild the contract in code, and since Spring '26 you can do it with Blob.toPdf() without a Visualforce page. But you now own that code, its tests, and its deployment for a legal document that changes often, and the output still runs through a rendering service with documented formatting constraints. Every clause change becomes a developer task.
What all three lack is conditional structure: clauses that appear only when they apply, tables that size to the data, sections that close up when empty. It is the same show-and-hide problem that shows up in quote PDFs, except that a contract is largely made of those conditions. You are not adding conditional logic to a contract as a nicety. Conditionality is what a contract is.
What "dynamic" should actually mean
For a contract, the bar is:
- Conditional clauses. A section renders only when its condition is met: jurisdiction, product, term length, deal size.
- Repeating and nested data. Schedules of deliverables, line items, signatories, each sized to the record rather than to the template.
- Computed values. Totals, effective dates, term math, derived at generation rather than typed in.
- Changeable without a developer. Legal adjusts wording without a deployment or a PDF editor.
- Deterministic and inspectable. The same inputs always produce the same document, and you can read what the template says rather than guessing from a binary.
A frozen PDF offers none of these. That is the mismatch, and no amount of merge cleverness resolves it.
Making the document itself dynamic
Instead of fighting a static file, generate the contract from a structural template where conditions are first-class. This is where ZeroExport fits.
Step 1: Bind to the record and its children. The Contract or Opportunity plus its related data: products, signatories, schedules. Nested child data is supported up to four levels below the primary object, each level scoped to its parent, so a schedule of deliverables under each service line stays under that line.
Step 2: Express clauses conditionally. Each clause or section carries the condition under which it appears, built from AND, OR, or custom logic, and reusable across templates as a named global condition. Conditions cascade, so hiding a clause hides its heading and everything nested inside it. A deal that does not trigger a clause simply does not render it: no blank space, no manual deletion, no second template for the variant.
One detail that matters for legal documents specifically: conditions are evaluated fail-closed. If a condition cannot be resolved, the section does not render rather than rendering by default. For a contract, the safe failure is an absent clause you notice, not an unintended clause you do not.
Step 3: Repeat and compute declaratively. Schedules and line tables repeat per record, with repeating boundaries detected from the structure rather than hand-marked. Aggregates re-scope inside a repeat, so a total under a schedule covers that schedule's own rows.
Step 4: Check readiness before anyone generates. Mark which fields the contract requires, and every record shows a readiness status before generation, naming the specific fields that are missing or inaccessible under field-level security. For a document heading to a counterparty, finding the gap on the record beats finding it in a signed PDF. More on that in document readiness.
Step 5: Generate, then route to signature. A button, a Flow, or an Agentforce action produces the PDF, which you hand to your e-signature step. Complex documents route to an asynchronous job and return a status with a job ID rather than an immediate file link, so build the Flow to handle a queued result.
Governance limits, stated plainly
Contracts invite governance questions, so here is what exists and what does not. Per-record overrides let one deal carry different content without spawning another template, and overrides are controlled by permission and at the record level, with a record of who edited and when. There is no per-section locking, meaning you cannot mark clause 7 as immutable while leaving the rest editable, and there is no field-level diff audit of what changed inside an override. If your legal process depends on locking specific clauses, that control does not exist here today and you should not plan around it.
Reusable blocks, meaning one clause defined once and propagated across many templates, are on the roadmap rather than shipped. Today the model is one template per contract family with conditional sections inside it, which collapses variants but does not yet share a clause across separate templates.
The honest exception: when you must fill a fixed PDF
If the PDF is not yours to redesign, filling its form fields is the correct approach and structural document generation is the wrong tool. A government form, a regulator's fixed template, a counterparty's paper on their letterhead: in each case the layout is the requirement, and reproducing it structurally is both pointless and risky.
The distinction is ownership. Structural generation is for documents you own and control: your contracts, statements of work, order forms, and proposals. Filling form fields is for documents someone else owns and you must return unchanged. Know which situation you are in before you pick a tool, because the two problems look similar and have opposite answers.
FAQ
Can I populate an existing PDF contract with Salesforce data?
Yes, if the PDF has AcroForm form fields, you can set their values. The limitation is that form fields are fixed boxes: they cannot grow a table, repeat a row per line item, or remove a clause. That works for a fixed form and fails as soon as the document's content varies by deal.
Why do coordinate overlays break on PDF contracts?
Because they place text at fixed x and y positions with no relationship to the content around it. As soon as anything reflows, a longer address or an extra signatory, every coordinate below it is wrong. It fails silently too: the PDF still generates, it is simply incorrect.
How do I add conditional clauses to a Salesforce contract?
Put the condition on the section that holds the clause, in a document tool that supports section-level conditional visibility. The clause and its heading then appear only when the condition is met, and one template covers the variants instead of maintaining a separate template per jurisdiction or product.
Does dynamic contract generation replace e-signature?
No. Document generation produces the contract; an e-signature product routes and executes it. They are separate steps in the same flow, and a generated PDF hands off to your existing signature process.
When should I fill an existing PDF instead of generating one?
When you do not own the document. Government forms, regulator templates, and a counterparty's paper must be returned in their original layout, so filling form fields is correct. Generate structurally only for documents you own and control.
Can I lock specific clauses so users cannot edit them?
Not in ZeroExport today. Override permissions are controlled at the permission and record level, with a record of who edited and when, but there is no per-section locking and no field-level diff audit. If clause-level immutability is a hard requirement for your legal process, verify it explicitly against any tool you evaluate.
Related Reading
- How to Generate a PDF From Any Salesforce Object, Standard or Custom
- Live Document Editing in Salesforce: No Admin Required
- The Hidden Cost of Finding Out a Document Was Broken After You Sent It
- Replace Fragile Word Templates with Logic-Driven Documents
- Why Native Salesforce Document Generation Matters for Compliance
Ready to try ZeroExport?
Start generating documents directly in your Salesforce org. No integrations, no setup overhead, no complexity.