NAV
code

Introduction

Overview

The Kontomatik PDF parsing API enables checking PDF statements against tampering attempts and parsing them to deliver clear banking data for credit scoring.

The common use case of this API is for assessing end-user creditworthiness. As such, the service requires user-uploaded PDF statements.

Please note that no end-user GUI for file upload is provided. You are expected to develop a user interface on your own.

Anti-tampering verification

Verification is done on every file upload via POST /v1/statement.xml. The following things are automatically checked against expected values:

Clients can also use for verification the following values in the returned data:

Supported targets

The PDF-parsing technology is currently available only in Poland. Coverage details are available here:

PDF-Parsing API - supported targets

API Conventions

Get API access

Authentication

Kontomatik API is protected by two-factor authentication:

Test environment

Start with the test environment to test and develop your credit scoring app. The test environment is fully-featured and unrestricted, returning real data. We kindly ask you to not use it for your production deployments.

The test API endpoint is:

https://test.api.kontomatik.com/

Request test API access.

After you sign the initial agreement for access, you'll have to provide us with email addresses for Insight (Client Area online system). Once we create the test account for you, you'll have to generate an API key in Insight and start your implementation.

Production environment

The production API endpoint is:

https://api.kontomatik.com/

Once the agreement is signed, after we internally sort all documents, the production access will be created and you'll be able to configure it in Insight - including generating a production API key and whitelisting your production servers IP addresses.

Tutorial

We recommend you to get API access before reading further, if you haven't done so already.

For the purpose of this tutorial we assume that you are a lender (for example a bank or a lending company) and you need the data as input for your credit scoring engine.

Example flow:

API reference

Catalog

Request

curl --get \
  --header "X-Api-Key=YOUR_LONG_API_KEY_HERE" \
  --data "country=pl"
  https://test.api.kontomatik.com/v1/parser-catalog.xml

Response

<reply xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://developer.kontomatik.com/schema/v1/get_parser_catalog.xsd" status="200 OK">
  <targets>
    <target name="Alior" officialName="Alior Bank"> </target>
    <target name="Bgz" officialName="BGŻ"> </target>
    <target name="Bos" officialName="BOŚ Bank"> </target>
    <target name="Bzwbk" officialName="BZWBK"> </target>
    <!-- other targets -->
  </targets>
</reply>

Returns the list of banks compatible with the PDF-parsing API (currently available only in Poland).

Parameters

Parameter Default Description
X-Api-Key obligatory API key
country pl Filters banks by the country they operate in. Accepted values: br cz es uk mx pl pt ru it lt lv ee. Currently all values except pl return an empty list, as the parsers API is not yet available for other countries than Poland.

Parse PDF statement

Test request

curl -H "X-Api-Key=<YOUR_API_KEY_FILE" \
     -F "pdfAsBase64=<YOUR_BASE64_ENCODED_PDF_FILE"
     https://test.api.kontomatik.com/v1/statement.xml

Response

<?xml version="1.0" encoding="utf-8"?>
<reply xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation="http://developer.kontomatik.com/schema/v1/statement.xsd" status="200 OK">
  <result>
    <statement id="12323423" isConsistent="true">
      <owners>
        <owner>
          <name>Jan Kowalski</name>
          <address>Krótka 8, Wąchock</address>
          <polishNip>1258882345</polishNip>
          <kind>OWNER</kind>
        </owner>
        <!-- ... more owners ... -->
      </owners>
      <period>
        <startOn>2014-01-01</startOn>
        <endOn>2014-01-31</endOn>
      </period>
      <type>MONTHLY_STATEMENT</type>
      <target name="MBank">
        <accounts>
          <account>
            <name>eKONTO</name>
            <iban>PL32114020040000320250132522</iban>
            <owners>
              <owner>
                <name>Jan Kowalski</name>
                <address>Krótka 8, Wąchock</address>
                <kind>OWNER</kind>
              </owner>
              <!-- ... more owners ... -->
            </owners>
            <activeSinceAtLeast>2014-11-12</activeSinceAtLeast>
            <currencyBalance>1467.39</currencyBalance>
            <currencyName>PLN</currencyName>
            <moneyTransactions>
              <moneyTransaction>
                <transactionOn>2012-06-28</transactionOn>
                <bookedOn>2012-06-30</bookekOn>
                <currencyAmount>20.00</currencyAmount>
                <currencyBalance>1264.21</currencyBalance>
                <title>I return money for a beer</title>
                <party>Mark Brown</party>
                <partyIban>PL68249000050000400075212326</partyIban>
                <kind>OUTGOING EXTERNAL TRANSFER</kind>
              </moneyTransaction>
              <!-- ... more transactions ... -->
            </moneyTransactions>
          </account>
          <!-- ... more accounts ... -->
        </accounts>
      </target>
    </statement>
  </result>
</reply>

Returns data from the PDF statement or an error when the uploaded file is not a valid PDF document or seems to be counterfeited.

The command recognizes the source bank, parses the file, verifies authenticity and reads the owner, period, account(s) and transactions.

The command takes one PDF file. To aggregate multiple PDF files, call it several times with the same ownerExternalId parameter.

HTTP Request

POST /v1/statement.xml

Parameters

Parameter Default Description
X-Api-Key obligatory API key
pdfAsBase64 obligatory PDF file encoded as Base64.
ownerExternalId optional data owner identifier (for example your internal credit-application-id). Data will be grouped around this parameter so that it can later be fetched together. If omitted, data won’t be persisted to the database and must be retrieved immediately after an individual command completion.
acceptInconsistent false pass true to indicate acceptance of incomplete statements, for ex. filtered statements containing only salary transactions

Data returned

Description of the <statement> element.

Data Availability Description
owners guaranteed personal details of the account owner or owners
period guaranteed the start and end dates of the statement as read from the PDF
type guaranteed a type of statement, either MONTHLY_STATEMENT or ACCOUNT_HISTORY
target guaranteed the originating bank of the statement
isConsistent guaranteed whether the statement contains the full history of transactions or not

Description of the <owner> element.

Data Availability Description
name guaranteed name (name and surname or company's name)
address possibly none address of the owner as presented by bank or multiple addresses if found (such as permanent address and contact address), in a comma-separated list
polishNip possibly none Polish NIP number
kind optional one of: OWNER, CO_OWNER, COMPANY. OWNER is the natural person shown as the main account owner, for example in the profile page. CO_OWNER is a co-owner of one of the bank accounts with full access to that specific bank account. COMPANY is the legal entity shown as the main account owner. If it's not possible to determine the main owner, all found persons will be marked as OWNER.

Description of the <target> element.

Data Availability Description
name guaranteed the name of a target bank as parsed from the submitted statement(s)
accounts guaranteed parent element containing data abstracts for each of the individual bank accounts

Description of the <account> element.

Data Availability Description
name optional internal bank descriptor for this account type
iban guaranteed full account number (with country code for 'true’ IBAN accounts)
owners guaranteed structured list of all owners represented as a separate owner tag with name, address and kind of each owner for the given account. A detailed description of the account owner element can see below. We recommend using this tag instead of <owner>. For now, both tags will be returned.
activeSinceAtLeast guaranteed the date when the account was opened or the date of the oldest transaction found
currencyBalance possibly missing account balance at the end of the period. Can be missing for inconsistent documents.
currencyName possibly missing the 3-letter acronym for the native currency of the bank account
moneyTransactions guaranteed list of money transactions for the given period

Description of the account <owner> element.

Data Availability Description
name guaranteed name (name and surname or company's name)
address possibly none address of the owner as presented by bank or multiple addresses if found (such as permanent address and contact address), in a comma-separated list
kind optional one of: OWNER, CO_OWNER, COMPANY. OWNER is the natural person shown as the main account owner, for example in the profile page. CO_OWNER is a co-owner of one of the bank accounts with full access to that specific bank account. COMPANY is the legal entity shown as the main account owner. If it's not possible to determine the main owner, all found persons will be marked as OWNER.

Description of the <moneyTransaction> element.

Data Availability Description
transactionOn possibly missing actual transaction date. If missing, it's guaranteed that <bookedOn> element will be present.
bookedOn possibly missing transaction's booking date (sometimes even 10 days after the actual transaction date). If missing, it's guaranteed that <transactionOn> element will be present.
currencyAmount guaranteed transaction amount expressed in the account currency (it can be different from the currency of the country where the bank is located)
currencyBalance possibly missing account balance expressed in the account currency
partyIban possibly missing full account number of the other party of the transaction. The field is often present but not in all cases. A small number of banks do not include this information.
party possibly missing name and surname of the other party of the transaction
kind possibly missing transaction type, as presented in the online transaction system (e.g. "INTEREST COMPOUNDING")
title possibly missing transaction title

Get aggregated data

HTTP Request

<reply xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://developer.kontomatik.com/schema/v1/get_data.xsd" status="200 OK">
  <owner externalId="653643">
    <target name="MBank">
      <owners>
        <owner>
          <name>John Fitcha</name>
          <address>Kwiatowa 8/97 Warszawa  PL</address>
          <polishNip>1258882345</polishNip>  
          <kind>OWNER</kind>
        </owner>
        <!-- ... more owners ... -->
      </owners>
      <accounts>
        <account>
          <name>eKONTO</name>
          <iban>PL32114020040000320250132522</iban>
          <currencyBalance>1467.39</currencyBalance>
          <currencyName>PLN</currencyName>
          <owners>
            <owner>
              <name>Jan Kowalski</name>
              <address>Krótka 8, Wąchock</address>
              <kind>OWNER</kind>
            </owner>
            <!-- ... more owners ... -->
          </owners>
          <activeSinceAtLeast>2000-02-28</activeSinceAtLeast>
          <moneyTransactions>
            <moneyTransaction>
              <transactionOn>2012-06-28</transactionOn>
              <bookedOn>2012-06-30</bookekOn>
              <currencyAmount>20.00</currencyAmount>
              <currencyBalance>443.00</currencyBalance>
              <title>Return for beer in a pub</title>
              <party>Jan Kowalski</party>
              <partyIban>PL68249000050000400075212326</partyIban>
              <kind>EXTERNAL INCOMING TRANSFER</kind>
            </moneyTransaction>
            <!-- ... more transactions ... -->
          </moneyTransactions>
        </account>
        <!-- ... more accounts ... -->
      </accounts>
    </target>
  </owner>
</reply>

GET /v1/data.xml?ownerExternalId=653643

Returns all imported and aggregated data associated with the user identified by an ownerExternalId.

Parameter Default Description
X-Api-Key obligatory API key
ownerExternalId obligatory parameter to identify the data owner (here: 653643)
only optional an optional parameter to filter the results returned by the command. It can have one of the following values: owners, accounts, transactions

The command returns a response with the same data fields as the Get aggregated data command in Banking API. The command returns a response with the same data fields as the command in Banking API.

Error handling

We can divide possible errors into three categories:

Errors caused by incorrect API calls

Command execution may fail when there is a problem with the given ownerExternalId.

Response

<?xml version="1.0" encoding="utf-8"?>
<reply status="404 Not Found">
  <exception name="InvalidCommandId">
  </exception>
</reply>
Exception Description
InvalidOwnerExternalId Invalid identifier of the data owner
JobsQuotaExceeded Your app has sent too many documents to parse simultaneously, surpassing the limit of 8. What to do: wait for 10-15 seconds to allow some of the documents to finish being parsed and resubmit the file. If you get the same error, repeat the process until the file is accepted.

Errors caused by a problem with the uploaded PDF files

Exception Description
DoesntLookLikePDF The file is not a PDF (user mistake - probably uploaded some garbage file instead of a PDF)
UnrecognizedStatementLayout The file is a PDF but it doesn't have the expected layout of a bank statement (user probably uploaded a different document, like a payment confirmation or an e-book)
InvalidStatementSignature The digital signature is incorrect (most likely the file was tampered by the user or, less likely, the target bank changed its signing certificate)
UnrecognizedTarget Target for PDF could not be defined. Either we don’t support PDF parsing for the chosen bank or the PDF has invalid metadata
InvalidStatementMetadata The PDF was edited/saved with a different tool than the one which the bank uses (most likely it was tampered by the user or, less likely, the bank changed its tool set for PDF generation)
InvalidStatementConsistency The PDF has inconsistent data. For example amounts don’t sum up or transaction dates don't match the header period. This exception is also thrown if there are filters on statement that are not allowed. Most likely the file was tampered by the user or, less likely, consistency check doesn't work correctly.
InvalidStatementFonts Fonts family, size or color are different than expected (either the PDF was edited by the user or the bank changed the fonts)
InvalidStatementLogo Bank logotype is different than expected (either the PDF was edited by the user or the bank changed its logotype picture)
UnsupportedStatement It's a valid PDF, but we cannot parse it. It may have been issued by an unsupported bank or it may concern an account type - ex. SME account - that we do not support yet. The exception message may clarify the reason.

Bugs in Kontomatik

The following should be considered bugs in the Kontomatik Service. Most likely, some edge case condition occurred and our software was not prepared for this. Kontomatik should be improved to cover this case. The error should be reported to Kontomatik, attaching the XML reply and logs of the application server.

Exception Description
KontoXPdfBug Some unhandled condition occurred. What to do: send us the whole XML response (which will include the stacktrace).

PDF Widget

Embedding the widget

<!-- index.html / head -->
<script src="https://signin.kontomatik.com/assets/statement-widget.js">
</script>
<!-- index.html / body -->
<div id="kontomatik" />
// index.js
embedKontomatikPdf({
  client: 'YOUR_CLIENT_ID',    // replace it with your assigned client id
  divId: 'kontomatik',         // must match the div element id
  since: '2018-01-01',
  ownerExternalId: 'owner_id',
  onFinished: function({ target, periods, count }) {
    // End-user finished uploading the PDFs
    alert('It works!');
  }
});

Required params

The embedKontomatikPdf() function takes the following obligatory parameters:

Parameter Description
client The client id you received from us. You will likely have two of them - one for the test and one for production API. See embedding the widget for details.
divId Where to render the widget. Make sure this div element already exists before calling the embedKontomatikPdf() function.
since Start date in YYYY-MM-DD format. The end-user will be asked to provide the PDF statements which cover the period since this date until present day.
ownerExternalId Your own arbitrary identifier of the end user. For a lender, this might be your loan application id. If you are a bank, a credit application id might be appropriate. If you are a PFM vendor, this could be your end-user database id. It allows you to group all imported data and fetch them together.
onFinished Callback function called when the end-user decides to finish uploading PDF statements. Please see onFinished callback description for more details.

Optional params

The embedKontomatikPdf() function takes the following optional parameters:

Parameter Default Description
locale en Determines end-user interface language. Accepted values: cz en es et it pl pt ru lt lv ro.
target null Pre-selects the bank. If omitted, the bank drop down list will be shown. Accepted values: check target name attribute in Catalog command response.
showFavicons false Set to true to show banks' favicons in a drop down list. Makes it easier for the end user to find a bank. Also it looks more appealing and professional. This is off by default because using bank logotypes can be a grey area in some jurisdictions.
showBetaQualityLabels true Option to control whether beta quality banks display the warning label - (beta)
showTargetMissingOption true By default, "My bank is not listed..." option is displayed on the bank selection list. Set the value to false if you do not want this option to show up on the list.
showTargetMissingForm true Option to control whether the user who clicked on "My bank is not listed..." option is then redirected to a form prompting the user to enter the name and url address of the unsupported bank. Passing false enables you to handle this scenario however you prefer.
showDefaultTarget true The widget displays a bank with a large market share as the default value of the bank selection list. If instead of a default target you prefer to display the message Select from list, set showDefaultTarget to false.
styles null Optional object defining the look and feel of the widget. For more information please refer to styling the widget section.
coverageTreshold 0.8 Minimal coverage of the requested period - a warning will be shown to the end-user if it isn't met. The warning is informational in nature and doesn't prevent the end-user from completing the process with this expectiation unfullfilled. Accepts float values in range: 0.0 - 1.0
disableTargetChangeAfterUpload false Disables the option to change the selected bank after first successfully uploaded statement.

Callbacks

PDF Widget provides a set of several callbacks, which are invoked when widget enters a new state or an important event takes place. It should be emphasized, that you only need to implement the onFinished callback.

Callbacks are passed to embedKontomatikPdf() function as params.

Here is the brief summary of available callbacks:

Callback Required Description
onFinished yes Callback function executed when the end-user decides to finish uploading the bank statements. Please see onFinished callback description for more details.
onError no Callback function executed an error occured during the end-user's interaction with the widget (for any reason). Please see onError callback description for more details.
onUnsupportedTarget no Invoked when the user clicks “My bank is not listed...” option on the bank selection list. Please see onUnsupportedTarget callback description for more details.
onInitialized no Called when the application is fully initialized and ready for user interaction. Please see onInitialized callback description for more details.
onStarted no Called when bank selection list is shown. Please see onStarted callback description for more details.
onTargetSelected no Invoked when user selects bank from the list. Please see onTargetSelected callback description for more details.

The following figure presents a visual reference for the callbacks and widget's transition between stages.

onFinished callback

Once the files have been successfully parsed the onFinished callback is called.

Property Description
target an identifier of the bank from which the PDF statement originates
periods a list of periods covered by the uploaded PDF statements. Single period format: { startOn: 'YYYY-MM-DD', endOn: 'YYYY-MM-DD' }
count the number of sent PDF statements

onError callback

The onError callback is called when an error has occured during the end-user's interaction with the widget. It will be passed the following parameters:

Parameter Description
exception indicates what went wrong. For more details please refer to error handling.
options an object containing extra properties, a more detailed explanation follows below

The options object contains the following properties:

Property Available Description
target always an identifier of the bank from which the PDF statement originates
officialName always the full bank name

Please note that you do not have to implement this. The widget handles error paths gracefully. This only serves informational purposes and should not affect your UI flow.

onUnsupportedTarget callback

In case when the user's bank is not listed, the user can select "My bank is not listed..." option on the dropdown list. The user is then redirected to a form, where he or she is prompted to enter the name and the url address of the missing bank. Regardless whether the user enters any text, the onUnsupportedTarget callback is fired. It will be passed an object with the following properties:

Property Description
target the name of the bank the user has entered
country location of the requested bank
address the url address of the bank's login page

onInitialized callback

The onInitialized callback is called when the widget is ready for user interaction, that is a fully initialized bank select list is shown.
The callback could be useful in case you decide to show your own spinner until the widget is initialized.

Note: the callback will be fired only once in widget's lifecycle.

onStarted callback

In contrast to onInitialized callback, the onStarted callback is called each time a bank selection list is shown to the end user.

onTargetSelected callback

The onTargetSelected callback is called when the user selected a bank and clicked the "next" button. The callback will be passed an object with the following properties:

Property Description
name an identifier of the bank the end user has selected
officialName the full bank name

Removing the widget

removeKontomatikPdf();

If you dynamically reload the SignIn Widget on the frontend, the already registered callbacks will be attached to the previously created session. In order to manage this, before calling for embedKontomatik() again, please use the removeKontomatikPdf() function.

CSS styling the widget

embedKontomatikPdf({
  /*
  ... (see Embedding the widget for the full reference) ...
  */
  styles: {
    bodyBgColor: '#20252b',
    textColor: '#ebebeb',
    borderRadius: '10px',
    btnBgColor: '#4e5d6c',
    btnBorderColor: 'transparent',
    btnTextColor: '#fff',
    btnPrimaryBgColor: '#e76d3b',
    btnPrimaryBorderColor: 'transparent',
    btnPrimaryTextColor: '#fff',
    inputBgColor: '#4e5d6c',
    inputBorderColor: 'transparent',
    inputBorderFocusColor: '#2c97de',
    inputTextColor: '#fff',
    inputDisabledTextColor: '#b4bcc2',
    alertErrorBgColor: '#d9534f',
    alertErrorBorderColor: 'transparent',
    alertErrorTextColor: '#fff',
    menuHighlightBgColor: '#2c3e50'
  }
});

Scope and approach

Widget offers easy customization of colors but no arbitrary CSS overrides.

Why no CSS overrides? We improve the widget every month in a CSS-breaking way to further optimize conversion rate, security and usability.

Allowing for arbitrary CSS overrides would effectively block us from ongoing widget development (or we would break our customers layouts).

This limitation brings mutual benefits - you automatically get all important improvements, for free.

We believe you can get very close to your ideal visual effect just by smartly customizing the colors.

How to customize the colors?

Customization is achieved by passing the styles: { /* ... */ } option to embedKontomatikPdf() function.

For a complete list of styles object properties see the following table.

Key Description
alertErrorBgColor
alertErrorBorderColor
alertErrorTextColor
respectively controls the background, border and text color of an error message alert box
bodyBgColor the background color of the widget
borderRadius controls the corner roundness of all input components (buttons, inputs, alert box). The default value is 4px
btnBgColor
btnBorderColor
btnTextColor
respectively controls the background, border and text color of the "Change bank" button
btnPrimaryBgColor
btnPrimaryBorderColor
btnPrimaryTextColor
respectively controls the background, border and text color of the "Next" and "Try again" buttons
inputBgColor
inputBorderColor
inputTextColor
inputDisabledTextColor
inputBorderFocusColor
the first three keys control the background, border and text color of all inputs and dropdown lists. The inputDisabledTextColor key controls the text color of disabled element. The last key - inputBorderFocusColor - controls the border color of an input that has focus
menuHighlightBgColor controls the background color of a menu item the mouse pointer is over
textColor text color

The color values use a subset of standard CSS color definitions, you can use both the hexadecimal (#123456) as well as the standard RGB (rgb(12, 34, 56)) notations.

Additionally, you can also use transparent and inherit keywords. However the RGBA, HSL and HSLA notations are not supported. You cannot use predefined HTML and CSS color names.

The properties which take length values accept standard CSS length units like px, em and so on.

Testing

To test the PDF Parsing service you can follow these few steps:

  1. Embed the PDF Widget on your website or integrate with the statement.xml endpoint and prepare your own frontend to send the files.
  2. Prepare documents to be tested:
    • real bank statements from your users - you can attempt to modify some of them to test negative scenarios;
    • use fake documents generated by Kontomatik - KontoBank statements.
  3. Upload the documents using your chosen method.
  4. Analyze the results and output.

For testing purposes please remember to use:

How to generate KontoBank statements

To generate a fake statement:

  1. Go to https://bank.kontomatik.com/pdf/
  2. Choose one of the mock accounts:
    • there are up to 10 existing mock accounts;
    • each account has different data, some can have multiple payment accounts available;
    • you’ll find the accounts descriptions in this document under the “Test accounts” tab.
  3. Choose document type:
    • monthly statement - spans over one month only for just one account
    • account history - can include multiple accounts within a custom date range
  4. (optional) Add errors:
    • this is to test negative parsing flow and learn to handle exceptions thrown by Kontomatik API;
    • you can choose multiple exceptions that will actually appear on the document;
    • Kontomatik API returns only one exception (first found).
  5. Click “Generate PDF” and then save the file.