Skip to content
Simple Smooth Safe

DocGen: Dataverse document generation without a code release

Branded PDFs from your Dataverse records, through one API that your model-driven app, Power Automate, Code Apps and Power Pages can all call. Templates are configuration, and everything runs in your own Azure subscription.

€7,500 per production environment per year€625 a month equivalent, billed annually. Excl. VAT; implementation and Azure costs are additional.

See the finished documents

Two statements generated by DocGen: standard and credit balance. Sample data, anonymised branding.

Anonymised account statement generated by DocGen: firm letterhead, client address block, an invoice detail table, an unapplied-payments table, an aging summary, and a payment and remittance panel.
Account statement: open checks
The same statement template in its credit-balance variant, showing a negative net amount due and the credit-balance wording in place of the payment request.
Account statement: credit balance

In production today

12Legacy templates converted
Weeks → daysChange turnaround, before → after
0Compiled-code releases required per template change
A multi-office professional services firm, anonymised at its request. A named reference is available under NDA.

Changing templates: before and after

The same request, a line moved on an invoice, under compiled templating and under DocGen.

Today: Aspose Words and LINQ, compiled into the app
  • Client wants a line moved on an invoice
  • A platform consultant edits compiled C# templating code
  • 15–40 hours of build, test, and deploy per change
  • ~€4,750 average per change, billed T&M
  • Wait in the vendor's dev queue for a release
  • Aspose.Words OEM licence + annual support on top
With DocGen
  • Client wants a line moved on an invoice
  • Edit template.html (Handlebars) or a FetchXML dataset
  • Preview locally: npm run preview <code>
  • Seed by alternate-key upsert — no code release
  • Live in every channel that calls the API
  • One change per quarter included; beyond that, a fixed price you can approve without a scoping call

Compare the cost of template changes

The typical firm changes its documents about six times a year — a rebrand, a new remittance block, a regulatory line, a field the partners want moved. Under compiled templating, every one of those is a project. Here is what six changes a year cost.

Compiled templating, today
€28,500per year
  • 6 changes × ~€4,750 each
  • Billed time & materials, per change
  • Each one waits in a dev queue
  • Cost grows with every change you ask for
With DocGen
€9,000per year
  • €7,500 platform — one production environment, every template in it
  • 4 changes included, one per quarter
  • 2 chargeable changes × €750
  • Fixed price, quoted before you approve
You keep
€19,500per year, every year
  • 68% less for the same six changes
  • No dev queue between you and a corrected invoice
  • Savings compound — the more you change, the wider the gap
Central case. Change frequency drives the delta: at 2 changes/yr DocGen still wins; at 12 it wins by roughly triple. The ~€4,750 per change is a modelled input taken from one client's own historical change costs, not an industry benchmark — the DocGen case study shows the working.

Forty seconds, template edit to finished document

A recorded template change on the real production statement template: edit the Handlebars source, re-render, and see the change land in the document. In production the same edit ships by seed — an idempotent alternate-key upsert — with no compiled-code release.

What happens in this video
  1. A title card: a template change, start to finished document — real production template, real rendering pipeline, no code release.
  2. Step 1, edit the Handlebars template. In template.html for the account statement, the Invoice Detail table's “Reference” column header is changed to “Invoice No.”, because the client wants the column called Invoice No.
  3. Step 2, re-render. A terminal runs npm run preview account-statement-openchecks: Handlebars plus the enriched data tree become HTML, then Chromium turns it into the PDF.
  4. The re-rendered statement scrolls past with the same data in the new layout: letterhead, account summary, invoice detail, unapplied payments, aging summary and the payment and remittance panel.
  5. The change, live in the document: the Invoice Detail table now has an “Invoice No.” column where “Reference” was.
  6. In production, the same edit ships with npm run seed, an idempotent alternate-key upsert into Dataverse, and is live in every channel that calls sss_GenerateDocument. No compiled-code release, no dev queue.

39 seconds, no sound. Anonymised production statement template, synthetic data.

Technical details: the document pipeline

One call, seven stages

Your app calls a single unbound custom API with a template code and a record id. A thin plugin proxies it (Entra client-credentials) to the rendering container, which runs the pipeline and returns the finished PDF. Nothing is stored unless you ask for it — pass Attach to have the document written back to the record as a note.

sss_GenerateDocument · account-statement-openchecks
// MDA / Power Automate / Code App → sss_GenerateDocument
{
  "Code": "account-statement-openchecks",
  "EntityId": "a1f8c2e6-4b90-4d1e-9a77-3f0e5c8b2d14",
  "Attach": true       // optional, default false — store a note on the record
}

// engine pipeline (in your Azure subscription)
▸ TemplateStore      read sss_documenttemplate by sss_code
▸ DatasetRunner      4 FetchXML datasets in parallel  // @entityId@ bound
▸ TreeBuilder        nest child rows via sss_parentkeyfield
▸ Enricher           totals, amountDue, aging buckets, credit-balance flag
▸ Handlebars         template.html + data tree → HTML
▸ PdfRenderer        HTML → PDF  // Playwright Chromium
▸ DeliveryService    annotation on the record  // only when Attach=true

// return
{
  "fileName": "Statement_ACME-Corp_2026-07.pdf",
  "annotationId": "7c3d…e21a",
  "fileBase64": "JVBERi0xLjc…",  // full PDF, ready to attach or download
  "warnings": null          // non-fatal problems, e.g. a truncated dataset
}
Illustrative shape. Business logic lives in the Enricher — templates stay logic-light and safe to hand to non-developers.
Technical details: engine capabilities

What's in the engine

Config-driven templates

A template is data, not code: manifest.json, FetchXML datasets, and a Handlebars template.html, seeded into Dataverse by idempotent alternate-key upsert.

Parallel datasets

Child sss_templatedataset queries run in parallel — 5,000-row pages, 50k hard cap — then nest into a JSON tree by parent key field.

The Enricher

Totals, amount due, credit-balance detection, aging buckets, and bill-address resolution — all the business logic, kept out of the templates.

Chromium PDF rendering

Handlebars → HTML → pixel-faithful PDF via Playwright Chromium, with fonts baked into the container image.

Delivery, opt-in

Nothing is stored by default. Pass Attach and the run writes an annotation (note attachment) to the target record; the optional draft email is a per-environment flag — so you don't pay Dataverse file storage twice, or at all.

Callable everywhere

One unbound custom API — sss_GenerateDocument — from the model-driven app, Power Automate, Code Apps, and Power Pages.

HTML & data modes

Output=html returns the rendered layout without starting a browser; Output=data returns the enriched data tree as JSON, so template authors can see every field before writing a line of markup.

Correctness warnings

The dangerous failure is a document that renders successfully but wrongly. A truncated dataset or an unresolved parent key comes back in a warnings field instead of passing silently — branch on it rather than trusting HTTP 200.

Deployment, security and maintenance

Runs in your tenant, by design

No black-box SaaS holding your documents. DocGen deploys into your own cloud and talks only to your own data.

Your Azure subscription

Scale-to-zero Azure Container Apps (1 vCPU / 2 GiB). All-in run cost typically well under €900/yr at current Azure pricing — you pay Azure directly, and the actual cost depends on your region, tier and volume.

Your Dataverse & Entra ID

One app registration, client-credentials token. The container uses the same service principal as its Dataverse application user.

Secrets, and where they actually live

The container app reads its Entra client secret from Key Vault through its own managed identity — never checked in, never in logs. The Dataverse plugin needs its own copy, and the platform request it uses can't resolve Key Vault-backed variables, so that one is a Text environment variable you restrict to admins. We'd rather say so here than have your security reviewer find it.

Deliberately simple

No queues, no blob storage, no caching until real volume proves the need. Fewer moving parts to break.

100+ tests

Engine and integration coverage: happy path plus normal and credit-balance variants, verified against real sample data.

Managed & versioned

Monitoring, patching, Chromium and Dataverse-API compatibility maintenance. Dev and test environments are included at no charge — you should never be billed for good ALM.

High-volume invoices and statements

If you send invoices or statements in bulk

Two real jobs. Three ways to do them. The price that actually moves with volume is Power BI capacity, not DocGen.

Send invoices in bulk

  • SSRS / paginated

    An RDL per document type. Bulk PDF uses exportToFile, and that API requires a workspace on dedicated Power BI Embedded, Premium, or Fabric capacity — it isn't optional. Premium Per User allows one export per five minutes, which is unusable for a thousand-plus invoices. A1 (~$735/mo) is a lab floor; real paginated load sits on A3/A4-class nodes. A layout change is another RDL release.

  • Word templates (platform)

    A Power Automate loop — Populate a Word template, then Convert to PDF on the premium connector, once per invoice. Fine for a handful; a monthly batch is hundreds or thousands of runs. More in Dynamics 365 Word template limitations.

  • DocGen

    One HTML template in Dataverse, sss_GenerateDocument per invoice, attach and send from a flow. No Power BI Embedded. No monthly document cap.

Send account statements in bulk

  • SSRS / paginated

    Same three paths. A second RDL on the same expensive capacity.

  • Word templates (platform)

    A second .docx and the same per-document loop.

  • DocGen

    Clone the template, change the FetchXML. The €7,500 environment licence does not move.

Path — licence only 1,000 / mo12k / year 5,000 / mo60k / year 10,000 / mo120k / year
SSS DocGen€7,500 / year, flat — no Power BI Embedded, no monthly cap €0.63per PDF €0.13per PDF €0.06per PDF
Power BI Embedded A3, 24/7US East estimate · ~$2,939/mo (~$35k/year) $2.94per PDF $0.59per PDF $0.29per PDF
Power BI Embedded A4, 24/7US East estimate · ~$5,878/mo (~$70k/year) $5.88per PDF $1.18per PDF $0.59per PDF
Currency. The DocGen row is in euros, at the published price. The two Power BI Embedded rows are in US dollars and are not converted to euros.
One year of DocGen (€7,500) sits in the same band as one month of A4. Capacity then keeps billing, month after month. DocGen's €/PDF falls as volume rises because the licence is flat.
A3/A4 dollars are US East, 24/7 estimates from Microsoft's public Azure hourly list prices. Not a quote; region, pause schedule and SKU choice change the bill. We are not pitching A1 for this load.
Per-seat document tools also meter a monthly document cap, and license every writer besides — see the per-seat paragraph under Pricing. DocGen has no document count at all.
Azure Container Apps for DocGen stay typically well under €900/year, as stated under Pricing — running at this volume doesn't change that number.
No customer here: these three volume bands are worked examples of the published €7,500 rate, not a named case study or a demo login.

Pricing

€7,500per production environment per year€625 a month equivalent, billed annually. Excl. VAT.

Not per user, not per document, and not by template count — the same number for a five-person team and a five-thousand-person one, because you aren't buying seats. Marginal cost per document is effectively zero because the infrastructure is yours, so metering volume would only be a tax on using the thing you bought. Dev and test environments are free. Everything else in this category makes you book a call to find out the price; we don't think a price is a negotiating position to protect until a salesperson has qualified you.

Platform

per production environment · billed annually
LinePer month
SSS DocGen€625 / month €7,500 / year, billed annually
SSS DMS — add-on to DocGen, not sold on its own€375 / month €4,500 / year, billed annually
Both, same environment€1,000 / month €12,000 / year, billed annually
Included
  • Dev and test environments at no charge
  • Every template in the environment — no bands, no count to report
  • Monitoring and patching
  • Chromium and Dataverse API compatibility maintenance
  • Business-hours support, next-business-day response
  • One template change per quarter
Both in one environment share the same app registration, the same container and one deployment. €12,000 per year (€1,000 a month equivalent, billed annually) is that shared cost, not a discount.
Each additional production environment is the same rate. Example: two production environments running DocGen → €15,000 per year (€1,250 a month equivalent), whatever the template count. Per-environment vs per-seat licensing, and where the crossover sits.

Changes

fixed price · no retainer
LinePrice
Template change — layout, wording, field swap€750
Block of 5 changes€3,300
Template change — new dataset or enrichment rule€1,300

One-time

fixed price · per item
LinePrice
Deployment and onboarding, first environment€5,500
Each additional environment€2,200
New template — simple€1,750
New template — standard€2,600
New template — complex€3,900
All prices are in euros and exclusive of VAT. EU business customers with a valid VIES-registered VAT number are reverse-charged; customers outside the EU are invoiced in euros with no Portuguese VAT added — confirm the treatment on your side with your own tax adviser. See Terms of Service §5.1 for the full treatment. Monthly figures are the annual licence divided by twelve; licences are billed annually.
Azure infrastructure is billed directly to your own subscription by Microsoft (typically well under €900/yr, depending on region, tier and volume) and is not part of these figures.

No per-seat creep. Per-seat document tools license every user with write access to a Dataverse table. Above roughly 300 users, that costs more than DocGen — and it keeps growing as the firm does. They also cap how many documents you may generate each month; DocGen has no document count at all.

Licensing never blocks a document. Documents are business-critical, so enforcement is deliberately soft: past renewal, whatever the state — the PDF still generates, and the discrepancy is flagged to us, not to your users. A licensing dispute should never stop a firm invoicing.

Building a Dataverse product with compiled templating inside it? There is an OEM lane: you embed the engine, resell at your price, and pay a wholesale per-environment rate. The terms — including the parts that might rule you out — are published. OEM and embed terms, on the partners page.

Questions buyers actually ask

Who owns the templates?

You do. A template is configuration — Handlebars markup and FetchXML rows — living in your Dataverse, readable and exportable at any time. If we part ways, your templates stay where they've always been.

What counts as a production environment?

Any Dataverse environment where real business documents are generated — typically one per legal entity. Dev and test environments are free, however many you run: we don't tax good ALM.

What's a change versus a new template?

A change edits a template you already have: layout, wording, or a field swap is €750; a new dataset or enrichment rule behind it is €1,300. A new template is a document class you don't have yet — €1,750–€3,900 by complexity, quoted before you approve.

Does the number of templates change the price?

No. One production environment is €625 per month, billed annually (€7,500/year), whether it runs three templates or fifty — templates are unlimited, and there's no count to report at renewal. If your library is very large we'll still say so — a library that size tends to hide near-duplicates, and rationalising it makes the thing easier to own — but it's advice, not an invoice.

Where do the generated PDFs live?

They're rendered in your Azure subscription and returned to the caller — nothing is stored by default, and nothing leaves your tenant. Pass Attach and the PDF is written to the record as a note, in your Dataverse, under your retention rules.

Why isn't pricing per document?

Because your documents cost us nothing. The engine runs scale-to-zero on your own infrastructure, so a per-document meter would just be a tax on using the thing you bought. The only meter that tracks real cost is the environment — so that's what you pay for: €625 a month, billed once a year, at a number you can read on this page. At 10,000 invoices a month the flat licence works out at €0.06 per PDF, and it keeps falling as you send more.

Tell us about your documents

The fastest route to a useful answer: tell us what you generate today, what it's built on, and how often it changes. We'll come back with whether DocGen fits, what it would cost you, and what it wouldn't solve — before anyone books a call.

Send us the shape of the problem.

Which documents, which system generates them now, roughly how often they change, and how many production environments you run. That's enough for us to answer properly.

Runs in your tenantData Processing AgreementSecurity overview

How we handle your email
  • Controller. Simple Smooth Safe, Unipessoal Lda., Rua Retiro dos Pacatos 50, Ed. Startup, Sala 9, 2635-224 Rio de Mouro, Portugal. NIF/VAT PT518264742. Questions or requests: info@simplesmoothsafe.com.
  • What we hold. Your name, email address, whatever you chose to tell us about your organisation, and the correspondence itself.
  • Purpose. To answer you, and to follow up on the specific thing you asked about.
  • Legal basis. Legitimate interest (Art. 6(1)(f)) in responding to an enquiry you initiated, or steps prior to entering a contract (Art. 6(1)(b)) where you are asking to buy.
  • Retention. Up to 24 months after our last exchange, then deleted — unless you become a customer, in which case section 1.4 applies.
  • Your rights. Ask for access, correction or deletion, or object, at any time by emailing us. Full detail in the Privacy Policy, section 1.2.