Security change on December 1, 2026: TLS 1.2 will become the minimum standard for 365 business Print Agent. Details and system requirements
365 business development

365 business PDF

365 business PDF post-processes the PDF documents Microsoft Dynamics 365 Business Central produces: it applies stationery, concatenates documents, attaches further documents, signs and protects them, and turns sales invoices into ZUGFeRD / Factur-X documents. The processing itself runs in the 365 business API PDF service; the app is the Business Central side of it.

This page is the entry point for using the app from your own extension. There are three ways to do that, and they solve different problems:

You want toStart here
Apply stationery, merge documents or read a stored PDF file from your own codeThe codeunit chapters below
Change or skip what the app does to a printed reportExtensibility Events
Add a document to a sales or purchase document from outside Business CentralDocument Attachment API

Dependency

Add a dependency to the 365 business PDF app in the dependencies node of your app.json:

JSONCode
{ "id": "66745141-90b6-4fb0-906a-94400600f856", "name": "365 business PDF", "publisher": "365 business development", "version": "20.5.0.0" }

Which version you need

The codeunits described here have been introduced with 20.5, which split the former bdev.Pdf API codeunit into one codeunit per capability. On an older version only bdev.Pdf API is available.

The public objects

The objects below are the supported surface of the app. The three capability codeunits, the event publisher and the reference table declare Access = Public; the enums and the obsolete bdev.Pdf API are public by the AL default. Everything else in the app is either Access = Internal or an implementation detail that may change without notice, even where AL leaves it public.

ObjectTypeWhat it is for
bdev.Pdf - StationeryCodeunit (5523673)Apply stationery to a PDF document.
bdev.Pdf - ConcatenateCodeunit (5523674)Merge PDF documents into one, optionally in several copies.
bdev.Pdf - FileCodeunit (5523672)Read a PDF file stored in PDF Files, in the language you need.
bdev.PDFCodeunit (5523675)The integration point of the report processing. It only publishes an event.
bdev.Pdf ZUGFeRD TaxCat.ReasonTable (5523599)The tax category exemption reasons a ZUGFeRD document can state. Reference data, pointed at by the Tax Category Reason Code field the app adds to VAT Posting Setup.
bdev.Pdf APICodeunit (5523590)The predecessor of the three codeunits above. Obsolete since 20.5, but still the only way to sign a document from AL.

Two enums are part of that surface:

EnumValuesMeaning
bdev.Pdf Document Print Intent (5523591)Print, Preview, Download, SaveWhat the user asked for. A configuration states per intent whether it applies, which is why the intent is a parameter of the stationery methods and of the event. Extensible.
bdev.Pdf Rotation (5523594)None, RotateAngle90, RotateAngle180, RotateAngle270How a document is rotated when it is merged into another one. Set per document attachment; not extensible.

How a printed report is processed

Knowing the order the app works in makes both the events and the codeunits easier to place. Whenever Business Central has rendered a report to PDF and the report selection carries a 365 business PDF configuration, the app runs the following:

  1. The base record of the report is resolved. A report printed for exactly one record is a single print, anything else is a bulk print.
  2. The print intent is read from the object payload; on a single print the language code is taken from the document.
  3. OnBeforePerformAdditionalActionsOnPdf is raised. A subscriber can replace the document, change the report selection, or stop the processing here.
  4. A security configuration on the report selection is remembered and applied to the service calls that follow.
  5. The stationery configuration is applied.
  6. The concatenate configuration is applied.
  7. On a single print, the document attachments of the record are added.
  8. The signing configuration is applied - unless the intent is Print, as a signature on a document that goes to a printer serves no purpose.
  9. On a single print, the document is converted to ZUGFeRD / Factur-X.

Bulk print is not the same as single print

Steps 7 and 9 are skipped on a bulk print, and stationery that is configured per page position is skipped as well - the app cannot tell where one document ends and the next begins in a merged bulk print, and sends a notification instead. Extensions that rely on document attachments or on ZUGFeRD must expect them to be absent when a user prints a batch.

Everything goes through the PDF service

Every method of the codeunits described here ends in an HTTP call to the 365 business API PDF service. Two things must be in place for such a call to succeed:

  • the 365 business PDF feature must be licensed for the tenant;
  • outgoing HTTP calls must be allowed for the 365 business PDF extension. In a sandbox this is off by default and the call fails.

Both are properties of the environment, not of your extension - but your error handling has to cope with them.

See also

Last modified on