Microsoft Power Platform
Build Penneo Sign flows in Microsoft Power Automate with our certified connectors
Power Automate connectors
Penneo publishes two certified connectors for Microsoft Power Platform. They let you create case files, poll for case file creation, poll for casefile status, and download signed documents from a Power Automate flow without writing any code.
Both connectors are open source and maintained in Microsoft's connector repository:
Choosing an environment
The two connectors expose exactly the same actions with exactly the same fields. The only difference is which Penneo environment they talk to:
| Connector | Environment | API host | OAuth host |
|---|---|---|---|
| Penneo Sign | Production | app.penneo.com | login.penneo.com |
| Penneo Sign Sandbox | Sandbox | sandbox.penneo.com | sandbox.oauth.penneo.cloud |
Build and test your flow with Penneo Sign Sandbox, then swap the connection over to Penneo Sign for production. Because the action names and fields are identical, no other changes to the flow are needed.
A sandbox account is separate from your production account. If you don't have one, contact Penneo support to get sandbox access before you start.
Prerequisites
- An active Penneo account (a sandbox account for the sandbox connector).
- A Power Automate, Power Apps, or Logic Apps environment.
Authentication
Both connectors use OAuth 2.0 Authorization Code Grant. When you create the connection, Power Platform redirects you to Penneo's login page and you sign in with your regular Penneo credentials - there are no API keys to manage in the flow.
The connectors request no scopes, and the connection acts as the signed-in user - so the case files it creates are owned by that user, and it can only read case files that user has access to.
Actions
Each connector ships four actions.
| Action | What it does |
|---|---|
| Create a new case file | Queues a new case file with your documents and signers. Returns a job uuid and payloadHash. |
| Check job status | Polls the creation job using uuid + payloadHash until it is completed (or failed). Returns the caseFileId that are used in the next actions. |
| Get case file details | Returns a case file's status, signers, and documents (including the document ids) by caseFileId. |
| Download document | Returns a document's content as a base64 encoded string. |
The typical flow
Case file creation is asynchronous, so a complete end-to-end flow has four steps:
- Create a new case file - pass the title, base64 encoded PDFs, and signers. You get back a job
uuidand apayloadHash. - Check job status - poll with that
uuidandpayloadHashuntiljobStatusiscompleted. The completed job'sresultcontains the createdcaseFileId. - Get case file details - call with the case file id. Wait for
status5 (completed) before downloading; until then the signers haven't all signed. - Download document - call once per document id from step 3, then decode the base64
contentinto a PDF file.
Steps 2 and 3 are polling steps. Use a Do until loop with a delay between iterations rather than a tight loop, and remember that a case file can end in a non-completed state (rejected, expired, failed) - handle those branches too.
Create a new case file
The request body is a single caseFile object.
Case file fields
| Field | Type | Required | Notes |
|---|---|---|---|
title | string | Yes | 1–1024 characters. |
documents | array | Yes | See Document fields. |
signers | array | Yes | See Signer fields. |
language | enum | No | en, da, sv, nl, fr, fi, no, de. Applied to signers without their own language. |
sendAt | integer (UNIX ts) | No | When to send the case file. Empty = send immediately. |
expireAt | integer (UNIX ts) | No | When the case file expires. Defaults apply if omitted. |
visibilityMode | integer | No | 0 = signers see all documents (default), 1 = signers see only what they must sign. |
sensitiveData | boolean | No | Signers must validate their identity before accessing documents. Also disables email attachments. |
disableEmailAttachments | boolean | No | Leaves signed documents out of finalisation emails. Overridden when sensitiveData is true. |
disableNotificationsOwner | boolean | No | Stops notifications to the case file owner. |
signOnMeeting | boolean | No | Documents are signed during a physical meeting. |
folderId | integer | No | Places the case file in a specific Penneo folder. |
reference | string | No | Shown in the Penneo web application — handy for correlating with your own system's record id. |
metaData | string | No | Searchable in Penneo via API. |
ccRecipients | array | No | name and email; receive a copy of the signed documents. |
Document fields
| Field | Type | Required | Notes |
|---|---|---|---|
title | string | Yes | 1–1024 characters. |
pdf | string | Yes | Base64 encoded PDF. |
signable | boolean | No | true (default) = signable document, false = read-only attachment. |
roles | array | No | Signer roles allowed to sign this document. Empty = all signers. |
documentOrder | integer | No | Signing order of the document. Defaults to the order supplied. |
metaData | string | No | Searchable in Penneo. |
Signer fields
Only name is strictly required, but in practice you also want email so Penneo can send the signing request.
| Field | Type | Notes |
|---|---|---|
name | string | Required. |
email | string | Penneo handles all communication with the signer. |
role | string | Min. 3 characters. Letters, numbers, spaces, comma, underscore, hyphen. Must not end in a space. Match with documents[].roles. |
signOrder | integer | 0 (default) = no enforced order. Use ascending numbers for sequential signing. |
language | enum | Same list as the case file language. |
reminderInterval | integer | Days between reminders. |
activeAt / expireAt | integer | UNIX timestamps controlling when this signer can sign. |
successUrl / failUrl | string | Redirect URLs after signing succeeds or fails. |
onBehalfOf | string | Company or organisation the signer signs for. |
storeAsContact | boolean | Default true — stores the signer as a contact in Penneo. |
accessControl | boolean | Validates SSN / VATIN / phone before granting access. |
socialSecurityNumberPlain | string | SSN or phone number. Use E.164 format for phone numbers. |
ssnType | enum | legacy (default), dk:cpr, se:pin, no:nin, be:nrn, fi:pic, sms, google:oidc, microsoft:oidc. |
vatin | string | VAT number of the signer's company. |
secureSigningMethods | array | Restricts eID methods — see below. Overrides case file and customer settings. |
enableInsecureSigning | boolean | Allows touch signatures. |
insecureSigningMethods | array | text, draw, image. Empty = company default. |
emailSubject / emailText | string | Signature request email. Falls back to your company template. |
reminderEmailSubject / reminderEmailText | string | Reminder email. Falls back to your company template. |
completedEmailSubject / completedEmailText | string | Completion email. Falls back to your company template. |
emailFormat | enum | text (default) or html. |
Available values for secureSigningMethods:
mitid.dk bankid_se bankid_no
itsme.be ftn.fi eid.belgium.be
passport-reader.eident.dk ausweisapp.bund.de
qes.personal.mitid.dk qes.erhverv.mitid.dk
Every field maps 1:1 to the Create case file API reference, so use that page when you need the full detail behind a field.
Check job status
Send the uuid and payloadHash from the create step. The response includes:
| Field | Notes |
|---|---|
jobStatus | pending, processing, completed, failed, or aborted_duplicated. |
result | Returned as JSON once the job completes — this is where the created caseFileId comes from. |
errorMessage | Only present when jobStatus is failed. |
createdAt / updatedAt | ISO 8601 timestamps. |
This action is rate limited to 20 requests per minute per
uuid+payloadHashcombination. Put a delay in your polling loop and back off on failures.
Get case file details
Takes the caseFileId and returns the case file with its signers (name, id, and the signing request's email and status) and its documents (id, status, and whether the document is signable). The documentIds are what you pass to Download document.
Case file status values:
| Value | Status | Value | Status |
|---|---|---|---|
| 0 | new | 5 | completed |
| 1 | pending | 6 | failed |
| 2 | rejected | 7 | expired |
| 3 | deleted | 8 | anonymized |
| 4 | signed |
Use status 5 (completed) as the trigger for downloading signed documents.
Download document
Takes a document id and returns a content field with the base64 encoded document. The optional Signed parameter defaults to true.
If a case file contains several documents, loop over the document ids from Get case file details - the action returns one document per call.
Working with base64 in Power Automate
Both the request and response side of these connectors use base64 encoded PDFs:
- Uploading: use the
base64()expression on the file content, for examplebase64(outputs('Get_file_content')?['body']). - Downloading: use
base64ToBinary()on the returnedcontentbefore writing the file, for example in a Create file action for SharePoint or OneDrive.
Large PDFs take longer to process and inflate roughly 33% when base64 encoded, so keep an eye on document size in high-volume flows.
Known limitations
- Asynchronous creation. Creating a case file returns a job, not a case file. You must poll Check job status; there is no synchronous create.
- Polling, not webhooks. These connectors have no triggers, so a flow reacting to signing completion has to poll Get case file details. If you need push notifications, use webhooks against the REST API instead.
- Rate limit. 20 requests per minute per
uuid+payloadHashon Check job status. - Environment is fixed per connector. A connector cannot be pointed at a different Penneo environment - pick the connector that matches the environment.
Where to go next
- Field-level reference for every case file property: Create case file.
- Building something more custom than a flow? Start with the Direct REST API.
Updated 17 days ago
