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


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:

Request test API access.

Production environment

The production API endpoint is:

Once the agreement is signed, please request your production API access at [email protected]. Use your official company e-mail and provide:


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



curl --get \
  --data "apiKey=YOUR_LONG_API_KEY_HERE" \
  --data "country=pl"


<reply xmlns:xsi="" xsi:noNamespaceSchemaLocation="" status="200 OK">
    <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 -->

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


Parameter Default Description
apiKey obligatory API key
country pl Filters banks by the country they operate in. Accepted values: br cz es uk mx pl 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 -F "apiKey=<YOUR_API_KEY_FILE" \
     -F "pdfAsBase64=<YOUR_BASE64_ENCODED_PDF_FILE"


<?xml version="1.0" encoding="utf-8"?>
<reply xmlns:xsi=""
       xsi:noNamespaceSchemaLocation="" status="200 OK">
    <statement id="12323423" isConsistent="true">
      <owner deprecated="true">John Smith, ....</owner>
          <name>Jan Witkacy Kowalski</name>
          <address>Krótka 8, Wąchock</address>
      <target name="MBank">
            <owner>Jan Witkacy Kowalski</owner>
                <title>I return money for a beer</title>
                <party>Mark Brown</party>
                <kind>OUTGOING EXTERNAL TRANSFER</kind>
              <!-- ... more transactions ... -->
          <!-- ... more accounts ... -->

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


Parameter Default Description
apiKey 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
kind guaranteed one of: “OWNER”, “CO_OWNER, "COMPANY”
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

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)
owner guaranteed the name of the account owner
activeSinceAtLeast guaranteed the date when the account was opened or the date of the oldest transaction found
currencyBalance guaranteed account balance at the end of the period
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 <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

Fetch aggregated data

HTTP Request

<reply xmlns:xsi="" xsi:noNamespaceSchemaLocation="" status="200 OK">
  <owner externalId="653643">
    <target name="MBank">
      <owner>John Fitcha</owner>
          <owner>Jan Kowalski, Adam Nowak</owner>
              <title>Return for beer in a pub</title>
              <party>Jan Kowalski</party>
              <kind>EXTERNAL INCOMING TRANSFER</kind>
            <!-- ... more transactions ... -->
        <!-- ... more accounts ... -->

GET /v1/data.xml?ownerExternalId=653643

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

Parameter Default Description
apiKey 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 returs a response with the same data fields as the Parse PDF statement command.

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.


<?xml version="1.0" encoding="utf-8"?>
<reply status="404 Not Found">
  <exception name="InvalidCommandId">
Exception Description
InvalidOwnerExternalId Invalid identifier of the data owner

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="">
<!-- index.html / body -->
<div id="kontomatik" />
// index.js
  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 lv pl pt ru.
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


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

When the user successfully signs into the banking system the onFinished callback is called. It will be passed an object with the following properties:

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

CSS styling the widget

  ... (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
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
respectively controls the background, border and text color of the “Change bank” button
respectively controls the background, border and text color of the “Next” and “Try again” buttons
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.