Digitoo.ai
Processes

Webhooks

About webhooks

Webhooks are a vital component in modern Software as a Service (SaaS) applications, facilitating real-time communication and data exchange between different systems and services over HTTP. In the context of SaaS software, webhooks enable seamless integration with external systems, allowing for automated notifications, data synchronization, and triggering of actions based on specific events.

Webhook types

There are currently multiple webhook types available in Digitoo ecosystem. Here is a breakdown list with their functionality explained.

TypeTriggered whenDescription
document_status_changeWhenever document status change occursThis webhook is triggered when document status is changed either by API or user interaction. It is mostly used to trigger export mechanism to a 3rd party system.
queue_createdWhenever new queue is created in a workspaceThis webhook is triggered when new queue is created by the user. It's use case is mainly for integrators to update queues schema, or upload registers.
initial_document_validationWhenever document is first upload and data are received from AIThis webhook is triggered when document is firstly extracted and validated. It can be used for interacting with 3rd party system, adding more data or validations to the document.
document_validationWhenever document validation occursThis webhook is triggered anytime a document annotations change.

Creating a webhook

Webhook can be created via API:

curl -L \
  --request POST \
  --url '/api/v2/webhooks' \
  --header 'Authorization: Bearer JWT' \
  --header 'Content-Type: application/json' \
  --data '{
    "url": "text",
    "type": "document_status_changed",
    "entity_type": "organization",
    "entity_id": "123e4567-e89b-12d3-a456-426614174000",
    "signature_verification": "enabled"
  }'
sh

Webhook request bodies

document_status_change

{
  "document_id": "string",
  "queue_id": "string",
  "status": "string",
  "webhook_event": "document_status_change"
}
json

queue_created

{
  "workspace_id": "string",
  "queue_id": "string",
  "webhook_event": "queue_created"
}
json

initial_document_validation & document_validation

Both of these webhooks will received a full list of extracted data (or data already changed by user).

The main difference between these 2 is how fast the webhook should be. For initial validations it is ok for the webhook to be slower (seconds in response) because user has not yet had the chance to see the document and work with it.

This is the request we are sending out:

{
  "document_id": "string",
  "queue_id": "string",
  "user_id": null,
  "previous_annotations": [
    {
      "key": "iban",
      "value": "111"
    }
  ],
  "annotations": [
    {
      "key": "iban",
      "value": "999"
    },
    {
      "key": "bank_account",
      "value": "123/800",
      "values": [
        {
          "value": "123/800"
        }
      ]
    },
    {
      "key": "total_due",
      "value": "100,2",
      "numericValue": 100.2
    },
    {
      "key": "due_date",
      "value": "01.01.2021",
      "isoDateValue": "2021-01-01"
    }
  ]
}
json

For real time document validation webhook the response should be within a couple of hundred ms so it is not blocking the user from work.

[
  {
    "key": "iban",
    "value": "999"
  }
]
json

It is possible to return a response to this webhook which will be propagated to the UI. It is possible to change:

  • value of the annotated data
  • validation message
  • options for a register that will be shown only for the particular document

Here is an example of a response:

{
  "results": [
    {
      "key": "iban",
      "value": "123",
      "validationResults": [
        {
          "message": "Invalid IBAN",
          "severity": "warning"
        }
      ]
    },
    {
      "key": "line_items",
      "results": [
        {
          "key": "activity",
          "rowIndex": 0,
          "value": "123"
        }
      ]
    },
    {
      "key": "contract",
      "options": [
        {
          "label": "First Item",
          "value": "123"
        },
        {
          "label": "Second Item",
          "value": "456"
        }
      ]
    }
  ]
}
json

There are 3 types of validation result severity:

  • error -> this means a critical error and it is not possible to move this document to another status (eg. to be sent to ERP)
  • warning -> this is allowed error which does not prevent any action on the document
  • info -> info message for eg. stating that the data has been added from and external system

Signing Webhooks


Signing Webhook events allows you to verify each event was sent by Digitoo. Signature verification provides protection against bad actors spoofing webhook event payloads to look like they came from Digitoo.

Configuration

  1. A webhook signing key needs to be created for an organization (an access token with a supervisor or owner role is needed for the request)
  2. A webhook entity needs to have signature_verification: enabled

See the webhooks.md API reference for more info.
Once set up a x-digitoo-signature will be included in request headers for you to verify.

The signing key is organization-scoped and is used to sign and verify a signature for all webhook entity types within the organization.

Signing method

A signature is a hexadecimal representation of a SHA 256 HMAC of a serialized (text) request body.

function generate_signature(raw_body, signing_key):
    hmac("sha256", signing_key).data(raw_body).digest("hex")

raw_body = '{"example": "data"}' // raw (text) wehook body
signing_key = 'your_secret_key' // organization secret signing key

expected_signature = generate_signature(raw_body, signing_key)
digitoo_signature = request["x-digitoo-signature"]
signature_valid = expected_signature == digitoo_signature
javascript

Please note that for webhooks that expect some response (like document_validation), Digitoo expects a response to be signed as well so don't forget to sign the response and include x-digitoo-signature calculated by the same method, otherwise the webhook response will be rejected.