> For the complete documentation index, see [llms.txt](https://docs.sign.enadocapp.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.sign.enadocapp.com/evia-sign-api/v2/webhook-management/store-completed-documents-in-sharepoint-using-microsoft-power-automate.md).

# Store Completed Documents in SharePoint using Microsoft Power Automate

Webhook-triggered document retrieval, validation, extraction, and SharePoint storage

## Overview

This guide configures a Power Automate cloud flow that receives the Evia Sign signing\_completed webhook, validates its HMAC signature, retrieves the completed package, and saves the signed documents and audit trail in SharePoint.

Important: The completed package contains the completed documents and audit trail. Do not use the webhook payload itself as the document file; it contains only event metadata.

{% hint style="info" %} <mark style="color:$primary;">Important:</mark> The completed package contains the completed documents and audit trail. Do not use the webhook payload itself as the document file; it contains only event metadata.
{% endhint %}

## How the integration works

1. Evia Sign sends a signing\_completed webhook when a request is fully completed.
2. Power Automate receives the raw JSON body through an HTTP request trigger.
3. The flow verifies X-Webhook-Signature using the shared webhook secret.
4. The flow calls the completed package endpoint with X-Webhook-Download-Token.
5. The downloaded package is extracted and its files are created in a SharePoint folder named after the request.

## Prerequisites

* An Evia Sign webhook configured for the signing\_completed event.
* Webhook security mode set to HMAC and a securely stored webhook secret.
* An Evia Sign access token with permission to retrieve completed requests.
* A SharePoint site and document library where the integration account can create folders and files.
* A Power Automate Premium licence if your selected HTTP actions/connectors require one.

{% hint style="info" %} <mark style="color:$primary;">Security:</mark> Store the webhook secret and Evia Sign access token in Power Automate environment variables, Azure Key Vault, or another approved secret store. Do not hard-code them in actions or screenshots.
{% endhint %}

## Webhook payload

The incoming webhook body is similar to the following:

```
{
  "deliveryId": "delivery-123",
  "eventId": "signing_completed",
  "tenantId": "tenant-123",
  "requestId": "request-123",
  "requestTitle": "document-123.pdf",
  "timestamp": "2026-09-04T10:00:00Z",
  "schemaVersion": "1.0"
}
```

| **Field**     | **Purpose**                                                                                   |
| ------------- | --------------------------------------------------------------------------------------------- |
| deliveryId    | Unique delivery reference for troubleshooting and duplicate handling.                         |
| eventId       | Event name. Continue only when it is signing\_completed.                                      |
| tenantId      | Tenant that owns the signing request.                                                         |
| requestId     | Request identifier used to download the completed package.                                    |
| requestTitle  | Request title; useful for logging only. Do not use it as a folder name without sanitizing it. |
| timestamp     | Event timestamp in UTC.                                                                       |
| schemaVersion | Webhook payload version.                                                                      |

## Build the Power Automate flow

### Create the trigger

1. <mark style="color:$primary;">Create a flow</mark>. Create an Automated cloud flow and select the When an HTTP request is received trigger.
2. <mark style="color:$primary;">Copy the URL</mark>. Save the flow once, then copy the generated HTTP POST URL. Use this URL as the webhook callback URL in Evia Sign.
3. <mark style="color:$primary;">Use a JSON schema</mark>. Add the following schema to make requestId and other fields available as dynamic content.

```
{
  "type": "object",
  "properties": {
    "deliveryId": { "type": "string" },
    "eventId": { "type": "string" },
    "tenantId": { "type": "string" },
    "requestId": { "type": "string" },
    "requestTitle": { "type": "string" },
    "timestamp": { "type": "string" },
    "schemaVersion": { "type": "string" }
  }
}
```

### Validate the HMAC signature

The webhook header X-Webhook-Signature is expected in this format:

```
X-Webhook-Signature: sha256=<hexadecimal HMAC>
```

Calculate an HMAC SHA-256 signature from the unmodified raw request body using the shared webhook secret. Compare the calculated value with the header value after removing the sha256= prefix. End the flow with an HTTP 401 or 403 response when the signature does not match.

{% hint style="warning" %} <mark style="color:$warning;">Do not alter the body first:</mark> HMAC verification must use the raw body received by the HTTP trigger. Parsing, formatting, or serializing JSON before computing the HMAC can produce a different signature.
{% endhint %}

If your tenant policy requires stronger validation, also verify eventId equals signing\_completed and reject any unsupported schemaVersion.

### Retrieve the completed package

When the webhook response includes a completedPackage object, add an HTTP GET action and use completedPackage.url directly. This is the recommended webhook retrieval method because it is a time-limited URL for that completion event.

```
GET @{triggerBody()?[completedPackage]?[url]}
```

Configure this header using the values from the completedPackage object:

{% hint style="info" %} <mark style="color:$primary;">Expiry:</mark> Use the package URL and token promptly. The completedPackage object may include an ExpiresAt value. Do not store the download token as a reusable credential.
{% endhint %}

<table data-header-hidden><thead><tr><th width="252"></th><th></th></tr></thead><tbody><tr><td>Header</td><td>Value</td></tr><tr><td><strong>X-Webhook-Download-Token</strong></td><td>concat(Bearer , triggerBody()?[completedPackage]?[token])</td></tr><tr><td><strong>Accept</strong></td><td>application/zip</td></tr></tbody></table>

### Create a request folder in SharePoint

Add a Create new folder action before writing files. A safe folder naming convention is:

```
EviaSign Signed Documents / <requestId>
```

Using requestId avoids invalid SharePoint filename characters and prevents different requests with similar titles being stored in the same folder.

### Extract and save the package files

The completed-package response is a ZIP archive. Use an approved ZIP extraction approach in your environment, then loop through the extracted files.

* For each file, use Create file (SharePoint) with the request folder path, the extracted filename, and file content.
* Store the signed documents and audit\_trail.pdf in the same request folder.
* Optionally create a small metadata JSON file containing deliveryId, requestId, tenantId, timestamp, and the stored file list.

{% hint style="info" %} <mark style="color:$primary;">Extraction option:</mark> Power Automate cloud flows do not provide universal native ZIP extraction. Depending on your licensing and organisation policy, use an approved connector, an Azure Function, Power Automate Desktop, or another approved service. Keep the extraction component private and ensure it preserves binary content.
{% endhint %}

## Recommended flow controls

| Control              | Recommendation                                                                                                                      |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| Duplicate protection | Store deliveryId in a SharePoint list or data store. If it has already been processed, return success without creating files again. |
| Retry policy         | Use controlled retries for transient HTTP or SharePoint failures. Do not retry signature-validation failures.                       |
| Failure alerting     | Notify the integration owner with deliveryId and requestId if package retrieval or SharePoint storage fails.                        |
| Folder permissions   | Grant the flow connection only the minimum SharePoint permissions needed for the target library.                                    |
| Logging              | Log IDs, timestamps, status codes, and file names. Never log access tokens, webhook secrets, or full signed-document content.       |

Test checklist

* [ ] Webhook test connection succeeds and reaches the Power Automate HTTP trigger.
* [ ] A genuine signing\_completed event contains the X-Webhook-Signature header.
* [ ] Valid HMAC is accepted; an edited body or invalid signature is rejected.
* [ ] The package endpoint returns a ZIP containing completed documents and audit trail.
* [ ] A new SharePoint folder is created using requestId.
* [ ] All expected files open correctly from SharePoint.
* [ ] Replaying the same deliveryId does not create duplicate files.
* [ ] Logs contain useful identifiers but no secrets.

## Troubleshooting

| Issue                         | Check                                                                                                                     |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| Webhook not received          | Confirm the callback URL is saved, reachable over HTTPS, and the signing\_completed event is enabled.                     |
| Signature mismatch            | Confirm HMAC mode is enabled, the correct secret is used, and the calculation uses the unchanged raw body.                |
| 401/403 from package endpoint | Check the bearer token, tenant access, request completion status, and X-Webhook-Download-Token value.                     |
| No documents in package       | Confirm the request is fully completed. The package should be requested only after the completion event.                  |
| SharePoint Create file fails  | Check folder path, connection permissions, file-name validity, and that the extracted content is binary rather than text. |
| Duplicate documents           | Implement deliveryId idempotency before creating the folder and files.                                                    |

## Completion criteria

The integration is ready for production when a completed Evia Sign request automatically results in a validated webhook event, a retrievable completed package, and an organized SharePoint folder containing the signed documents and audit trail.
