1. Overview

Our Push API helps you to transfer imported bank transactions into your system. Whenever we find new transactions for your bank account we'll issue a HTTPS request to your server and transfer the new transactions.

1.1 Setup

Setup is straight forward. Just click on Settings / Push API Settings in the menu and create a new Push API Setting. You basically define your API endpoint like www.yourserver.com/new_transactions, which HTTP method we should use (POST or PUT) and in which format we should transfer the transactions to you (JSON or XML). Additionally you need to choose for which bank accounts we should call the API (that means you can define different endpoints for each of your bank accounts).

1.2 Security

Enable SSL

Of course you need to protect your API. First, you really should enable SSL for the transfers. Otherwise it may be possible that unauthorized third parties look at the API request and therefore know everything about your banking accounts and transactions.

Protect against unauthorized calls

Unfortunately SSL encryption won't protect you against calls of unauthorized parties against your API. Therefore you need to protect it in a way that no unauthorized third party can call it.

HTTP Basic Authentication

You should protect your API using HTTP Basic Authentication. If you're using Apache as webserver you can simply place a .htaccess file in your API folder and create a user like 'bankimport' as the only one who may access it. Alternatively you can programatically check for the correct HTTP Authorization headers.

Unfortunately HTTP Authentication only protects you when you've enabled SSL! We already told you to enable it, right?
HMAC-SHA Signature

For additional protection, or if you are not able to use HTTP Basic Authentication, you can enter a secret key in the Push API Settings form. If you entered anything we'll sign our requests to your API using a HMAC-SHA512 signature. On every request you need to verify that the signature for the transferred data is correct.

Example signature verification

# Read parameters from webserver (this example for Rails)
signature = params[:signature]
data = params[:data]

# Init OpenSSL Digest SHA512 and compute hash
digest = OpenSSL::Digest.new('sha512')
hash = OpenSSL::HMAC.hexdigest(digest, 'your_secret_key', data)

# Compare with signature parameter
raise 'Unauthorized Access' unless signature == hash
// Read parameters from request
$signature = $_POST['signature'];
$data = $_POST['data'];

// Compute hash
$hash = hash_hmac('sha512', $data, 'your secret key');
if ($hash != $signature) die("Unauthorized Access");


2. The Request

2.1 Samples

The data itself is transferred to your API via the data parameter. It contains the actual transaction information. Additionally if you enabled HMAC signing the signature parameter contains the HMAC-SHA512 hash.

Example content of data parameter:

{
  "push_api_request_id": 2,
  "bank_account": {
    "account_number": "1234567",
    "sub_account_number": "00",
    "account_owner": "ACME Company",
    "currency": "EUR",
    "bank_name": "Sample Bank Name",
    "last_update_at": "2013-04-28T11:56:12Z"
  },
  "transactions": [
    {
      "id": 980194224,
      "valuta": "2012-10-04",
      "account_date": "2012-10-04",
      "purpose": "JOHN DOE \nSAMPLE TWO LINE\nPURPOSE",
      "new_balance": "1729.84",
      "amount": "31.27",
      "currency": "EUR",
      "hash": "da1b782b2059826e14c25380d0fddf742db6339b"
    },
    {
      "id": 980194225,
      "valuta": "2012-10-04",
      "account_date": "2012-10-04",
      "purpose": "RG 1293939\nSAMPLE TRANSACTION",
      "new_balance": "1709.84",
      "amount": "-20.0",
      "currency": "EUR",
      "hash": "d8105cd3ba700f9e51a580059b4b80754475548f"
    }
  ]
}
<?xml version="1.0" encoding="UTF-8"?>
<request>
  <push-api-request-id>2</push-api-request-id>
  <bank-account>
    <account-number>123456</account-number>
    <sub-account-number>00</sub-account-number>
    <account-owner>ACME Company</account-owner>
    <currency>EUR</currency>
    <bank-name>Sample Bank Name</bank-name>
    <last-update-at>2013-04-28T11:56:12Z</last-update-at>
  </bank-account>
  <transactions>
    <transaction>
      <id>980194224</id>
      <valuta>2012-10-04</valuta>
      <account-date>2012-10-04</account-date>
      <purpose>JOHN DOE
               SAMPLE TWO LINE
               PURPOSE
      </purpose>
      <new-balance>1729.84</new-balance>
      <amount>31.27</amount>
      <currency>EUR</currency>
      <hash>da1b782b2059826e14c25380d0fddf742db6339b</hash>
    </transaction>
    <transaction>
      <id>980194225</id>
      <valuta>2012-10-04</valuta>
      <account-date>2012-10-04</account-date>
      <purpose>RG 1233333
               SAMPLE TRANSACTION
      </purpose>
      <new-balance>1709.84</new-balance>
      <amount>-20.0</amount>
      <currency>EUR</currency>
      <hash>d8105cd3ba700f9e51a580059b4b80754475548f</hash>
    </transaction>
  </transactions>
</request>

2.2 Response

We need to know if you received our request to decide whether we have to re-send the request. For example in case your server is down or not answering correctly (e.g. due to database problems).

We assume the request failed unless your server responds with a HTTP 200 status code. If your server answers with a different status or is not answering at all, we try to call your API at a later time.

Optional check for actual response body

Under some circumstances you may not be able to control the HTTP response status code. A misconfigured web server may answer with an error message or exception but still use HTTP code 200. In these cases you can optionally activate the setting Check Response.

If it is activated we will check whether the response code is 200 AND if the response equals the string "OK" like this:

OK

2.3 Retries

In case the request to your API failed we will retry the request at a later time - with a maximum of 30 trials. The following table shows you how long we wait between the retries:

Trial Delay
First retry 1 minute after original request
2nd - 5th 10 minutes
6th - 10th 1 hour
11th - 15th 2 hours
16th - 20th 12 hours
21st - 25th 1 day
26th - 30th 2 days

Prevent double processing

During a request it may be possible that the network connection dies but your server nonetheless got all required information and processed the request before it recognized the died connection.

Therefore you need to make sure to prevent processing the same transactions again when we send our retry request. You can use the push_api_request_id, which we send along with each request, and store it in your database. On a subsequent call you can check if you already processed the request and ignore it. But please still send a 200 OK response to prevent more retries from our side - our both servers don't like unnecessary work.

 


3. Properties

3.1 Request

The root properties of every request are as follows:

JSON XML Description
-- <request> Root element of each request.
push_api_request_id <push-api-request-id> Unique identifier of each request. You should use it to prevent multiple processing of the same request (e.g. in case of timeouts).
bank_account <bank-account> Information about the bank account for which the transactions are transferred. Each request only holds the transaction of a single bank account - there is no mix of transactions between multiple accounts.
transactions <transactions> Array of transactions. See Transaction Properties.

3.2 Bank Account Properties

JSON XML Description
account_number <account-number> Account number of bank account.
sub_account_number <sub-account-number> The sub account number of that bank account, if applicable. May be numeric (e.g. 00) but can be a string as well.
account_owner <account-owner> Name of account owner.
currency <currency> Currency in which bank account is managed in ISO_4217 format.
bank_name <bank-name> Name of the bank.
last_update_at <last-update-at> The most recent time when we requested new transactions from that bank account. Time is returned in ISO-8601 format, e.g. "2013-04-28T11:56:12Z".

3.3 Transaction Properties

JSON XML Description
-- <transaction> Root container for each transaction
id <id> Numeric identifier for this transaction (according to our database).
valuta <valuta> Valuta date of the transaction. This is the date when your bank financially accounts the transaction. Most often same day or shortly after the account date. As ISO-8601 Depending on the backend this can be a Date (e.g. "2013-04-01" via HBCI interface or a full timestamp "2013-04-01T12:20:22Z" for PayPal transactions).
account_date <account-date> Date when the bank accounts the transactions. As ISO-8601. Depending on the backend this can be a Date (e.g. "2013-04-01" via HBCI interface or a full timestamp "2013-04-01T12:20:22Z" for PayPal transactions).
purpose <purpose> The purpose of the transaction. This is basically a free text field and most often contains the sender/receiver of the money, probably along with their bank account information. It also contains the free text of each transaction as given by the originator. Unfortunately we can't tell you which line contains which information because this differs from bank to bank.
new_balance <new-balance> The new balance of the bank account after this transaction was booked. Of course in the currency of the bank account, in decimals, e.g. "100.99" for One hundred and Ninetynine cents.
amount <amount> The amount of the transaction, delimitted with decimal without thousand separator.
Example: "2500.25" for USD 2,500.25
or "-99.00" for a negative amount of USD 99.00
currency <currency> Currency of the transaction. In ISO_4217 format.
Example: "EUR" or "USD".
hash <hash> SHA1 calculated of purpose, account_date and amount of the transaction. This can be used by your system to idenfify similar transactions or transactions booked multiple times. Especially helpful when you're dealing with prebookings.