DocumentReader App

Basic information

In this section you will find general information about the Document Reader app API.

About Document Reader app API

In this documentation you will learn how to use the programming interface of the Document Reader app for configuring your own developments. The Document Reader app offer functionalities for the classification of documents with and without master data reference.

Range of functions of the Document Reader app

The Document Reader app includes text recognition, classification and document indexing. The following functions are available:

  • Importing documents to the web interface or via API call
  • Exporting batch or documents to downstream systems (such as DMS app, Azure Service Bus, SharePoint Adapter app)
  • Indexing of documents
  • Simplified permissions concept
  • Importing master data to the web interface or via API call
  • Improving recognition with the help of validated results

Using the API functions

Below, you will learn how to use the programming interface of the Document Reader app for configuring your own developments.

The Document Reader app offers a number of features. Each feature has its own endpoint. When using the API functions, please ensure that you enter the correct endpoint.

You can find the supported features and associated endpoints in the List of features.

Authentication

The API functions of the Document Reader app require a valid authentication from the IdentityProvider app.

The user with permission to use the API key has to have administrator rights.

You can find more information on authentication in the API documentation for the IdentityProvider app.

Submitting a new document for processing

Use this function to submit a document for further processing.

Request

POST /classcon-documentreader/Api/CreateDocumentRecognitionJobV2
Accept: application/json
  
{
  "Content": "Byte-Array (Base64)",
  "ContentLink": "link to the file",
  "Language": "",
  "CallbackURI": "",
  "ErrorCallbackURI": "",
  "Schema": "",
  "DocumentName": "invoice.pdf",
  "Description": "Invoice Description",
  "PageAreas": [
    "1",
    "3-5",
    "Last-1"
  ],
  "PredefinedProperties": [
    {
      "PropertyName": "ProcessingRule",
      "PropertyValue": "Api"
    }
  ],
  "InheritedProperties": {
    "ExtractedAttributes": [
      {
        "AttributeName": "OrderNum",
        "ExtractedValue": "12345678"
      },
      {
        "AttributeName": "InvoiceDate",
        "ExtractedValue": "20.01.2022"
      }
    ],
    "ExtractedTables": [
      {
        "StructureName": "positions",
        "Rows": [
          {
            "Attributes": [
              {
                "AttributeName": "Pos.Quantity",
                "ExtractedValue": "1000"
              },
              {
                "AttributeName": "Pos.Description",
                "ExtractedValue": "Mid-Range Speaker"
              },
              {
                "AttributeName": "Pos.UPrice",
                "ExtractedValue": "57,66"
              },
              {
                "AttributeName": "Pos.OrderNum",
                "ExtractedValue": "12345678"
              },
              {
                "AttributeName": "Pos.SPrice",
                "ExtractedValue": "576,60"
              },
              {
                "AttributeName": "Pos.OrderPos",
                "ExtractedValue": "1"
              },
              {
                "AttributeName": "Pos.Article",
                "ExtractedValue": "D0001"
              },
              {
                "AttributeName": "Pos.DeliveryNote",
                "ExtractedValue": "1234"
              }
            ]
          }
        ]
      }
    ]
  }
}

Notes on the properties

PropertyDescription
ContentThe actual file that is submitted as a byte array (Base64). The following formats are permitted: PDF, JPG, PNG, XML, TIF, ZIP. You can also post multiple documents in one call by submitting documents as a ZIP package.
ContentLinkYou can post the file that is to be classified in form of a link. If you specify a link, this link will always be used to retrieve the file and the value of the property Content will be ignored.
LanguageYou can use this property to specify the language used for text recognition. If no value is entered, the default language is “German”.
CallbackURIThe Callback URI is accessed once the task was completed successfully. (Optional)
ErrorCallbackURIThe ErrorCallback URI is accessed if the task was completed with errors. (Optional)
SchemaUse this property to display various master data sets. If no value is entered, the default schema will be used. If you would like to submit a value, you have to post the master data with the corresponding schema first. This value has to start with a letter. (Optional)
DocumentNameFile name of the uploaded file with extension.
DescriptionDescription of the uploaded file. In the batch summary, the description will be used as batch name. (Optional)
PageAreasA list of page areas that are relevant for processing. Possible information includes specific page numbers (e.g. "1") or banding (e.g. "3-5"). To limit processing to the last two pages, you can, for example, use the expression “Last-1”. (Optional)
PredefinedPropertiesYou can submit a list of predefined properties that are relevant for processing.
InheritedPropertiesAllows for selecting property value default settings that will be displayed in the results of document properties after processing. This applies both for header data and for position data. You can find the list of possible properties in the section Calling up classified results.

info: You have to submit the parameter PredefinedProperties as shown in the example, with the property ProcessingRule and the value API. If you do not submit this parameter, the documents will be forwarded to the processing step manual document inspection (WebIndex) and will then be exported to the configured target systems. You cannot call up the results via API request. The Document Reader app supports several predefined properties which are listed in the table below.

Supported predefined properties

PropertyDescription
ProcessingRuleIf you submit the property with the value API, you can call up the recognized results via API.
DebitorNumSet client code which identifies the client (invoice recipient) of the transferred documents.

If the document was submitted successfully, you will receive an ID in the reply in JSON format. This ID is identified as TaskId in the workflow and allows you to call up the uploaded document in later processing steps. If you have posted multiple documents, the documents will be grouped into a “batch” and the ID refers to all documents in the batch.

Response

HTTP-Statuscode 200 Ok

{
  "TaskId": "0dbbd591-432b-4c2f-8f55-640fc952f54d"
}

If an error occurs when posting the documents, a corresponding HTTP status code will be displayed and the associated error message displayed in the body. The following status codes may occur:

  • 400 Bad Request: Not able to process the request, for example due to missing request information or because the provision of master data is not supported by the product.
  • 401 Unauthorized: The supplied API key is not valid or the user does not have sufficient permission to post documents.
  • 404 Not Found: The specified customer or subscription could not be found.
  • 500 Internal Server Error: An internal error has occurred.

These HTTP status codes will also be returned in other requests, should errors occur.

When specifying a CallbackURI or a ErrorCallbackURI, the respective URL will be accessed after successful or unsuccessful processing of a batch.

The response will include the TaskId of the batch.

Response

HTTP-Statuscode 200 Ok
  
{
  "TaskId": "0dbbd591-432b-4c2f-8f55-640fc952f54d"
}

Notes on the properties

PropertyDescription
TaskIdUnique ID for the posted documents.

If the batch was processed successfully, you can call up the classified results using the TaskId. If you have not entered a value for the property CallbackURI, you can also query the status via the API.

Querying the status

After the documents were uploaded, they will complete the individual processing steps.

To determine what the current processing status of the documents is, you can query the status using the API:

Request

POST /classcon-documentreader/Api/GetProcessingStatus
Accept: application/json
   
{
  "TaskId": "0dbbd591-432b-4c2f-8f55-640fc952f54d"
}

Notes on the properties

PropertyDescription
TaskIdUnique ID for the posted documents. The ID was returned when the documents were posted.

You will receive the following JSON body as reply:

Response

HTTP-Statuscode 200 Ok
  
{
  "Status": 0
}

The status will be indicated with one of the following values:

  • 0: Documents are waiting to be processed.
  • 1: Documents are being processed.
  • 2: Documents were processed successfully. You can call up the results.
  • 3: An error has occurred while processing the documents.

If this status is returned with the value 2, you can call up the results of document classification.

You can also call up all batches that are being processed with one request:

Request

GET /classcon-documentreader/Api/GetDocumentRecognitionJobs
Accept: application/json

A list of individual batches will be provided in response:

Response

HTTP-Statuscode 200 Ok
  
[
  {
    "TaskId": "01a425eb-6b9f-4f15-8d99-29c8844f0955",
    "Position": "DataExchange",
    "Status": 2,
    "DocumentCount": 2
  },
  {
    "TaskId": "44db072f-4b40-4219-8303-fdb3f7334b63",
    "Position": "WebIndex",
    "Status": 0,
    "DocumentCount": 3
  },
  {
    "TaskId": "0c4987bf-d7f5-4136-af00-0befa65144a5",
    "Position": "WebIndex",
    "Status": 1,
    "DocumentCount": 1
  }
]

Notes on the properties

PropertyDescription
TaskIdUnique ID for the posted documents.
PositionCurrent position of the batch in processing. You can call up the batch in the position DataExchange via API. The position WebIndex indicates that the batch is undergoing visual examination. If the batch is in any other position, processing is not yet completed.
StatusCurrent status of the batch that is being processed. Identical to the status values already described.

Calling up classified results

You can call up the results of document classification in JSON format via API query. Use the following request to call up the information:

Request

POST /classcon-documentreader/Api/GetExtractedResults
Accept: application/json
   
{
  "TaskId": "0dbbd591-432b-4c2f-8f55-640fc952f54d"
}

Notes on the properties

PropertyDescription
TaskIdUnique ID for the posted documents. The ID was returned when the documents were posted.

The return value will be a list containing the classified results for each document:

Response

HTTP-Statuscode 200 Ok
 
[
  {
    "DocumentName": "Invoice",
    "Extracted": {
      "ExtractedAttributes": [
        {
          "AttributeName": "DocumentType",
          "Clues": [
            {
              "Extracted": "Invoice",
              "Zone": {
                "Bottom": 0,
                "Height": 0,
                "Left": 0,
                "Length": 0,
                "Page": 0
              }
            }
          ],
          "Confidence": 100.00000000000002,
          "ExtractedValue": "Invoice"
        },
        {
          "AttributeName": "GrossAmountCurrency",
          "Clues": [
            {
              "Extracted": "EUR",
              "Zone": {
                "Bottom": 0,
                "Height": 0,
                "Left": 0,
                "Length": 0,
                "Page": 0
              }
            }
          ],
          "Confidence": 100,
          "ExtractedValue": "EUR"
        },
        {
          "AttributeName": "DEBITOR_NUM",
          "Clues": [
            {
              "Extracted": "ceu",
              "Zone": {
                "Bottom": 0,
                "Height": 0,
                "Left": 0,
                "Length": 0,
                "Page": 0
              }
            }
          ],
          "Confidence": 100,
          "ExtractedValue": "ceu"
        },
        {
          "AttributeName": "NAME",
          "Clues": [
            {
              "Extracted": "ecstraordinary gmbh",
              "Zone": {
                "Bottom": 736,
                "Height": 36,
                "Left": 139,
                "Length": 353,
                "Page": 0
              }
            },
            {
              "Extracted": "ecstraordinary gmbh",
              "Zone": {
                "Bottom": 1100,
                "Height": 36,
                "Left": 1264,
                "Length": 354,
                "Page": 0
              }
            }
          ],
          "Confidence": 100,
          "ExtractedValue": "ecstraordinary GmbH"
        },
        {
          "AttributeName": "STR",
          "Clues": [
            {
              "Extracted": "helsinki str. 20",
              "Zone": {
                "Bottom": 1136,
                "Height": 28,
                "Left": 1266,
                "Length": 285,
                "Page": 0
              }
            }
          ],
          "Confidence": 88.23529052734375,
          "ExtractedValue": "Helsinki street 20"
        },
        {
          "AttributeName": "ZIP",
          "Clues": [
            {
              "Extracted": "81829",
              "Zone": {
                "Bottom": 859,
                "Height": 28,
                "Left": 179,
                "Length": 95,
                "Page": 0
              }
            },
            {
              "Extracted": "81829",
              "Zone": {
                "Bottom": 1179,
                "Height": 28,
                "Left": 1304,
                "Length": 95,
                "Page": 0
              }
            }
          ],
          "Confidence": 100,
          "ExtractedValue": "81829"
        },
        {
          "AttributeName": "CITY",
          "Clues": [
            {
              "Extracted": "munich",
              "Zone": {
                "Bottom": 859,
                "Height": 28,
                "Left": 295,
                "Length": 147,
                "Page": 0
              }
            },
            {
              "Extracted": "munich",
              "Zone": {
                "Bottom": 1179,
                "Height": 28,
                "Left": 1420,
                "Length": 147,
                "Page": 0
              }
            }
          ],
          "Confidence": 100,
          "ExtractedValue": "Munich"
        },
        {
          "AttributeName": "VENDOR_NUM",
          "Clues": [],
          "Confidence": 0,
          "ExtractedValue": "8001"
        },
        {
          "AttributeName": "VENDOR_NAME",
          "Clues": [
            {
              "Extracted": "schubert gmbh",
              "Zone": {
                "Bottom": 644,
                "Height": 26,
                "Left": 140,
                "Length": 235,
                "Page": 0
              }
            },
            {
              "Extracted": "schubert gmbh",
              "Zone": {
                "Bottom": 444,
                "Height": 32,
                "Left": 2036,
                "Length": 302,
                "Page": 0
              }
            },
            {
              "Extracted": "schubert gmbh",
              "Zone": {
                "Bottom": 2963,
                "Height": 32,
                "Left": 1445,
                "Length": 301,
                "Page": 0
              }
            },
            {
              "Extracted": "schubert gmbh",
              "Zone": {
                "Bottom": 3127,
                "Height": 37,
                "Left": 789,
                "Length": 290,
                "Page": 0
              }
            }
          ],
          "Confidence": 100,
          "ExtractedValue": "Schubert GmbH"
        },
        {
          "AttributeName": "VENDOR_STR",
          "Clues": [
            {
              "Extracted": "new alley 21-23",
              "Zone": {
                "Bottom": 646,
                "Height": 27,
                "Left": 408,
                "Length": 237,
                "Page": 0
              }
            },
            {
              "Extracted": "new alley 21-23",
              "Zone": {
                "Bottom": 504,
                "Height": 39,
                "Left": 2029,
                "Length": 310,
                "Page": 0
              }
            }
          ],
          "Confidence": 100,
          "ExtractedValue": "New Alley 21-23"
        },
        {
          "AttributeName": "VENDOR_CITY",
          "Clues": [
            {
              "Extracted": "weilrod",
              "Zone": {
                "Bottom": 643,
                "Height": 24,
                "Left": 779,
                "Length": 105,
                "Page": 0
              }
            },
            {
              "Extracted": "weilrod",
              "Zone": {
                "Bottom": 549,
                "Height": 31,
                "Left": 2197,
                "Length": 140,
                "Page": 0
              }
            },
            {
              "Extracted": "weilrod",
              "Zone": {
                "Bottom": 3122,
                "Height": 31,
                "Left": 1835,
                "Length": 140,
                "Page": 0
              }
            }
          ],
          "Confidence": 100,
          "ExtractedValue": "Weilrod"
        },
        {
          "AttributeName": "VENDOR_VAT_REGISTRATION_ID",
          "Clues": [
            {
              "Extracted": "de111294343",
              "Zone": {
                "Bottom": 813,
                "Height": 31,
                "Left": 2071,
                "Length": 264,
                "Page": 0
              }
            }
          ],
          "Confidence": 100,
          "ExtractedValue": "DE111294343"
        },
        {
          "AttributeName": "VENDOR_ZIP_CODE",
          "Clues": [],
          "Confidence": 0,
          "ExtractedValue": "64276"
        },
        {
          "AttributeName": "VENDOR_IBAN",
          "Clues": [
            {
              "Extracted": "de94512500000037875006",
              "Zone": {
                "Bottom": 3175,
                "Height": 31,
                "Left": 662,
                "Length": 528,
                "Page": 0
              }
            }
          ],
          "Confidence": 100,
          "ExtractedValue": "DE94512500000037875006"
        },
        {
          "AttributeName": "OrderNum",
          "Clues": [
            {
              "Extracted": "00000252",
              "Zone": {
                "Bottom": 1393,
                "Height": 27,
                "Left": 511,
                "Length": 168,
                "Page": 0
              }
            }
          ],
          "Confidence": 100,
          "ExtractedValue": "00000252"
        },
        {
          "AttributeName": "GrossAmount",
          "Clues": [
            {
              "Extracted": "885.12",
              "Zone": {
                "Bottom": 2771,
                "Height": 31,
                "Left": 2202,
                "Length": 114,
                "Page": 0
              }
            }
          ],
          "Confidence": 100,
          "ExtractedValue": "885,12"
        },
        {
          "AttributeName": "NetAmount1",
          "Clues": [
            {
              "Extracted": "743.80",
              "Zone": {
                "Bottom": 2531,
                "Height": 31,
                "Left": 2202,
                "Length": 114,
                "Page": 0
              }
            }
          ],
          "Confidence": 100,
          "ExtractedValue": "743,80"
        },
        {
          "AttributeName": "VatRate1",
          "Clues": [
            {
              "Extracted": "19 %",
              "Zone": {
                "Bottom": 2606,
                "Height": 25,
                "Left": 1837,
                "Length": 74,
                "Page": 0
              }
            }
          ],
          "Confidence": 100,
          "ExtractedValue": "19,00"
        },
        {
          "AttributeName": "VatAmount1",
          "Clues": [
            {
              "Extracted": "141.32",
              "Zone": {
                "Bottom": 2611,
                "Height": 31,
                "Left": 2205,
                "Length": 108,
                "Page": 0
              }
            }
          ],
          "Confidence": 100,
          "ExtractedValue": "141,32"
        },
        {
          "AttributeName": "InvoiceNumber",
          "Clues": [
            {
              "Extracted": "20190527-V1",
              "Zone": {
                "Bottom": 900,
                "Height": 25,
                "Left": 2136,
                "Length": 198,
                "Page": 0
              }
            }
          ],
          "Confidence": 100,
          "ExtractedValue": "20190527-V1"
        },
        {
          "AttributeName": "InvoiceDate",
          "Clues": [
            {
              "Extracted": "27.05.19",
              "Zone": {
                "Bottom": 942,
                "Height": 25,
                "Left": 2208,
                "Length": 128,
                "Page": 0
              }
            }
          ],
          "Confidence": 100,
          "ExtractedValue": "27.05.2019"
        }
      ],
      "ExtractedTables": [
        {
          "StructureName": "positions",
          "Rows": [
            {
              "Attributes": [
                {
                  "AttributeName": "Pos.Quantity",
                  "Clues": [
                    {
                      "Extracted": "10",
                      "Zone": {
                        "Bottom": 1967,
                        "Height": 27,
                        "Left": 144,
                        "Length": 36,
                        "Page": 0
                      }
                    }
                  ],
                  "Confidence": 60,
                  "ExtractedValue": "10"
                },
                {
                  "AttributeName": "Pos.Description",
                  "Clues": [
                    {
                      "Extracted": "Mid-Range Speaker",
                      "Zone": {
                        "Bottom": 1976,
                        "Height": 36,
                        "Left": 557,
                        "Length": 326,
                        "Page": 0
                      }
                    }
                  ],
                  "Confidence": 60,
                  "ExtractedValue": "Mid-Range Speaker"
                },
                {
                  "AttributeName": "Pos.UPrice",
                  "Clues": [
                    {
                      "Extracted": "57.66",
                      "Zone": {
                        "Bottom": 1971,
                        "Height": 31,
                        "Left": 1931,
                        "Length": 90,
                        "Page": 0
                      }
                    }
                  ],
                  "Confidence": 60,
                  "ExtractedValue": "57,66"
                },
                {
                  "AttributeName": "Pos.OrderNum",
                  "Clues": [
                    {
                      "Extracted": "00000252",
                      "Zone": {
                        "Bottom": 1393,
                        "Height": 27,
                        "Left": 511,
                        "Length": 168,
                        "Page": 0
                      }
                    }
                  ],
                  "Confidence": 60,
                  "ExtractedValue": "00000252"
                },
                {
                  "AttributeName": "Pos.SPrice",
                  "Clues": [
                    {
                      "Extracted": "576,60",
                      "Zone": {
                        "Bottom": 1971,
                        "Height": 31,
                        "Left": 2202,
                        "Length": 114,
                        "Page": 0
                      }
                    }
                  ],
                  "Confidence": 60,
                  "ExtractedValue": "576,60"
                },
                {
                  "AttributeName": "Pos.OrderPos",
                  "Clues": [
                    {
                      "Extracted": "1",
                      "Zone": {
                        "Bottom": 0,
                        "Height": 0,
                        "Left": 0,
                        "Length": 0,
                        "Page": 0
                      }
                    }
                  ],
                  "Confidence": 60,
                  "ExtractedValue": "1"
                },
                {
                  "AttributeName": "Pos.Article",
                  "Clues": [
                    {
                      "Extracted": "D0001",
                      "Zone": {
                        "Bottom": 0,
                        "Height": 0,
                        "Left": 0,
                        "Length": 0,
                        "Page": 0
                      }
                    }
                  ],
                  "Confidence": 60,
                  "ExtractedValue": "D0001"
                },
                {
                  "AttributeName": "Pos.DeliveryNote",
                  "Clues": [
                    {
                      "Extracted": "--",
                      "Zone": {
                        "Bottom": 0,
                        "Height": 0,
                        "Left": 0,
                        "Length": 0,
                        "Page": 0
                      }
                    }
                  ],
                  "Confidence": 60,
                  "ExtractedValue": "--"
                }
              ],
              "Score": 0
            },
            {
              "Attributes": [
                {
                  "AttributeName": "Pos.Quantity",
                  "Clues": [
                    {
                      "Extracted": "10",
                      "Zone": {
                        "Bottom": 2047,
                        "Height": 27,
                        "Left": 144,
                        "Length": 36,
                        "Page": 0
                      }
                    }
                  ],
                  "Confidence": 60,
                  "ExtractedValue": "10"
                },
                {
                  "AttributeName": "Pos.Description",
                  "Clues": [
                    {
                      "Extracted": "StandardSpeaker",
                      "Zone": {
                        "Bottom": 0,
                        "Height": 0,
                        "Left": 0,
                        "Length": 0,
                        "Page": 0
                      }
                    }
                  ],
                  "Confidence": 60,
                  "ExtractedValue": "StandardSpeaker"
                },
                {
                  "AttributeName": "Pos.UPrice",
                  "Clues": [
                    {
                      "Extracted": "16.78",
                      "Zone": {
                        "Bottom": 2051,
                        "Height": 31,
                        "Left": 1934,
                        "Length": 90,
                        "Page": 0
                      }
                    }
                  ],
                  "Confidence": 60,
                  "ExtractedValue": "16,78"
                },
                {
                  "AttributeName": "Pos.OrderNum",
                  "Clues": [
                    {
                      "Extracted": "00000252",
                      "Zone": {
                        "Bottom": 1393,
                        "Height": 27,
                        "Left": 511,
                        "Length": 168,
                        "Page": 0
                      }
                    }
                  ],
                  "Confidence": 60,
                  "ExtractedValue": "00000252"
                },
                {
                  "AttributeName": "Pos.SPrice",
                  "Clues": [
                    {
                      "Extracted": "167,80",
                      "Zone": {
                        "Bottom": 2051,
                        "Height": 31,
                        "Left": 2205,
                        "Length": 108,
                        "Page": 0
                      }
                    }
                  ],
                  "Confidence": 60,
                  "ExtractedValue": "167,80"
                },
                {
                  "AttributeName": "Pos.OrderPos",
                  "Clues": [
                    {
                      "Extracted": "2",
                      "Zone": {
                        "Bottom": 0,
                        "Height": 0,
                        "Left": 0,
                        "Length": 0,
                        "Page": 0
                      }
                    }
                  ],
                  "Confidence": 60,
                  "ExtractedValue": "2"
                },
                {
                  "AttributeName": "Pos.Article",
                  "Clues": [
                    {
                      "Extracted": "D0002",
                      "Zone": {
                        "Bottom": 0,
                        "Height": 0,
                        "Left": 0,
                        "Length": 0,
                        "Page": 0
                      }
                    }
                  ],
                  "Confidence": 60,
                  "ExtractedValue": "D0002"
                },
                {
                  "AttributeName": "Pos.DeliveryNote",
                  "Clues": [
                    {
                      "Extracted": "--",
                      "Zone": {
                        "Bottom": 0,
                        "Height": 0,
                        "Left": 0,
                        "Length": 0,
                        "Page": 0
                      }
                    }
                  ],
                  "Confidence": 60,
                  "ExtractedValue": "--"
                }
              ],
              "Score": 0
            }
          ]
        }
      ]
    }
  }
]

Notes on the properties

PropertyDescription
DocumentNameName of the document so that the result can be unequivocally matched to one document. If you have submitted the documents as a .ZIP package, the file name of the .ZIP package will be used as the property DocumentName. The document name specified when posting the .ZIP package is irrelevant.
ExtractedContains the extracted results on the position level and property level.
ExtractedAttributesExtracted results on the property level
ExtractedTablesExtracted results on position level
StructureNameName of the position level. The value positions indicates order lines.
RowsEach row has the same number of properties, for example Order quantity of the item.

Structure of an extracted property

The property consists of an extracted value and the following additional information:

PropertyDescription
AttributeNameName of the property.
ExtractedValueExtracted value that was determined based on the document or using the master data.
ConfidenceProvides information about the accuracy of a classified result. The maximum value is 100.
CluesPosition in the document from which the result was extracted.
ExtractedValue extracted from the document. This value does not have to be identical to the ExtractedValue because the master data is called up using the extracted value.
ZoneThe exact position of the extracted value in the document. The property Page indicates the page. If the value was extracted from the first page, Page has the value “0”.

The following properties are classified on the property level by the Document Reader app (invoice reader business feature):

Client properties

PropertyDescription
DEBITOR_NUMClient number.
NAMEClient name.
STRClient street.
CITYClient city of residence.
ZIPClient ZIP code.

Supplier properties

PropertyDescription
VENDOR_NUMSupplier number.
VENDOR_NAMESupplier name.
VENDOR_STRSupplier street.
VENDOR_CITYSupplier city.
VENDOR_ZIP_CODESupplier ZIP code.
VENDOR_VAT_REGISTRATION_IDSupplier VAT ID.
VENDOR_REGISTRATION_IDSupplier tax number.
VENDOR_IBANSupplier IBAN.

Invoice data properties

PropertyDescription
DocumentTypeDocument type. The following values are possible: Invoice, CreditAdvice, CorrectionOfInvoice
InvoiceNumberInvoice number.
InvoiceDateInvoice date.
PerformanceDatePerformance date.
OrderNumOrder number.
GrossAmountCurrencyCurrency.
GrossAmountGross value.
AdditionalCostsAdditional costs, such as transport costs.
NetAmount1Net value 1.
VatRate1Tax rate 1.
VatAmount1Tax value 1.
NetAmount2Net value 2.
VatRate2Tax rate 2.
VatAmount2Tax value 2.

The following properties are classified on the position level by the Document Reader app:

Order item properties

PropertyDescription
Pos.OrderNumOrder number.
Pos.OrderPosOrder item.
Pos.UPriceUnit price.
Pos.SPriceTotal price.
Pos.QuantityQuantity.
Pos.ArticleArticle no.
Pos.DescriptionItem description.
Pos.DeliveryNoteDelivery note number.

The following additional properties are extracted from QR invoices:

Additional properties QR invoice

PropertyDescription
QR-IBANQR IBAN.
QR-REFERENCEQR REFERENCE.

If a property has no value attached to it, the property will not be listed in the classified results.

Transmitting validated results

If the information in a document was not recognized and not extracted correctly, you can correct the information. Your corrections also train the auto trainer, which improves the quality of property recognition. To correct extracted information and to train the auto trainer, you have to return the corrected values. Use the following request to transmit the corrected values:

Request

POST /classcon-documentreader/Api/RegisterValidatedValuesV2
Accept: application/json
  
{
  "TaskId": "0dbbd591-432b-4c2f-8f55-640fc952f54d",
  "ProvedResults": [
    {
      "DocumentName": "Invoice",
      "Extracted": {
        "ExtractedAttributes": [
          {
            "AttributeName": "GrossAmountCurrency",
            "ExtractedValue": "EUR"
          },
          {
            "AttributeName": "DEBITOR_NUM",
            "ExtractedValue": "ceu"
          },
          {
            "AttributeName": "NAME",
            "ExtractedValue": "ecstraordinary GmbH"
          },
          {
            "AttributeName": "STR",
            "ExtractedValue": "Helsinki Street 20"
          },
          {
            "AttributeName": "ZIP",
            "ExtractedValue": "81829"
          },
          {
            "AttributeName": "CITY",
            "ExtractedValue": "Munich"
          },
          {
            "AttributeName": "VENDOR_NUM",
            "ExtractedValue": "8001"
          },
          {
            "AttributeName": "VENDOR_NAME",
            "ExtractedValue": "Schubert GmbH"
          },
          {
            "AttributeName": "VENDOR_STR",
            "ExtractedValue": "New Alley 21-23"
          },
          {
            "AttributeName": "VENDOR_CITY",
            "ExtractedValue": "Weilrod"
          },
          {
            "AttributeName": "VENDOR_VAT_REGISTRATION_ID",
            "ExtractedValue": "DE111294343"
          },
          {
            "AttributeName": "VENDOR_ZIP_CODE",
            "ExtractedValue": "64276"
          },
          {
            "AttributeName": "VENDOR_IBAN",
            "ExtractedValue": "DE94512500000037875006"
          },
          {
            "AttributeName": "OrderNum",
            "ExtractedValue": "00000252"
          },
          {
            "AttributeName": "GrossAmount",
            "ExtractedValue": "885.12"
          },
          {
            "AttributeName": "NetAmount1",
            "ExtractedValue": "743.80"
          },
          {
            "AttributeName": "VatRate1",
            "ExtractedValue": "19.00"
          },
          {
            "AttributeName": "VatAmount1",
            "ExtractedValue": "141.32"
          },
          {
            "AttributeName": "InvoiceNumber",
            "ExtractedValue": "20190527-V1"
          },
          {
            "AttributeName": "InvoiceDate",
            "ExtractedValue": "27.05.2019"
          },
          {
            "AttributeName": "DocumentType",
            "ExtractedValue": "Invoice"
          }
        ],
        "ExtractedTables": [
          {
            "StructureName": "positions",
            "Rows": [
              {
                "Attributes": [
                  {
                    "AttributeName": "Pos.OrderNum",
                    "ExtractedValue": "00000252"
                  },
                  {
                    "AttributeName": "Pos.UPrice",
                    "ExtractedValue": "57.66"
                  },
                  {
                    "AttributeName": "Pos.SPrice",
                    "ExtractedValue": "576.60"
                  },
                  {
                    "AttributeName": "Pos.Quantity",
                    "ExtractedValue": "10"
                  },
                  {
                    "AttributeName": "Pos.OrderPos",
                    "ExtractedValue": "1"
                  },
                  {
                    "AttributeName": "Pos.DeliveryNote",
                    "ExtractedValue": "--"
                  },
                  {
                    "AttributeName": "Pos.Article",
                    "ExtractedValue": "D0001"
                  },
                  {
                    "AttributeName": "Pos.Description",
                    "ExtractedValue": "Mid-Range Speaker"
                  }
                ]
              },
              {
                "Attributes": [
                  {
                    "AttributeName": "Pos.OrderNum",
                    "ExtractedValue": "00000252"
                  },
                  {
                    "AttributeName": "Pos.UPrice",
                    "ExtractedValue": "16.78"
                  },
                  {
                    "AttributeName": "Pos.SPrice",
                    "ExtractedValue": "167.80"
                  },
                  {
                    "AttributeName": "Pos.Quantity",
                    "ExtractedValue": "10"
                  },
                  {
                    "AttributeName": "Pos.OrderPos",
                    "ExtractedValue": "2"
                  },
                  {
                    "AttributeName": "Pos.DeliveryNote",
                    "ExtractedValue": "--"
                  },
                  {
                    "AttributeName": "Pos.Article",
                    "ExtractedValue": "D0002"
                  },
                  {
                    "AttributeName": "Pos.Description",
                    "ExtractedValue": "StandardSpeaker"
                  }
                ]
              }
            ]
          }
        ]
      }
    }
  ]
}

Notes on the properties

PropertyDescription
TaskIdUnique ID for the posted documents. The ID was returned when the documents were posted.
ProvedResultsThe corrected property values. The structure is identical to the JSON structure received when calling up the results. When transmitting the validated results, you only have to enter the properties AttributeName and ExtractedValue for the individual validated properties.

To train the auto trainer using the document, you have to have previously called up the results for the extracted properties via API.

To ensure that you submit the corrected results for the correct document, you have to enter both the ID of the documents submitted (TaskId) and the name of the document as the property DocumentName. If an ID is assigned to multiple documents, you can submit the validated results for multiple documents in one request. The property DocumentName is the name of the document in the .ZIP package.

If the validated results were uploaded successfully, the following HTTP status code will be returned:

Response

HTTP-Statuscode 200 Ok

Posting master data

You can post master data to support the processing of the documents. You can only use this function for features for which separate master data are activated. The features for which this is the case are shown in the List of features.

Use the following request for submitting master data:

Request

POST /classcon-documentreader/Api/ImportMasterFilesV2
Accept: application/json
  
{
  "Content": "Byte-Array (Base64)",
  "ContentLink": "Link to the file",
  "Schema": "",
  "DocumentName": "masterdata.zip",
  "MasterDataTableList": [
    {
      "TableName": "CC_COMPANIES",
      "ExpectedRowCount": 3
    },
    {
      "TableName": "CC_VENDORS",
      "ExpectedRowCount": 5
    },
    {
      "TableName": "CC_VENDOR_BANK",
      "ExpectedRowCount": 9
    },
    {
      "TableName": "CC_ORDERS",
      "ExpectedRowCount": 9
    },
    {
      "TableName": "CC_ORDERLINES",
      "ExpectedRowCount": 19
    },
    {
      "TableName": "CC_RECEIPTS",
      "ExpectedRowCount": 19
    },
    {
      "TableName": "EXTENDED_VENDOR_SETTINGS",
      "ExpectedRowCount": 10
    }
  ]
}

Notes on the properties

PropertyDescription
ContentThe actual file that is submitted as a byte array (Base64). The following formats are permitted: CSV, ZIP. You can submit multiple sets of master data in one call.
ContentLinkYou can post the file that contains the master data as a link. If you specify a link, this link will always be used to retrieve the file and the value of the property Content will be ignored.
SchemaYou can use this property to display various master data sets. If no value is entered, the default schema will be used. This value has to start with a letter. (Optional)
DocumentNameFile name of the uploaded file with extension.
MasterDataTableListYou can submit additional information on the master data table. This information is used to help recognize errors at an early stage. (Optional)

You can enter the following information for each table:

PropertyDescription
TableNameThe name of the table, so that the information can be allocated.
ExpectedRowCountSpecify the number of expected rows the table has to have at the end of the import process. You can check potential deviations in the master data section of the Document Reader app.

If the master data were posted successfully, the following HTTP status code will be returned:

Response

HTTP-Statuscode 200 Ok

In addition to importing master data with CSV or ZIP files, you can also transfer master data directly as JSON call:

Request

POST /classcon-documentreader/Api/ImportMasterData
Accept: application/json
  
{
  "Schema": "",
  "Tables": [
    {
      "TableName": "CC_Companies",
      "MasterData": [
        {
          "COMPANY_NUM": "01",
          "NAME": "Solbau GmbH",
          "STR": "Baustraße 40",
          "ZIP": "46395",
          "CITY": "Bocholt",
          "BLACK": ""
        },
        {
          "COMPANY_NUM": "ceu",
          "NAME": "ecstraordinary GmbH",
          "STR": "Helsinkistraße 20",
          "ZIP": "81829",
          "CITY": "München",
          "BLACK": ""
        }
      ]
    },
    {
      "TableName": "CC_Vendors",
      "MasterData": [
        {
          "COMPANY_NUM": "01",
          "VENDOR_NUM": "00000",
          "VENDOR_NAME": "Blonk GmbH",
          "VENDOR_STR": "Westmüllerstraße 13",
          "VENDOR_ZIP_CODE": "49219",
          "VENDOR_CITY": "Glandorf",
          "VENDOR_COUNTRY": "DE",
          "VENDOR_EMAIL": "",
          "VENDOR_VAT_REGISTRATION_ID": "DE812906932",
          "VENDOR_REGISTRATION_ID": "316571003391",
          "VENDOR_PHONE_NUMBER": ""
        }
      ]
    }
  ]
}

Notes on the properties

PropertyDescription
SchemaUse this property to display various master data sets. If no value is entered, the default schema will be used. This value has to start with a letter. (Optional)
TablesWhen calling, you can transfer master data for multiple tables. An import is performed for each table in the list.

You must enter the following information for each table:

PropertyDescription
TableNameThe table name for which the listed master data sets should be imported from the property MasterData.
MasterDataThe list of master data sets which should be provided in the respective table. Each entry in the list has to contain all properties, even if the corresponding value is not filled in.

If the master data were posted successfully, the following HTTP status code will be returned:

Response

HTTP-Statuscode 200 Ok

The posted master data will not be available immediately. The data will be reviewed again after a service was made available and will then be integrated into the system. This process may take a few seconds.

The basic version of the DocumentReader app works without separately provided master data.

Using the API functions in the Process app

You can use the API of the Document Reader app to make the classification of documents available for the Process app as an asynchronous service.

You have to start a different process for each document that is to be classified.

To start an asynchronous process for a document, the Process app requires the following information:

  • documentName: Name of the document with extension, e.g. Invoice.pdf.
  • documentFileLink: Link to the document.
  • documentOcrLink (optional): Link to the OCR file used for classification. The permitted file types are .hocr and .addx. If you have not specified a link, text recognition will be performed by the Document Reader app.

The following example process illustrates all properties that the Document Reader app returns to the Process app.

Example process BPMN

<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" targetNamespace="">
  <process id="DocumentReaderBusinessAPI" name="Document Reader Business API Demo" isExecutable="true">
    <extensionElements>
      <camunda:properties>
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:in:documentName" value="String" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:in:documentMimeType" value="String" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:in:documentFileLink" value="URL" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:in:documentOcrLink" value="URL" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:vendorNum" value="String" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:vendorName" value="String" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:vendorCity" value="String" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:vendorStreet" value="String" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:vendorZipCode" value="String" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:vendorVatRegistrationId" value="String" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:vendorRegistrationId" value="String" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:vendorIban" value="String" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:companyNum" value="String" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:companyName" value="String" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:companyCity" value="String" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:companyStreet" value="String" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:companyZipCode" value="String" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:invoiceNumber" value="String" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:invoiceDate" value="String" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:performanceDate" value="String" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:documentType" value="String" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:grossAmountCurrency" value="String" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:grossAmount" value="Number" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:additionalCosts" value="Number" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:netAmount1" value="Number" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:vatAmount1" value="Number" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:vatRate1" value="Number" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:netAmount2" value="Number" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:vatAmount2" value="Number" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:vatRate2" value="Number" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:orderNum" value="String" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:pos_orderNum" value="[String]" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:pos_unitPrice" value="[Number]" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:pos_sumPrice" value="[Number]" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:pos_quantity" value="[String]" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:pos_orderPosition" value="[String]" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:pos_deliveryNote" value="[String]" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:pos_articleNum" value="[String]" />
        <camunda:property name="service:/classcon-documentreader/DataExchange/UploadProcessApp:out:pos_description" value="[String]" />
        <camunda:property name="variable:documentName" value="String" />
        <camunda:property name="variable:documentMimeType" value="String" />
        <camunda:property name="variable:documentFileLink" value="URL" />
        <camunda:property name="variable:documentOcrLink" value="URL" />
        <camunda:property name="variable:vendorNum" value="String" />
        <camunda:property name="variable:vendorName" value="String" />
        <camunda:property name="variable:vendorCity" value="String" />
        <camunda:property name="variable:vendorStreet" value="String" />
        <camunda:property name="variable:vendorZipCode" value="String" />
        <camunda:property name="variable:vendorVatRegistrationId" value="String" />
        <camunda:property name="variable:vendorRegistrationId" value="String" />
        <camunda:property name="variable:vendorIban" value="String" />  
        <camunda:property name="variable:companyNum" value="String" />
        <camunda:property name="variable:companyName" value="String" />
        <camunda:property name="variable:companyCity" value="String" />
        <camunda:property name="variable:companyStreet" value="String" />
        <camunda:property name="variable:companyZipCode" value="String" />
        <camunda:property name="variable:invoiceNumber" value="String" />
        <camunda:property name="variable:invoiceDate" value="String" />
        <camunda:property name="variable:performanceDate" value="String" />
        <camunda:property name="variable:documentType" value="String" />
        <camunda:property name="variable:grossAmountCurrency" value="String" />
        <camunda:property name="variable:grossAmount" value="Number" />
        <camunda:property name="variable:additionalCosts" value="Number" />
        <camunda:property name="variable:netAmount1" value="Number" />
        <camunda:property name="variable:vatAmount1" value="Number" />
        <camunda:property name="variable:vatRate1" value="Number" />
        <camunda:property name="variable:netAmount2" value="Number" />
        <camunda:property name="variable:vatAmount2" value="Number" />
        <camunda:property name="variable:vatRate2" value="Number" />
        <camunda:property name="variable:orderNum" value="String" />
        <camunda:property name="variable:pos_orderNum" value="[String]" />
        <camunda:property name="variable:pos_unitPrice" value="[Number]" />
        <camunda:property name="variable:pos_sumPrice" value="[Number]" />
        <camunda:property name="variable:pos_quantity" value="[String]" />
        <camunda:property name="variable:pos_orderPosition" value="[String]" />
        <camunda:property name="variable:pos_deliveryNote" value="[String]" />
        <camunda:property name="variable:pos_articleNum" value="[String]" />
        <camunda:property name="variable:pos_description" value="[String]" />
      </camunda:properties>
    </extensionElements>    
    <startEvent id="start"/>
    <sendTask id="call_documentReaderAPI" name="Call 'Document Reader API'" camunda:delegateExpression="${asyncService}" camunda:asyncBefore="true" camunda:exclusive="true">
      <extensionElements>
            <camunda:inputOutput>
                <camunda:inputParameter name="service.uri">/classcon-documentreader/DataExchange/UploadProcessApp</camunda:inputParameter>
                <camunda:inputParameter name="documentName">${variables.get("documentName")}</camunda:inputParameter>
                <camunda:inputParameter name="documentMimeType">${variables.get("documentMimeType")}</camunda:inputParameter>
                <camunda:inputParameter name="documentFileLink">${variables.get("documentFileLink")}</camunda:inputParameter>
                <camunda:inputParameter name="documentOcrLink">${variables.get("documentOcrLink")}</camunda:inputParameter>
            </camunda:inputOutput>
        </extensionElements>
    </sendTask>
    <receiveTask id="receive_documentReaderAPI" name="Wait for 'Document Reader API'" camunda:asyncAfter="true" camunda:exclusive="true">
      <extensionElements>
            <camunda:inputOutput>
                <camunda:outputParameter name="vendorNum">${variables.get("vendorNum")}</camunda:outputParameter>
                <camunda:outputParameter name="vendorName">${variables.get("vendorName")}</camunda:outputParameter>
                <camunda:outputParameter name="vendorCity">${variables.get("vendorCity")}</camunda:outputParameter>
                <camunda:outputParameter name="vendorStreet">${variables.get("vendorStreet")}</camunda:outputParameter>
                <camunda:outputParameter name="vendorZipCode">${variables.get("vendorZipCode")}</camunda:outputParameter>
                <camunda:outputParameter name="vendorVatRegistrationId">${variables.get("vendorVatRegistrationId")}</camunda:outputParameter>
                <camunda:outputParameter name="vendorRegistrationId">${variables.get("vendorRegistrationId")}</camunda:outputParameter>
                <camunda:outputParameter name="vendorIban">${variables.get("vendorIban")}</camunda:outputParameter>
                <camunda:outputParameter name="companyNum">${variables.get("companyNum")}</camunda:outputParameter>
                <camunda:outputParameter name="companyName">${variables.get("companyName")}</camunda:outputParameter>
                <camunda:outputParameter name="companyCity">${variables.get("companyCity")}</camunda:outputParameter>
                <camunda:outputParameter name="companyStreet">${variables.get("companyStreet")}</camunda:outputParameter>
                <camunda:outputParameter name="companyZipCode">${variables.get("companyZipCode")}</camunda:outputParameter>
                <camunda:outputParameter name="invoiceNumber">${variables.get("invoiceNumber")}</camunda:outputParameter>
                <camunda:outputParameter name="invoiceDate">${variables.get("invoiceDate")}</camunda:outputParameter>
                <camunda:outputParameter name="performanceDate">${variables.get("performanceDate")}</camunda:outputParameter>
                <camunda:outputParameter name="documentType">${variables.get("documentType")}</camunda:outputParameter>
                <camunda:outputParameter name="grossAmountCurrency">${variables.get("grossAmountCurrency")}</camunda:outputParameter>
                <camunda:outputParameter name="grossAmount">${variables.get("grossAmount")}</camunda:outputParameter>
                <camunda:outputParameter name="additionalCosts">${variables.get("additionalCosts")}</camunda:outputParameter>
                <camunda:outputParameter name="netAmount1">${variables.get("netAmount1")}</camunda:outputParameter>
                <camunda:outputParameter name="vatAmount1">${variables.get("vatAmount1")}</camunda:outputParameter>
                <camunda:outputParameter name="vatRate1">${variables.get("vatRate1")}</camunda:outputParameter>
                <camunda:outputParameter name="netAmount2">${variables.get("netAmount2")}</camunda:outputParameter>
                <camunda:outputParameter name="vatAmount2">${variables.get("vatAmount2")}</camunda:outputParameter>
                <camunda:outputParameter name="vatRate2">${variables.get("vatRate2")}</camunda:outputParameter>
                <camunda:outputParameter name="orderNum">${variables.get("orderNum")}</camunda:outputParameter>
                <camunda:outputParameter name="pos_orderNum">${variables.get("pos_orderNum")}</camunda:outputParameter>
                <camunda:outputParameter name="pos_unitPrice">${variables.get("pos_unitPrice")}</camunda:outputParameter>
                <camunda:outputParameter name="pos_sumPrice">${variables.get("pos_sumPrice")}</camunda:outputParameter>
                <camunda:outputParameter name="pos_quantity">${variables.get("pos_quantity")}</camunda:outputParameter>
                <camunda:outputParameter name="pos_orderPosition">${variables.get("pos_orderPosition")}</camunda:outputParameter>
                <camunda:outputParameter name="pos_deliveryNote">${variables.get("pos_deliveryNote")}</camunda:outputParameter>
                <camunda:outputParameter name="pos_articleNum">${variables.get("pos_articleNum")}</camunda:outputParameter>
                <camunda:outputParameter name="pos_description">${variables.get("pos_description")}</camunda:outputParameter>
            </camunda:inputOutput>
        </extensionElements>
    </receiveTask>
    <endEvent id="end"/>       
    <sequenceFlow id="s1" sourceRef="start" targetRef="call_documentReaderAPI" />
    <sequenceFlow id="s2" sourceRef="call_documentReaderAPI" targetRef="receive_documentReaderAPI" />
    <sequenceFlow id="s3" sourceRef="receive_documentReaderAPI" targetRef="end" />
  </process> 
</definitions>

Serverless hooks

The Document Reader app offers multiple entry points that can be accessed while processing is in progress. When an entry point is reached, a message is sent to the Azure Service Bus queue. The queue can be monitored by an Azure Function, which can then be used as an additional processing step. This allows you to edit properties or to execute additional functions based on a property value. You can also access master data in the database. If a document is submitted to the Document Reader app using the Inbound app, the Inbound app properties can also be evaluated.

The following entry points are available as standard:

  • After extraction: Classification is complete and the recognized property values can be processed further.
  • Before extraction: Setting default values for properties.
  • After indexing: Validated properties can be enhanced with additional information prior to exporting them.

You have to enter the connection string and Azure Service Bus queue in the configuration for the corresponding entry point.

Using serverless hooks

Below you can find the implementation of a serverless hook in the programming language C#. A NuGet package is available for using the basic functionalities. The name of the package is Classcon.Cloud.ServerlessHooks and you can find it in the d.velop nuget feed. Please contact your d.velop contact if you would like to source the package externally.

Example 1 Changing the Client name based on the Client number

    public class DRaaSScriptingTest
    {
        [FunctionName("PostExtractionHook")]
        public void Run([ServiceBusTrigger("postextraction_queue", Connection = "ServiceBusConnectionString")]string myQueueItem)
        {
            /*Creates a new object of the class "Context".
            Context contains all documents to be processed in a list.*/
            Context context = new Context(myQueueItem);
            foreach (Document document in context.DocumentList)
            {
                //Checks whether a document has the client number "ceu".
                if (document.GetAttribute("DEBITOR_NUM") != null && document.GetAttribute("DEBITOR_NUM").ExtractedValue.Equals("ceu"))
                {
                    //The name of the client is changed.
                    document.SetAttribute("DEBITOR_NUM", "Test Debitor");
                }
            }

            //Writes the changes made to the Azure blob memory and reports back successful processing.            
            context.Commit();
        }
    }

Example 2 Entering the Client based on a property added in the Inbound app

    public class DRaaSScriptingTest
    {
        [FunctionName("PostExtractionHook")]
        public void Run([ServiceBusTrigger("postextraction_queue", Connection = "ServiceBusConnectionString")]string myQueueItem)
        {
            /*Creates a new object of the class "Context".
            Context contains all documents to be processed in a list.*/
            Context context = new Context(myQueueItem);
            foreach (Document document in context.DocumentList)
            {
                //Checks whether an inbound property is filled with a value and sets the client depending on this.
                InboundProperty inboundProperty = document.GetInboundProperty("InboundDebitorProperty");
                if (inboundProperty != null && inboundProperty.PropertyValues != null && inboundProperty.PropertyValues.Count > 0)
                {
                    //Establish an SQL connection to the database.
                    using (SqlConnection sqlConnection = new SqlConnection(context.DBConnectionString))
                    {
                        //Query the client from the master data.
                        using (SqlCommand command = new SqlCommand(string.Format("SELECT * FROM CC_COMPANIES WHERE COMPANY_NUM='{0}'", inboundProperty.PropertyValues[0]), sqlConnection))
                        {
                            sqlConnection.Open();
                            using (SqlDataReader reader = command.ExecuteReader())
                            {
                                if (reader.Read())
                                {
                                    document.SetAttribute("DEBITOR_NUM", reader["COMPANY_NUM"].ToString());
                                    document.SetAttribute("NAME", reader["NAME"].ToString());
                                    document.SetAttribute("STR", reader["STR"].ToString());
                                    document.SetAttribute("CITY", reader["CITY"].ToString());
                                    document.SetAttribute("ZIP", reader["ZIP"].ToString());
                                }
                            }
                        }
                    }
                }
            }

            //Writes the changes made to the Azure blob memory and reports back successful processing.           
            context.Commit();
        }
    }

Features

The Document Reader app supports the following features:

FeatureEndpointSupported configuration profilesSeparate master data
Invoice reader businessclasscon-documentreaderd.velop invoices, SAPYes
Invoice reader basicclasscon-genericinvoicesNo
Invoice reader business (real estate)classconinvoicesrealestateYes
Invoice reader business (US)classconinvoicesusYes
Invoice reader business (2)classconinvoicesv2Yes
Invoice reader business (3)classconinvoicesv3Yes
Intelligent mail distributionclassconmailroutingYes
Order confirmation readerclassconorderconfirmationsYes
Order readerclassconordersYes
Personnel documentsclassconpersonnelfilesYes
Delivery note readerclasscondeliverynotesYes
Customs export documentsclassconcustomsexportdocsYes
ContractsclassconcontractsYes
Dynamic classificationclasscondynamicclassificationYes
Generic recognition appclasscongenericNo

Configuration and activation of a feature

You can activate and configure a feature by calling up the following endpoint.

Request

POST /classcon-documentreader/Api/Setup
Accept: application/json
  
{
  "Profiles": [
    "d.velop invoices"
  ],
  "TargetSystems": [],
  "RoutingRules": [],
  "MasterDataDefinitions": []
}

Notes on the properties

PropertyDescription
ProfilesYou can activate various pre-defined configurations using profiles. When activated, target systems, routing rules and master data are automatically added to a feature. You can find the supported configuration profiles in the List of features.
TargetSystemsA list of target systems which are to be added when activating the feature. (optional)
RoutingRulesA list of routing rules which are to be added when activating the feature. (Optional)
MasterDataDefinitionsA list of master data structures which are to be added when activating the feature. (Optional)

Features are configured in the background. You can check the status of a feature on the configuration page Features of the Document Reader app.

Response

HTTP-Statuscode 200 Ok

Below you can find an example call for submitting additional target systems, routing rules and master data structures

Request

POST /classcon-documentreader/Api/Setup
Accept: application/json
  
{
  "Profiles": [
    "d.veop invoices"
  ],
  "TargetSystems": [
    {
      "Name": "D3EndpointService",
      "RepositoryId": "Repository-ID",
      "ApiKey": "API key"
    }
  ],
  "RoutingRules": [
    {
      "IsRoutingActivated": true,
      "AutoProcessingRuleDescription": "VENDOR_NUM='1420'",
      "DestinationProcessSequence": "0189e289-edcc-48ae-974e-3edde2029070",
      "DestinationNodeID": "irbBeforeExportHook",
      "DocumentClass": null,
      "TaskNameTemplate": "Kreditor 1420 Export",
      "UserGroupIDs": null,
      "ManualCreated": false,
      "Name": "Kreditor 1420",
      "AttributeResetInstructions": []
    }
  ],
  "MasterDataDefinitions": [
    {
      "TableName": "TEST_TABLE",
      "Description": null,
      "Columns": [
        {
          "ColumnName": "Column1",
          "Description": null,
          "ColumnType": 1,
          "MaxLength": 20,
          "CreateIndex": true,
          "TryIdentifyPattern": false,
          "SingleValueEntityName": null,
          "SemanticType": 0,
          "SignificantCharacters": null,
          "DefaultValue": "",
          "CreateFulltextIndex": false
        },
        {
          "ColumnName": "Column2",
          "Description": null,
          "ColumnType": 1,
          "MaxLength": 20,
          "CreateIndex": true,
          "TryIdentifyPattern": false,
          "SingleValueEntityName": null,
          "SemanticType": 0,
          "SignificantCharacters": null,
          "DefaultValue": "",
          "CreateFulltextIndex": false
        },
        {
          "ColumnName": "Column3",
          "Description": null,
          "ColumnType": 1,
          "MaxLength": 20,
          "CreateIndex": false,
          "TryIdentifyPattern": false,
          "SingleValueEntityName": null,
          "SemanticType": 0,
          "SignificantCharacters": null,
          "DefaultValue": "",
          "CreateFulltextIndex": false
        }
      ]
    }
  ]
}

Response

HTTP-Statuscode 200 Ok

Configuration of the layout

In addition to the webindex designer, an interface can also be used directly to configure the layout during indexing. The properties and structure of the master data can also be configured. You can obtain the current configuration as JSON via the following endpoint:

Request

GET /classcon-documentreader/Api/GetDocumentDefinitionLayout
Accept: application/json

The current configuration of the layout is returned as the response (the example only contains part of the actual information):

Response

HTTP-Statuscode 200 Ok
  
{
  "DefaultLayout": "INV",
  "DocumentClassAttributeId": null,
  "TenantDbConnectionString": "Tenant Subscription SQL Connection String (Read only)",
  "DocumentDefinitionLayouts": [
    {
      "DocumentTypeID": "INV",
      "CustomDuplicateCheck": {
        "QueryDefinition": "SELECT * FROM CCLogAttributes AS att INNER JOIN CCLogDocuments AS doc ON att.DocumentID = doc.DocumentID WHERE doc.SubscriptionID = @subscriptionID AND doc.ProcessSequenceID = @processSequenceID AND doc.Type = 0 AND att.DocumentID <> @documentID AND att.Attribute_Name = 'InvoiceNumber' AND att.Attribute_After = @invoiceNumber",
        "QueryMappings": [
          {
            "ColumnName": "@subscriptionID",
            "AttributeID": "SubscriptionId"
          },
          {
            "ColumnName": "@processSequenceID",
            "AttributeID": "ProcessSequenceId"
          },
          {
            "ColumnName": "@documentID",
            "AttributeID": "DocumentUID"
          },
          {
            "ColumnName": "@invoiceNumber",
            "AttributeID": "InvoiceNumber"
          }
        ],
        "HttpDataSourceId": null,
        "IsResultTransformationEnabled": false
      },
      "DateTargetFormats": [
        {
          "Code": "de",
          "JSFormat": "DD.MM.YYYY",
          "Format": "dd.MM.yyyy",
          "Pattern": "^(0?[1-9]|[12][0-9]|3[01])[.](0?[1-9]|1[012])[.](\\d{4})$"
        }
      ],
      "FloatValueFormats": [
        {
          "Code": "de",
          "ThousandDelimiter": "",
          "DecimalPlacesDelimiter": ",",
          "Pattern": "^\\d+(,\\d+)?$"
        }
      ],
      "AttributeTypeDefinitions": [
        {
          "AttributeTypeId": "VENDOR_NUM",
          "AttributeTypeDescription": "Vendor Number",
          "SemanticType": 0,
          "ValueType": 3,
          "InterpretAsMultipleValues": false,
          "ModelType": 0,
          "TemplatePath": "basics.vendor clues",
          "DataBaseDefinition": null,
          "DInfSaveOption": 0,
          "DClassifyAlias": "vendor.VENDOR_NUM",
          "InboundAlias": null,
          "LoggingFlag": 0
        },
      ],
      "AttributeTypeStructureDefinitions": [
        {
          "StructureName": "positions",
          "Description": null,
          "DClassifyAlias": "Positionen",
          "AttributeTypes": [
            {
              "AttributeTypeId": "Pos.OrderNum",
              "AttributeTypeDescription": "Pos.OrderNum",
              "SemanticType": 0,
              "ValueType": 3,
              "InterpretAsMultipleValues": false,
              "ModelType": 0,
              "TemplatePath": null,
              "DataBaseDefinition": null,
              "DInfSaveOption": 0,
              "DClassifyAlias": "ordernumber",
              "InboundAlias": null,
              "LoggingFlag": 0
            }
          ]
        }
      ],
      "AttributeGroups": [
        {
          "GroupID": 0,
          "GroupDescription": "Client",
          "MinifiedView": true,
          "AttributeDefinitions": [
            {
              "AttributeID": "DEBITOR_NUM",
              "Description": "",
              "AttributeType": 0,
              "AttributeLabel": null,
              "AttributeIcon": null,
              "Position": {
                "verticalPosition": 0,
                "horizontalPosition": 0
              },
              "SizeDesktop": 3,
              "SizeTablet": 3,
              "SizePhone": 4,
              "MinLength": 0,
              "MaxLength": 0,
              "ColumnSizePercent": 0,
              "ReadOnly": false,
              "AlignStart": false,
              "DoAlignStart": null,
              "TabStop": 1,
              "Pattern": null,
              "Title": null,
              "ValueConversion": null,
              "Required": true,
              "AllowNegativeAmount": false,
              "Minified": {
                "SizeDesktop": 3,
                "SizeTablet": 3,
                "SizePhone": 4
              },
              "JSSnippets": [],
              "Values": null,
              "DefaultValue": null,
              "DataBaseDefinition": {
                "QueryDefinition": "SELECT COMPANY_NUM, NAME, STR, ZIP, CITY, COUNTRY, DEFAULT_CURRENCY FROM dbo.CC_COMPANIES WHERE COMPANY_NUM LIKE @DEBITOR_NUM",
                "QueryMappings": [
                  {
                    "ColumnName": "COMPANY_NUM",
                    "AttributeID": "DEBITOR_NUM"
                  },
                  {
                    "ColumnName": "NAME",
                    "AttributeID": "NAME"
                  },
                  {
                    "ColumnName": "STR",
                    "AttributeID": "STR"
                  },
                  {
                    "ColumnName": "ZIP",
                    "AttributeID": "ZIP"
                  },
                  {
                    "ColumnName": "CITY",
                    "AttributeID": "CITY"
                  },
                  {
                    "ColumnName": "COUNTRY",
                    "AttributeID": "COUNTRY"
                  },
                  {
                    "ColumnName": "DEFAULT_CURRENCY",
                    "AttributeID": "DEFAULT_CURRENCY"
                  }
                ],
                "HttpDataSourceId": null,
                "IsResultTransformationEnabled": false
              },
              "QueryAttributes": [
                {
                  "AttributeID": "DEBITOR_NUM",
                  "AttributeValue": null,
                  "AttributeQueryPrefix": "%",
                  "AttributeQuerySuffix": "%",
                  "Prefix": null,
                  "MultipleParameter": null
                }
              ],
              "IsTransitive": false,
              "PositionCounterpart": null,
              "AutoComplete": true
            }
          ],
          "AttributeStructureDefinitions": [],
          "JSSnippets": []
        }
      ],
      "StructureGroups": [
        {
          "GroupID": 0,
          "GroupDescription": "PositionData",
          "MinifiedView": false,
          "AttributeDefinitions": [],
          "AttributeStructureDefinitions": [
            {
              "AttributeID": "positions",
              "AttributeDefinitions": [
                {
                  "AttributeID": "Pos.OrderNum",
                  "Description": null,
                  "AttributeType": 0,
                  "AttributeLabel": null,
                  "AttributeIcon": null,
                  "Position": null,
                  "SizeDesktop": 0,
                  "SizeTablet": 0,
                  "SizePhone": 0,
                  "MinLength": 0,
                  "MaxLength": 0,
                  "ColumnSizePercent": 15,
                  "ReadOnly": false,
                  "AlignStart": false,
                  "DoAlignStart": null,
                  "TabStop": 0,
                  "Pattern": null,
                  "Title": null,
                  "ValueConversion": null,
                  "Required": false,
                  "AllowNegativeAmount": false,
                  "Minified": null,
                  "JSSnippets": [],
                  "Values": null,
                  "DefaultValue": null,
                  "DataBaseDefinition": {
                    "QueryDefinition": "SELECT ORL.ORDER_NUM, ORL.ORDER_POS, MATNR, VENDOR_MATNR, DESCRIPTION, UNIT_PRICE, ORL.QUANTITY, SUM_PRICE, PRICE_UNITS, UNITS, RECEIPT_NUM FROM dbo.CC_ORDERLINES AS ORL INNER JOIN dbo.CC_ORDERS AS ORD ON ORL.ORDER_NUM = ORD.ORDER_NUM LEFT JOIN dbo.CC_RECEIPTS AS REC ON ORL.ORDER_NUM = REC.ORDER_NUM AND ORL.ORDER_POS = REC.ORDER_POS AND ORL.COMPANY_NUM = REC.COMPANY_NUM WHERE ORL.COMPANY_NUM = @DEBITOR_NUM AND ORD.VENDOR_NUM = @VENDOR_NUM AND ORL.ORDER_NUM LIKE @PosOrderNum",
                    "QueryMappings": [
                      {
                        "ColumnName": "ORDER_NUM",
                        "AttributeID": "Pos.OrderNum"
                      },
                      {
                        "ColumnName": "ORDER_POS",
                        "AttributeID": "Pos.OrderPos"
                      },
                      {
                        "ColumnName": "MATNR",
                        "AttributeID": "Pos.Article"
                      },
                      {
                        "ColumnName": "VENDOR_MATNR",
                        "AttributeID": "Pos.VENDOR_MATNR"
                      },
                      {
                        "ColumnName": "DESCRIPTION",
                        "AttributeID": "Pos.Description"
                      },
                      {
                        "ColumnName": "UNIT_PRICE",
                        "AttributeID": "Pos.UPrice"
                      },
                      {
                        "ColumnName": "QUANTITY",
                        "AttributeID": "Pos.Quantity"
                      },
                      {
                        "ColumnName": "SUM_PRICE",
                        "AttributeID": "Pos.SPrice"
                      },
                      {
                        "ColumnName": "PRICE_UNITS",
                        "AttributeID": "Pos.PRICE_UNITS"
                      },
                      {
                        "ColumnName": "UNITS",
                        "AttributeID": "Pos.UNITS"
                      },
                      {
                        "ColumnName": "RECEIPT_NUM",
                        "AttributeID": "Pos.DeliveryNote"
                      }
                    ],
                    "HttpDataSourceId": null,
                    "IsResultTransformationEnabled": false
                  },
                  "QueryAttributes": [
                    {
                      "AttributeID": "Pos.OrderNum",
                      "AttributeValue": null,
                      "AttributeQueryPrefix": "%",
                      "AttributeQuerySuffix": "%",
                      "Prefix": true,
                      "MultipleParameter": null
                    },
                    {
                      "AttributeID": "DEBITOR_NUM",
                      "AttributeValue": null,
                      "AttributeQueryPrefix": "",
                      "AttributeQuerySuffix": "",
                      "Prefix": false,
                      "MultipleParameter": null
                    },
                    {
                      "AttributeID": "VENDOR_NUM",
                      "AttributeValue": null,
                      "AttributeQueryPrefix": "",
                      "AttributeQuerySuffix": "",
                      "Prefix": false,
                      "MultipleParameter": null
                    }
                  ],
                  "IsTransitive": false,
                  "PositionCounterpart": null,
                  "AutoComplete": true
                }
              ],
              "JSSnippets": []
            }
          ],
          "JSSnippets": []
        }
      ],
      "TemplateDefinition": {
        "TemplateId": "VENDOR_NUM",
        "TemplateName": "VENDOR_NAME"
      }
    }
  ],
  "MasterFileDefinitions": [
    {
      "TableName": "CC_COMPANIES",
      "Description": "debitorlist",
      "Columns": [
        {
          "ColumnName": "COMPANY_NUM",
          "Description": "Companynumber",
          "ColumnType": 1,
          "MaxLength": 256,
          "CreateIndex": false,
          "TryIdentifyPattern": false,
          "SingleValueEntityName": null,
          "SemanticType": 0,
          "SignificantCharacters": null,
          "DefaultValue": "",
          "CreateFulltextIndex": false
        }
      ]
    }
  ],
  "HttpDataSources": null
}

We recommend first making the changes in the webindex designer and saving the configuration. The layout can then be queried at the described end point.

To provide the layout to another tenant, you can transmit the configuration as a JSON call via the following endpoint:

Request

POST /classcon-documentreader/Api/SetDocumentDefinitionLayout
Accept: application/json
   
See example json from response when calling "GetDocumentDefinitionLayout"

Response

HTTP-Statuscode 200 Ok