Adobe PDF Certificate and Badge Generator
When a course or event is completed (Dataverse record), the flow merges the recipient's details into a certificate template with Adobe PDF Services, generates a personalized PDF certificate (optionally with a unique verification ID/QR), emails it to the recipient, and files a copy. Automates bulk certificate issuance.
Provided as-is, without warranty of any kind. Review and test each pattern in a non-production environment before deploying it to live automations. See our Terms.
Overview
FlowLibs CF-546 — Certificate and Badge Generator automatically issues a personalized, branded certificate the moment a course or event completion is recorded in Dataverse. When a completion row is created, the flow composes a branded certificate document, archives a copy to SharePoint, emails it to the recipient, and writes the issuance details (verification ID, archive URL, status) back onto the record.
Why it matters: Hand-made certificates don't scale. Templated, event-driven generation issues consistent, verifiable certificates in bulk with zero manual effort.
Implementation note — connector substitution. The original idea specified Adobe PDF Services Document Generation. The Adobe PDF Services connector's file-upload parameter (InputFile0 / "Template File Content") is a contentOnly multipart param that cannot be authored through the API/solution deployment path FlowLibs uses. The FlowLibs-standard, fully-supported substitute is used here: the certificate is composed in-flow as branded HTML (a Compose action) and delivered/archived with first-class connectors (SharePoint + Outlook). This produces a 100%-bound flow — Flow Checker 0 errors / 0 warnings. To emit a true PDF at go-live, swap the Compose Certificate Html action for an Adobe PDF CreateDocumentFromTemplate action (or Word Online Populate template -> Convert to PDF) once that connection is authorized; every other action stays the same.
Use Case
Training and events teams want completion certificates issued automatically, per attendee, the instant a completion is logged in CRM — archived for compliance and delivered to the recipient without anyone running a manual mail-merge.
Flow Architecture
When Completion Recorded
Microsoft Dataverse — SubscribeWebhookTrigger (row added)Fires on a new completion row (Organization scope); the new row is delivered inline.
Initialize configuration variables
Initialize Variable (x4)Issuing organization name, certificate signatory line, issued status label, and email subject prefix.
Compose Trace Id + Verification Id
Compose (@guid() x2)Mint a correlation trace id and a unique per-certificate verification id.
Compose Certificate Data
ComposeAssembles merge data from the trigger row + env vars.
Compose Certificate Html
ComposeRenders the branded HTML certificate document.
Compose File Name
ComposeBuilds a unique, collision-safe file name.
Create Archive Copy
SharePoint — CreateFileArchives the certificate to the configured library.
Send Certificate Email
Office 365 Outlook — SendEmailV2Emails the certificate (HTML body + file attachment).
Compose Issued Row
ComposeBuilds the Dataverse write-back object (one bound object).
Mark Certificate Issued
Microsoft Dataverse — UpdateRecordWrites status, verification id and archive URL back to the row.
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_CompletionTable | String | flowlibs_completion | Logical name of the completion table the trigger watches. |
| flowlibs_SharePointSiteURL | String | https://your-tenant.sharepoint.com | SharePoint site hosting the archive library. (reused shared variable) |
| flowlibs_CertLibraryPath | String | /Shared Documents/Certificates | Server-relative library/folder path for archived certificates. |
| flowlibs_VerifyBaseUrl | String | https://your-tenant.sharepoint.com/verify | Base URL used to build the certificate verification link. |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| Microsoft Dataverse | shared_commondataserviceforapps | SubscribeWebhookTrigger UpdateRecord |
| SharePoint | shared_sharepointonline | CreateFile |
| Office 365 Outlook | shared_office365 | SendEmailV2 |
Note — All connections are referenced as solution connection references; the flow is portable between environments as long as a connection is mapped at import time.
Customization Guide
Almost every realistic variant of this flow can be implemented by changing environment variable values. A few cases require small edits inside the flow definition — those are called out explicitly below.
- Emit a real PDF
- Replace Compose Certificate Html with Adobe PDF CreateDocumentFromTemplate, or Word Online Populate a Word template -> Convert Word Document to PDF; keep the same Compose Certificate Data object as the merge source.
- QR verification
- Embed a QR image pointing at verifyUrl (the flow already mints a per-certificate verification ID and URL).
- Badge variant
- Add a second Compose that renders a square, shareable badge and attach both to the email.
- Cohort / batch issuance
- Add a scheduled Recurrence + Dataverse ListRecords sibling flow to issue certificates for a whole group at once.
- Branding
- Adjust the inline CSS in Compose Certificate Html and the varOrgName / varSignatory variables — no logic changes required.
Key Expressions
The flow is intentionally light on Power Fx / WDL gymnastics — the heaviest expressions are the branch-name concatenation and the approval outcome check. They are listed below in the order they appear in the flow.
EXPR.01Verification ID
Unique per-certificate verification id (Compose Verification Id).
EXPR.02Completion date (formatted)
Human-readable completion date for the certificate.
EXPR.03Verify URL
Build the per-certificate verification link.
EXPR.04Certificate file name
Collision-safe certificate file name.
EXPR.05Email attachment bytes
Base64 of the HTML certificate for the email attachment.
EXPR.06Archived URL (write-back)
Full URL of the archived certificate for the row write-back.
EXPR.07Row write-back (whole-object bind)
Mark Certificate Issued binds the whole issued-row object (avoids new-table per-field schema-cache lag).
Customize & download
Generate a ready-to-import copy of this solution with your environment-variable values baked in — available on Base, Pro, or Team.
Upgrade to customize
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.