Skip to content

Document Flow webhooks ​

Webhooks let you receive information about process starts, recipient activity, document confirmation and sealing without polling the Document Flow API.

Contents ​

Configuration ​

An account administrator configures webhooks in the Document Flow module settings in the SARE panel.

  1. Provide a publicly accessible HTTPS URL that accepts POST requests.
  2. Select the event types you want to receive.
  3. Save the settings and test the webhook.
  4. Use the secret from module settings to verify signatures on the receiving server.

The configuration applies to the account. The webhook URL, secret and event list are not passed when creating a process through the API. Delivery is not queued if no URL or matching event type is configured.

The test sends a webhook.test event with event, eventId, occurredAt, source: "aurora.doc-flow", account and details fields. The account object contains tenantId and integrationKey, while details.message describes the test. The test has no process object and makes a single delivery attempt.

Headers and signature ​

HeaderMeaning
Content-Typeapplication/json
X-Confirmation-EventEvent type matching event in the payload
X-Confirmation-IdEvent ID matching eventId in the payload
X-Confirmation-SignatureSignature in sha256=<hex HMAC-SHA256> format, included when a secret is available

The signature covers the exact JSON content sent in the request. Verify it using the raw body bytes before the JSON parser converts them into an object. Serializing the object again can change field order or formatting and invalidate the signature.

Node.js example:

javascript
import { createHmac, timingSafeEqual } from 'node:crypto'

function verifyWebhook(rawBody, signature, secret) {
  if (!Buffer.isBuffer(rawBody) || typeof signature !== 'string') {
    return false
  }

  const match = /^sha256=([a-f0-9]{64})$/.exec(signature)
  if (!match) {
    return false
  }

  const expected = createHmac('sha256', secret).update(rawBody).digest()
  const received = Buffer.from(match[1], 'hex')

  return received.length === expected.length && timingSafeEqual(received, expected)
}

const signature = request.headers['x-confirmation-signature']
if (!verifyWebhook(rawBody, signature, webhookSecret)) {
  throw new Error('Invalid webhook signature')
}

const payload = JSON.parse(rawBody.toString('utf8'))

Here, rawBody is a Buffer containing the original request body, and webhookSecret is the secret from module settings. Configure your server to preserve the raw body before parsing JSON.

Example payload ​

A step.confirmed event:

json
{
  "event": "step.confirmed",
  "eventId": "dfw_t1_k8V4wN7xP2mQ6rS9aB3c",
  "occurredAt": "2026-10-19T10:15:00.000Z",
  "process": {
    "id": "dfp_t1_n7K2vP4qR8sT6wX9aB3c",
    "referenceId": "REF-2026-0001",
    "externalId": "case-2026-0001",
    "documentId": "dfd_t1_m3N8pQ2rS6tV4wX9aB7c",
    "sender": {
      "name": "Customer service",
      "email": "dokumenty@example.com",
      "replyTo": "dokumenty@example.com"
    }
  },
  "details": {
    "stepKey": "step_1",
    "actor": "recipient",
    "confirmedAt": "2026-10-19T10:15:00.000Z",
    "ip": "192.0.2.10",
    "userAgent": "Mozilla/5.0",
    "latestArtifactVersion": 2,
    "latestArtifactKind": "artifact",
    "fileAccessMode": "pin",
    "approvalMode": "button_only",
    "processStatus": "in_progress",
    "recipientEmail": "jan@example.com"
  }
}
FieldMeaning
eventEvent type
eventIdEvent ID, also used for retries
occurredAtWebhook event creation time in ISO 8601 format
process.idProcess ID used in the API
process.referenceIdProcess reference number
process.externalIdIdentifier in the integrator's system or null
process.documentIdProcess document ID
process.senderMessage sender: name, email, replyTo; may be null for older processes
detailsDetails specific to the event type

If an event identifies a step through stepKey, details.recipientEmail contains that recipient's email address when available. ip and userAgent may be null. Handwritten signature data in signatureDataUrl is not included in webhooks.

For step.confirmed, fileAccessMode and approvalMode describe the access and approval methods. The payload does not include the confirmationMethod or sourceIp fields shown in older documentation.

For a process belonging to a bulk send, details.campaign includes additional context: id, name, recipientId, executionId, documentUploadId, emailSubject, emailPreheader, scheduledAt, startedAt, expiresAt, fileAccessMode, approvalMode, pinDeliveryChannel, pinFallbackToEmail, includeSignatureCard, sealingEnabled and eurocertSealId. Some of these values may be null.

Event types ​

The following types can be selected in module settings:

Event typeMeaning
process.createdProcess created; see the emission note below
process.startedProcess started with recipients
email.sentEmail queued for sending, e.g. an access link or PIN
sms.sentSMS submitted for sending
sms.deliveredEmitted after a successful SMS sending call; see the delivery note below
step.email_sentAccess link message queued for a step
step.openedStep opened through the recipient link
step.viewedDocument view recorded
step.confirmedStep approved according to its mode
step.signedHandwritten signature added in a step
process.cancelledProcess withdrawn, rejected by a recipient or expired
artifact.sealing_startedFinal document sealing started
artifact.sealedSealed document version created
artifact.sealing_failedDocument sealing failed
process.completedAll process steps completed

Warning

process.created is available in settings, but the current process creation path records it only in process history. Select process.started to receive flow start notifications. Saving a draft without recipients does not trigger that event.

email.sent and step.email_sent do not confirm delivery to the recipient's inbox. They may describe the same queue operation under different names, with separate eventId values. sms.delivered is currently emitted immediately after a successful SMS sending operation and is not an independent delivery report from the handset.

process.completed does not guarantee successful sealing. Its details include completedAt, latestArtifactVersion, latestArtifactKind, latestSealedVersion, latestSealedKind and processStatus. If no sealed version has been created, latestSealedVersion and latestSealedKind are null. Also check artifact.sealed or artifact.sealing_failed to determine the sealing outcome.

Process history also includes process.paused, process.resumed, email.accepted, email.failed, step.pin_verified, password.requested and password.delivered. These types cannot be selected in webhook configuration. Do not expect them as webhook notifications.

Cancellation, rejection and expiry ​

All these scenarios use the process.cancelled event. Distinguish them using details:

ScenarioDistinctive details fields
Operator withdrawalprocessStatus: "cancelled" and reason, which may be null
Recipient rejectionactor: "recipient", stepKey, stepStatus: "failed", rejectedAt, reason, ip, userAgent and recipient email
expiresAt deadline reachedreason: "expired", completedAt and readUntil

Example details for a rejected document:

json
{
  "processStatus": "cancelled",
  "stepKey": "step_1",
  "stepStatus": "failed",
  "actor": "recipient",
  "rejectedAt": "2026-10-19T10:20:00.000Z",
  "reason": "Please correct the data in the document.",
  "ip": "192.0.2.10",
  "userAgent": "Mozilla/5.0",
  "recipientEmail": "jan@example.com"
}

Duplicates and retries ​

Webhooks are sent as POST requests with a 30-second response timeout. The receiver should return a 2xx status after durably storing the event.

  • Standard delivery makes up to 3 attempts in total: the initial attempt and 2 retries.
  • Retries are scheduled 30 seconds, then 60 seconds after the failed attempt. Queue load may increase the wait.
  • Connection errors, timeouts and HTTP error responses, including 4xx, are retried.
  • Retries preserve the eventId, request body, destination URL and headers saved when the delivery was created.
  • An administrator can review delivery history and manually retry delivery in the SARE panel.
  • Webhook delivery history is retained for 30 days after the record is created. Retries do not extend this period.

The same event may be delivered more than once. Store processed eventId values and return 2xx for correctly signed duplicates without repeating the business operation. Do not rely on webhook delivery order.

Best practices ​

  • Verify the signature against the raw body before processing business data.
  • Store eventId, event and process.id to associate events with processes and detect duplicates.
  • After durably storing the webhook, process longer tasks asynchronously.
  • Handle missing optional fields, null values and new fields added to the payload.
  • Retrieve the current process state and the appropriate PDF version through the Document Flow API.