NAV Navbar
Ahoi logo cookbook weiss

Quick Start Basics

This Cookbook enables you to get started quickly with AHOI. Before you begin, please register for an AHOI Sandbox Manager account.

Once you are registered, we recommend using our API Explorer to familiarize yourself with the API. The API Explorer contains the complete endpoint documentation. It allows you to test all AHOI endpoints and assists you with OAuth 2.0 authorization.

For general information about the AHOI API please refer to overview page.

Overview

Here are the steps necessary to proceed from registering a user to acquiring all of that user's transactions:

  1. Register with the Sandbox Manager
  2. Get a registration token
  3. Register the user
  4. Get a banking token
  5. List all providers
  6. Get access data for selected providers
  7. Create an access for the user
  8. Get all accounts
  9. Get all transactions for the account

STEP 1: Register with the Sandbox Manager

The first step you need to complete before you can use the AHOI API is to register with the Sandbox Manager. With every registration we create a bank access with accounts, portfolios and transactions for our testing bank, the Sandbank. You can use the this bank access for your own testing purposes. All of the credentials you need can be found in the Sandbox Manager. You can also enter your own test data.

STEP 2: Get a registration token

The registration token is used to register an actual user with AHOI. To obtain a registration token, the external application authenticates with the application credentials. Further endpoints are inaccessible with this token.

You need to add a basic authorization header with your clientId and clientSecret to your request to obtain the registration token. You’ll find the credentials in the Sandbox Manager. These values must be encoded with base64 in a single string.

Example: Encode basic auth credentials in Java

String credentials = String.format("%s:%s", <clientId>, <clientSecret>);
String AUTH_BASIC_BASE64 = Base64.getEncoder()
                                 .encodeToString(credentials.getBytes( StandardCharsets.UTF_8 ));

Request

POST /auth/v1/oauth/token?grant_type=client_credentials HTTP/1.1
Authorization: Basic <AUTH_BASIC_BASE64>

Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
    "access_token": "<REGISTRATION_TOKEN>",
    "token_type": "bearer",
    "expires_in": 1199,
    "scope": "ANON ENC_DIS",
    "jti": "8423faa7-e2ea-47c1-82a7-ace341506da8"
}

The "expires_in" value in the response contains the number of seconds until expiration. This token will expire in about 20 minutes.

STEP 3: User registration

Please insert the <REGISTRATION_TOKEN> fetched in the previous step for the "bearer" token in an "Authorization" request header.

Request

POST /ahoi/api/v2/registration HTTP/1.1
Authorization: Bearer <REGISTRATION_TOKEN>

Response

HTTP/1.1 201 CREATED
Content-Type: application/json; charset=utf-8

{
  "installation": "<INSTALLATION_ID>"
}

STEP 4: Get a banking token

With the <INSTALLATION_ID> you can now get a banking token. This token authenticates the actual user with AHOI and can be used by your application to execute banking actions on behalf of the user. With this token, all endpoints can be used except registration, for which you need a registration token.

You need to send a X-Authorization-Ahoi header with this request. The header value is an encoded JSON string that consists of the <INSTALLATION_ID>, a random 16-character string as nonce and the current date in ISO 8601 format.

{
    "installationId":"<INSTALLATION_ID>",
    "nonce":"0wYWLarLDBrWU7B2I1Go4A==",
    "timestamp":"2018-11-01T11:32:44.413Z"
}

Encode this data with Base64URL to create the required header.

Example: Create X-Authorization-Ahoi header in Java

String installationId = <INSTALLATION_ID>;
// create nonce
byte[] nonce = new byte[16];
SecureRandom.getInstanceStrong().nextBytes(nonce);
String nonceBase64Enc = Base64.getEncoder().encodeToString(nonce);
// create timestamp
String timeStr = Instant.now().toString();
// create json string
String xAuthAhoiJson = String.format("{\"installationId\":\"%s\",\"nonce\":\"%s\",\"timestamp\":\"%s\"}",
                                        installationId, nonceBase64Enc, timeStr);
// encode encrypted header value
String XAUTH_AHOI_BASE64_URL_ENC = Base64.getUrlEncoder().withoutPadding()
                                         .encodeToString(xAuthAhoiJson.getBytes( StandardCharsets.UTF_8 ));

Request

POST /auth/v1/oauth/token?grant_type=client_credentials HTTP/1.1
Authorization: Basic <AUTH_BASIC_BASE64>
X-Authorization-Ahoi: <XAUTH_AHOI_BASE64_URL_ENC>

Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
    "access_token": "<BANKING_TOKEN>",
    "token_type": "bearer",
    "expires_in": 3599,
    "scope": "ACCESS_C ACCESS_R ACCESS_U … TRANSFER_C ENC_DIS",
    "CONTEXT_ID": "Jz5Hq14Uc6Y3vo…VuuF3u9OLqpkHXXG9yXPDWIbgevo8yNe",
    "jti": "3ee3c5aa-77f0-44cb-aec1-69c8665a4bec"
}

Once again, the expires_in value in the response contains the number of seconds until expiration. This token will expire in about 60 minutes.

From now on, you have to include this banking token ("access_token") in each of your requests for this user.

STEP 5: List all providers

To set up the bank accounts, a banking access needs to be created first. For this the "id" of the provider (i.e., bank) is required. You can get a list of all available providers by using the "providers" resource.

Request

GET /ahoi/api/v2/providers/ HTTP/1.1
Authorization: Bearer <BANKING_TOKEN>

Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

[
  {
    "type": "BankProvider",
    "id": "<PROVIDER_ID>",
    "name": "Sandbank",
    "location": "Hamburg",
    "accessDescription": null,
    "supported": true,
    "bankCode": "99994000",
    "bic": "TESTBICXXXX"
  }
]

STEP 6: Get provider access data

Next you will need the fieldDescriptions of the provider. These tell you which fields are required to authenticate with the bank. Later these should be used to create a user interface to enter the access credentials. For the time being we will use them to send the required values when creating the access.

Request

GET /ahoi/api/v2/providers/<PROVIDER_ID> HTTP/1.1
Authorization: Bearer <BANKING_TOKEN>

Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Status: 200 OK

{
    "type": "BankProvider",
    "id": "<PROVIDER_ID>",
    "name": "Sandbank",
    "location": "Hamburg",
    "accessDescription": {
        "infoText": "Sofern Ihr Institut Ihnen keine separate Benutzerkennung mitgeteilt hat, geben Sie bitte unter Benutzerkennung Ihre Kontonummer ein. In Abhängigkeit von Ihrem Kreditinstitut können zusätzliche Informationen, wie beispielsweise eine Kundennummer, hinterlegt werden. Diese Eingabe ist meistens optional.",
        "fieldDescriptions": [
            {
                "id": "USERNAME",
                "label": "Benutzerkennung",
                "masked": false,
                "format": "DEFINITELYALPHANUMERIC",
                "lengthMin": 1,
                "lengthMax": 30
            },
            {
                "id": "PIN",
                "label": "PIN",
                "masked": true,
                "format": "UNSPECIFIED",
                "lengthMin": 5,
                "lengthMax": 5
            }
        ]
    },
    "supported": true,
    "bankCode": "99994000",
    "bic": "TESTBICXXXX"
}

STEP 7: Create an access

Now you have all the information you need to create a banking access. From the previous step you know that you need a USERNAME and a PIN for the Sandbank. Please refer to Sandbox Manager for the requested values.

Request

POST /ahoi/api/v2/accesses HTTP/1.1
Authorization: Bearer <BANKING_TOKEN>
Content-Type: application/json

{
    "providerId": "<PROVIDER_ID>",
    "type": "BankAccess",
    "accessFields": {
        "USERNAME": "myuser", 
        "PIN": "12345"
    }
}

Response

HTTP/1.1 201 CREATED
Content-Type: application/json; charset=utf-8

{
    "type": "BankAccess", 
    "id": "<ACCESS_ID>",
    "providerId": "<PROVIDER_ID>",
    "validationState": "OK"
}

When the access is successfully created, AHOI automatically acquires all accounts from the bank and saves them.

STEP 8: Get all accounts

With the access you have created, you can now acquire the related accounts by using the <ACCESS_ID>.

Request

GET /ahoi/api/v2/accesses/<ACCESS_ID>/accounts HTTP/1.1
Authorization: Bearer <BANKING_TOKEN>

Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

[
    {
        "type": "BankAccount",
        "id": "<ACCOUNT_ID>",
        "name": "Giro Classic",
        "..."
    },
    {
        "type": "BankAccount",
        "id": "f0629fd2-0f95-4f67-953d-e62bda0fa77d",
        "name": "Giro Classic",
        "..."
    },
    {
        "type": "BankAccount",
        "id": "4267646a-656e-44d7-a06b-854d4e53dc9e",
        "name": "Depot",
        "..."
    }

STEP 9: Get all transactions

For each account you can now list all transactions by using the <ACCESS_ID> and the <ACCOUNT_ID>.

Request

GET /ahoi/api/v2/accesses/<ACCESS_ID>/accounts/<ACCOUNT_ID>/transactions HTTP/1.1
Authorization: Bearer <BANKING_TOKEN>

Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

[
    {
        "type": "GiroTransaction",
        "id": "17b1f6bd-034d-4e17-a3df-e7f02e52ca3e",
        "transactionPatternId": "8c47a610-2069-447b-b09c-6e4053ba6f3e",
        "amount": {
            "value": -6522,
            "currency": "EUR"
        },
        "bookingDate": "2018-10-13T12:00:00Z",
        "valueDate": "2018-10-13T12:00:00Z",
        "creditor": "Stadtreinigung Musterstadt",
        
    },
    {
        "type": "GiroTransaction",
        "id": "e3a4d5ec-db2e-4900-bfd2-963a4e258fde",
        "transactionPatternId": "f9b9f252-a096-493c-81bd-4fc11488d616",
        "amount": {
            "value": -5250,
            "currency": "EUR"
        },
        "bookingDate": "2018-10-13T12:00:00Z",
        "valueDate": "2018-10-13T12:00:00Z",
        "creditor": "Rundfunk ARD, ZDF, DRadio",
        
    },

]

Quick Start Transfer

Overview

Steps to execute a single SEPA transfer using the AHOI API without webhook notifications:

  1. Submit the SEPA transfer
  2. Poll the task state
  3. Fetch the TAN challenge
  4. Submit the TAN
  5. Poll the task state again

STEP 1: Submit the SEPA transfer

The first step in executing a single SEPA transfer using the AHOI API is to submit a new transfer from one of your accounts that corresponds to your access.

Request

POST /ahoi/api/v2/accesses/<ACCESS_ID>/accounts/<ACCOUNT_ID>/transfers HTTP/1.1
Authorization: Bearer <BANKING_TOKEN>
Content-Type: application/json

{
    "iban" : "<IBAN>",
    "bic" : "TESTBICXXXX",
    "name" : "Stan S. Stanman",
    "amount" : {
        "value" : 5000,
        "currency" : "EUR"
    },
    "purpose" : "Test"}

Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
   "type" : "TransferTask",
   "bankMessages" : [],
   "id" : "<TASK_ID>",
   "state" : "AUTHORIZATION_PENDING"
}

STEP 2: Poll the task state

The second step is to poll the task state until the TAN challenge is available. To get the current state of the transfer task, you need to query the task resource using the <TASK_ID> returned in the response to the first step.

Request

GET /ahoi/api/v2/tasks/<TASK_ID> HTTP/1.1
Authorization: Bearer <BANKING_TOKEN>

Response (success)

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "type": "TransferTask",
  "state": "AUTHORIZATION_PENDING",
  "id": "<TASK_ID>",
  "bankMessages": []
}

Response (error)

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "type": "TransferTask",
  "state": "FAILED",
  "id": "<TASK_ID>",
  "bankMessages": [
    {
      "level": "ERROR",
      "message": "Unerwarteter Fehler: TAN request response loop ran into timeout!",
      "errorCode": "UNCLASSIFIED"
    }
  ]
}

STEP 3: Fetch the TAN challenge

The third step is to fetch the TAN challenge provided by the bank that is executing the SEPA transfer. The challenge is required to provide the proper TAN authorization method.

You can find a challenge for the AHOI Sandbank in the example response below.

Request

GET /ahoi/api/v2/tasks/<TASK_ID>/challenges HTTP/1.1
Authorization: Bearer <BANKING_TOKEN>

Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
   "challenge" : "Bitte geben Sie die TAN ***<TAN>*** für den  Connector ein!",
   "additionalInformation" : "Zahlung an: <IBAN> Betrag: 50,00 EUR",
   "tanGuiUrl" : "/ahoi/webui/task/<TASK_ID>/tan",
   "type" : "CHIPTAN"
}

STEP 4: Submit the TAN

The fourth step is to supply the TAN authorization. To do so, just send the authorization as a POST request per the following example.

Request

POST /ahoi/api/v2/tasks/<TASK_ID>/authorizations HTTP/1.1
Authorization: Bearer <BANKING_TOKEN>
Content-Type: application/json

{
    "type": "TanChallengeResponse",
    "response": "<TAN>"
}

Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "type": "TransferTask",
  "state": "AUTHORIZATION_PENDING",
  "id": "<TASK_ID>",
  "bankMessages": []
}

STEP 5: Poll the task state again

Please refer to STEP 2 to see an example of how to do this.

Poll the task until you get one of the following response bodies:

Transfer DONE

{
  "type": "TransferTask",
  "state": "DONE",
  "id": "<TASK_ID>",
  "bankMessages": []
}

Transfer FAILED

{
  "type": "TransferTask",
  "state": "FAILED",
  "id": "<TASK_ID>",
  "bankMessages": [
    {
      "level": "ERROR",
      "message": "Unerwarteter Fehler: TAN request response loop ran into timeout!",
      "errorCode": "UNCLASSIFIED"
    }
  ]
}

Transfer failed authorization (TAN invalid)

{
  "type": "TransferTask",
  "state": "AUTHORIZATION_WRONG",
  "id": "<TASK_ID>",
  "bankMessages": [
    {
      "level": "ERROR",
      "message": "Die TAN ist falsch!",
      "errorCode": "TAN_INVALID"
    }
  ]
}

Quick Start Webhook

Webhooks are used to deliver notificiations about events within AHOI that you or your users can respond to. For now these events consist of transfer-related actions, such as providing an answer to a challenge (e.g., a TAN).

You will also receive a notification when new transactions are detected in accounts that have already been set up.

Overview

To receive webhook-based notifications, please complete the following steps:

  1. Create a publicly available endpoint for AHOI webhooks
  2. Register your endpoint URL with the AHOI Sandbox Manager
  3. Send a test event
  4. Try triggering an event

STEP 1: Webhook endpoint

Your webhook endpoint must be able to receive POST requests with Content-Type: application/json. The body will contain a JSON object in the following format:

{
    "type": "TaskWebhookMessage",
    "event": "TASK_CHALLENGE_AVAILABLE",
    "clientId": "<CLIENT_ID>",
    "userContextId": "<CONTEXT_ID>",
    "taskId": "<TASK_ID>"
}

As a response we expect you to reply with the HTTP status code 202 (Accepted). Please queue the message and process it asynchronously instead of immediately starting to process it before you send us the reply.

You can find a swagger specification for the model and REST endpoint. Try generating your server code using the swagger editor.

STEP 2: Register

Log in to your Sandbox Manager account and visit your user profile. Here you can enter the URL to which we will send webhook notifications.

Sandbox Manager Webhook Registration

STEP 3: Send a test event

Once you have entered the webhook URL and ensured that your endpoint is available, you can use the "Verify" button to send a test request.

STEP 4: Try triggering an event

You can try and create a transfer using the AHOI API and see if you receive a TASK_CHALLENGE_AVAILABLE webhook event asking you to enter a TAN challenge. After you have successfully provided one, you should receive the message TASK_DONE.

Transfer with AHOI TAN UI

AHOI TAN UI is a web component designed to simplify the TAN authorization of transactions within your application, especially using Chip-TAN optic method. It is currently in an experimental state, this means that its security features will be improved soon.

Overview

This reference guide shows the usage of AHOI TAN UI in combination with AHOI API Explorer using the steps of Quick start transfer without webhook notifications.

  1. Submit the SEPA transfer
  2. Fetch the task state
  3. Fetch the TAN challenge
  4. Submit the TAN via TAN UI
  5. Fetch the task state again

STEP 1: Submit the SEPA transfer

First step to execute a single SEPA transfer using AHOI-API is to submit a new transfer from one of your accounts that corresponds to your access.

Request

Create new transfer, request

Response

Create new transfer, response

STEP 2: Fetch the task state

Second step is to fetch the task state to see if the TAN challenge is available. To get the current state of the transfer task you need to query the task resource using the task ID returned by the response of the first step.

Request

Fetch task state, request

Response

Fetch task state, response

STEP 3: Fetch the TAN challenge

Third step is to fetch the TAN challenge provided by the bank, executing the SEPA transfer. The challenge is required to provide proper TAN authorization scheme.

Request

Fetch TAN challenge, request

Response

Fetch TAN challenge, response

STEP 4: Submit the TAN via TAN UI

Fourth step is to supply the TAN. To do this, just open the URI path shown in the response screenshot of STEP 3 named tanGuiUrl within a browser or click on button named "Enter TAN".

Opening dialog for Sandbank

Submit TAN via TAN UI, open

Dialog with TAN before submit

Submit TAN via TAN UI, request

Dialog in success state

Submit TAN via TAN UI, result

Note: A loading spinner is shown while waiting for the result.

STEP 5: Fetch the task state again

Please refer to STEP 2 regarding example of how to do this.

Request

Fetch task state again, request

Response

Fetch task state again, response

How to Use Extended Encryption

Overview

Here are the steps to carry out a registration with extended encryption using the AHOI API:

  1. Get a registration token
  2. Retrieve a public key
  3. Create X-Ahoi-Session-Security header
  4. Request a registration
  5. Extract the installationId
  6. Encrypt the X-Authorization-Ahoi header to fetch a banking token

STEP 1: Get a registration token

This step is identical to the step outlined in the Quick Start.

Please copy your clientId and clientSecret from the AHOI Sandbox Manager and encode them using the Base64 algorithm to a single string as depicted below.

Example: Encode basic auth credentials in Java

String credentials = String.format("%s:%s", <clientId>, <clientSecret>);
byte[] credentialsBytes = credentials.getBytes(StandardCharsets.UTF_8);
String AUTH_BASIC_BASE64 = Base64.getEncoder().encodeToString(credentialsBytes);

Send this to the OAuth service using the following request. This should result in a response similar to the one shown below.

Request

POST /auth/v1/oauth/token?grant_type=client_credentials HTTP/1.1
Authorization: Basic <AUTH_BASIC_BASE64>

Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
    "access_token": "<REGISTRATION_TOKEN>",
    "token_type": "bearer",
    "expires_in": 1199,
    "scope": "ANON",
    "jti": "c6d69c1c-3f57-417b-82d6-0f288f38ef65"
}

STEP 2: Retrieve a public key

When communicating with AHOI and using extended encryption, the additional X-Ahoi-Session-Security header needs to be added to each request in which sensitive information is transmitted.

The session security header needs to be encrypted with an AHOI public key fetched in this step.

Request

GET /ahoi/api/v2/registration/keys HTTP/1.1
Authorization: Bearer <REGISTRATION_TOKEN>

Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
    "keyId": "<KEY_ID>",
    "validUntil": "2018-10-11T16:00:00Z",
    "publicKey": {
        "value": "<KEY>",
        "specification": "RSA_2048_SHA1"
    },
    "publicKeySignature": { 
        "value": "<KEY_SIGNATURE>",
        "specification": "SHA1_WITH_RSA"
    }
}
Identifier Description
RSA_2048_SHA1 RSA private / public key with 2048-bit key length and OAEP padding. ("RSA/ECB/OAEPWithSHA-1AndMGF1 Padding")
SHA1_WITH_RSA SHA1 signature with RSA private / public key with 2048-bit key length and PKCS1 padding. ("SHA1withRSA")

STEP 3: Create an "X-Ahoi-Session-Security" header

Why is the X-Ahoi-Session-Security request header necessary? Sensitive data like the PIN or the installationId are protected by HTTPS transport security and encrypted by a symmetricKey for each session you create while using extended encryption. This symmetricKey must be encrypted using an asymmetric public key, fetched in the previous step before it is send as the "sessionKey" in the X-Ahoi-Session-Security header.
The session key is used to encrypt and later to decrypt the sensitive user data in AHOI and vice versa.

The necessary steps to build the header are:

  1. Generate the symmetric key (AES)
  2. Decode the public key received from AHOI
  3. Encrypt the symmetric key with the AHOI public key to secure the session key
  4. Encode the session key with Base64URL
  5. Build the JSON string containing publicKeyId, sessionKey and keySpecification
  6. Encode the JSON string using Base64URL to create the header value

Example: How to create the "X-Ahoi-Session-Security" header in Java

// 1. Generate a simple symmetricKey
KeyGenerator generator = KeyGenerator.getInstance("AES");
generator.init(256);
SecretKey key = generator.generateKey();
byte[] symmetricKey = key.getEncoded();

// 2. Decode and parse PublicKey
byte[] data = Base64.getUrlDecoder().decode(<KEY>);
PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(data));

// 3. Encrypt symmetricKey with the recieved public key
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedsymmetricKey = cipher.doFinal(symmetricKey);

// 4. Encode Base64 url-safe
Base64.Encoder base64UrlEnocder = Base64.getUrlEncoder().withoutPadding(); 
String sessionKey = base64UrlEncoder.encodeToString(encryptedsymmetricKey);

// 5. Build JSON string
String headerTemplate = "{\"publicKeyId\":\"%s\",\"sessionKey\":\"%s\",\"keySpecification\":\"AES\"}";
String header = String.format(headerTemplate, <KEY_ID>, sessionKey);
byte[] headerBytes = header.getBytes(StandardCharsets.UTF_8);

// 6. Now encode JSON to create header value
String BASE64_ENCODED_JSON_HEADER = base64UrlEnocder.encodeToString(headerBytes);

STEP 4: User registration

After the X-Ahoi-Session-Security request header has been built, the registration request is submitted as detailled below. The corresponding response contains an encrypted installationId.

Request

POST /ahoi/api/v2/registration HTTP/1.1
Authorization: Bearer <REGISTRATION_TOKEN>
X-Ahoi-Session-Security: <BASE64_ENCODED_JSON_HEADER>

Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
    "installation":"<ENCRYPTED_INSTALLATION_ID>"
} 

STEP 5: Extract installation ID with session key (your symmetricKey)

The decryption of the installationId from the registration response with your symmetric key is shown below.

Example: Decrypt response in Java

// 1.Decode the base64 url-safe data
byte[] encryptedInstallation = Base64.getUrlDecoder().decode(<ENCRYPTED_INSTALLATION_ID>);

// 2.Decrypt with your symmetricKey
byte[] iv = new byte[16];
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKey secKey = new SecretKeySpec(symmetricKey, "AES");
cipher.init(Cipher.DECRYPT_MODE, secKey, new IvParameterSpec(iv));
String installationId = new String(cipher.doFinal(encryptedInstallation), "UTF-8");

STEP 6: Encrypt "X-Authorization-Ahoi" header to fetch the banking token

In the event that extended encryption is enabled, the X-Authorization-Ahoi needs to be encrypted, too. This header is used to request a banking token from the AHOI OAuth service.

We will skip the instructions here on how to create nonce and timestamp values for the header string. This is described in STEP 4 of the Quick Start.

Example: Encrypt "X-Authorization-Ahoi" header in Java

String xAuthorizationAhoiHeader = "{ \"installationId\": \"<ENCRYPTED_INSTALLATION_ID>\", \"nonce\": \"<nonce>\", \"timestamp\": \"<JAVA_TIMESTAMP>\" }";

// encrypt header value
byte[] key = Base64.getUrlDecoder().decode(<appSecretKey>);
byte[] iv = Base64.getUrlDecoder().decode(<appSecretIV>);
SecretKey secKey = new SecretKeySpec(key, SymmetricAlgorithm.AES_256.getAlgorithm());
Cipher cipher = Cipher.getInstance(SymmetricAlgorithm.AES_256.getTransformation());
cipher.init(1, secKey, new IvParameterSpec(iv));
byte[] encryptedJson = cipher.doFinal(xAuthAhoiJson.getBytes(StandardCharsets.UTF_8));
// encode encrypted header value
String XAUTH_AHOI_BASE64_URL_ENC = Base64.getUrlEncoder().withoutPadding().encodeToString(encryptedJson);

STEP 7: Create an access

When creating an access with extended encryption enabled, is slightly different than described in STEP 7 of Basic Quick Start Beside the need to supply the X-Ahoi-Session-Security header, the credentials must be encrypted using your symmetricKey.

Example: Encrypt access credentials in Java

byte[] iv = new byte[16];
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKey secKey = new SecretKeySpec(symmetricKey, "AES");
cipher.init(Cipher.ENCRYPT_MODE, secKey, new IvParameterSpec(iv));

byte[] enc_username = cipher.doFinal("meinAnmeldename".getBytes(StandardCharsets.UTF_8));
byte[] enc_pin = cipher.doFinal("meinePin".getBytes(StandardCharsets.UTF_8));

String USER_ENC_BASE64 = Base64.getUrlEncoder().withoutPadding().encodeToString(enc_username);
String PIN_ENC_BASE64 = Base64.getUrlEncoder().withoutPadding().encodeToString(enc_pin);

Here is an example of how the request to AHOI might look when creating an access with extended encryption enabled.

Request

POST /ahoi/api/v2/accesses HTTP/1.1
Authorization: Bearer <BANKING_TOKEN>
X-Ahoi-Session-Security: <BASE64_ENCODED_JSON_HEADER>
Content-Type: application/json

{
  "type" : "BankAccess",
  "providerId" : "<PROVIDER_ID>",
  "accessFields" : {
    "USERNAME" : "<USER_ENC_BASE64>",
    "PIN" : "<PIN_ENC_BASE64>"
  }
}

AHOI Resources

This section provides a brief overview of the various key components of AHOI. If you're uncertain about what a resource actually represents, please begin by consulting this section.

AHOI Resources

App service

Your app-specific service that connects to AHOI.

Installation

An installation represents one context for user-specific data.

Access

An access represents a login to an assigned provider (e.g., login credentials for online banking). It includes data such as the username and PIN. Which fields are required will be described in the provider's input field descriptions.

Each access has a validation state that describes the validity of the credentials. This state might change over time if the credentials are no longer valid.

Account

An account is a grouping of financial records (e.g., a bank account). It contains information about the account name, the account holder, the account type as well as related information such as the account number, IBAN or account balance. It is associated with one or more accesses.

An automatic background refresh of transactions can be activated for every account.

Provider

A provider represents financial institutions AHOI can connect to (e.g., banks).

Transaction

A transaction represents a financial operation associated with an account. A bank account transaction contains information about the payee and the creditor, the amount, the date on which it was booked, the availability of funds and its purpose. A transaction might also be related to a recurring transaction pattern.

API Explorer Tutorial

The API Explorer is integrated directly into the AHOI documentation. Follow the steps below to experience your first success with the API Explorer:

  1. Open your Sandbox Manager so you can see your service-specific credentials.

  2. Open the API Explorer in a second browser tab.

  3. Copy your credentials (clientId, clientSecret, appSecretIV and appSecretKey) from the Sandbox Manager into the respective fields in the API Explorer in the sidebar located on the left.

  4. Click on Get Registration Token. This obtains a registration token that appears in the Token field.

  5. Select Registration in the menu on the left, then User Registration, and finally select TRY for this endpoint. The previously anonymous user will now be registered and that user's installationId will be displayed. You don't have to remember the installationId — just close the pop-up. The API Explorer will automatically put the variable into the corresponding field in the sidebar on the left. The Explorer has also automatically fetched a banking token for you, so you can now access all banking-specific AHOI endpoints. Congratulations!

  6. Set up your AHOI Sandbank access in AHOI. To do this, first take note of your AHOI Sandbank credentials (blz, username, pin) in the Sandbox Manager. Then switch to Provider in the menu and select List bank providers. Insert the bank code of the AHOI Sandbank (99994000) into the bankCode field and execute the request with TRY.

  7. As a result, you've now received an id for the provider. Next, select Access in the menu and then select the Create a new access endpoint. By clicking on the JSON body sample on the right, you can add an accessDto to your request. Replace the values in the providerId, USERNAME and PIN fields with your own values, delete the entry for CUSTOMERNUMBER and then execute the request. In response, you should get an HTTP status code 201 with a validationState: OK.

Your bank account is now successfully set up and AHOI has retrieved the account data for the AHOI Sandbank. And you also have all the other banking endpoints such as Get Account or List Transactions at your fingertips. Just give it a try!

FAQ

Banks

Which banks are currently supported within the sandbox system?

Right now, you can only use the AHOI Sandbank.

Why can I only use "AHOI Sandbank" within the sandbox system?

To provide access to real bank accounts, registration with the BaFin is required. Our registration is not yet complete, but we are expecting it to take place in 2019.

Which banks does AHOI support?

Currently AHOI supports all banks that offer FinTS with PIN and TAN. These include the Sparkassen, Volksbanks and Raiffeisenbanks as well as most private banks. One exception is Commerzbank.

Which banks will AHOI connect to in the future?

How do I set up a bank access?

Accounts

My accounts are gone. What happened?

Why do I always have to re-register with AHOI to see my account?

You don't! When you register, you receive an installationId, which you have to save. The next time you return, you can use this installationId without having to re-register and you can then access your data again.

To manage data for multiple users/installations, you will have to create your own mapping of the users/installation to the corresponding installationId.

What account types does AHOI support?

AHOI basically supports giro-type (i.e., current, checking) and securities accounts. Both account types are also offered by the AHOI Sandbank.

What account types are still planned in AHOI?

Here, too, we are guided by the needs of our customers and will implement new types of accounts provided that there is sufficient demand for them.

Transactions

How do I get new transactions from my bank?

There are two ways to get new transactions from your bank (as well as from the AHOI Sandbank).

  1. By using the max-age_parameter accordingly. That is, by telling AHOI to refresh transactions for an account with the bank if the last refresh was at least "max-age" seconds ago.

  2. If you have not configured the settings otherwise, AHOI will update the accounts for a given installationId once a day as long as you have sent at least one request during the last 30 days using this installationId.

Why am I not receiving new transactions in my AHOI Sandbank accounts?

The AHOI Sandbank accounts currently only create transactions when you register with the Sandbox Manager. New transactions are not generated on an ongoing basis. However, you can generate your own transactions:

  1. By creating transfers to these accounts via the AHOI API. For example, if you transfer money from one demo account to another demo account, corresponding transactions are created.

  2. You have the possibility to create transactions directly in the Sandbox Manager for a demo account.

  3. If you want to have a new account, delete one of your maximum of five (5) accounts and create a new account based on a selected target group in your Sandbox Manager.

  4. If you would like to fill your account with new transactions (if, for example, the last transaction is 30 days old), you can also do this in the Sandbox Manager.

Payment transactions / bank transfers / direct debits

What kind of payment transactions does AHOI currently support?

AHOI does not currently offer any payment transactions for actual accounts. You can only perform a bank transfer with our demo accounts for testing and integration purposes. We are working on support for real-world accounts.

Managing my Sandbox Manager access

I forgot my password for the Sandbox Manager. What do I do?

No problem! You can use our "Forgot password" function to securely request a new password. You will then receive an e-mail with detailed reset instructions.

I want to delete / log out / deregister my sandbox access. How can I do that?

We're sorry to see you go, but it's still a very simple process. Just log into the Sandbox Manager. Under "Settings" you'll find a section titled "Delete your sandbox access".

I want to delete data in my sandbox account without deleting the sandbox account itself. How do I do that?

Simply log into the Sandbox Manager. You can:

a) delete a single installationId from the overview page at the bottom of the "Delete Installation Data" section, or

b) delete all installationIds and their associated data for a clientId at once. Consult the "Delete All Installation Data" section on the overview page.

Production use of AHOI

I want to use AHOI in one of my applications. What do I have to do?

It depends on your application. Please contact us via e-mail at ahoi-api@starfinanz.de. It helps if you're able to describe your application and the AHOI features you want to use as well as early quantitative factors (e.g., number of users, estimated number of updates per day, estimated number of new transactions), because this will enable us to better determine the costs.

Can I also use AHOI if I am not/do not have a company regulated by ZAG?

If you are only processing your own company's account data (e.g., incoming payment checks, statistics), we can offer you a solution. Simply contact us at ahoi-api@starfinanz.de — ideally with your contact details and a short description of what you would like to do, how many bank accounts are involved and how many transactions might occur per day.

Can I use AHOI for my own application as a private individual?

No, private individuals are not allowed to use AHOI in production contexts. As a private individual, you are only allowed to use the sandbox with demo accounts.

Engineering / software development

Is there a client SDK for AHOI?

We can currently offer SDKs for Java, JavaScript and PHP. However, we are unable to provide any guarantee for these clients. The clients should help you to build your applications in a straightforward way.

Contact us via e-mail at ahoi-api@starfinanz.de with questions.

Is there a way for me to generate an AHOI client?

Yes, you can generate a client by using our swagger file, but you will have to do it yourself.

Will you also offer server-to-server notifications / webhooks?

Yes, we plan to provide server-to-server / webhook notifications in the near future.

Security

Why does AHOI store my bank access credentials?

AHOI frequently attempts to refresh your accounts in order to provide you with up-to-date information as well as to inform you via notifications about new events such as transactions. If we had to request your credentials every time, this convenient and automated approach wouldn't be possible.

Why does the AHOI client have to encrypt certain data? Why is transport encryption via TLS insufficient?

Mobile devices in particular are often exposed to insecure networks where communication can be intercepted and surveilled. To avoid this, certain data has to be encrypted.

Are there any security requirements for clients that I want to provide to my customers?

Yes, we have security requirements for clients using the AHOI API. However, these requirements only apply once the application goes live to your customers. On request, we can provide you with the "Security Standard for AHOI Clients" prior to the conclusion of the contract.

How is the encrypted JSON data encoded?

The encrypted JSON data must be serialized via Base64URL encoding (without padding) (see also the Quick Start section).

How can I tell AHOI to work with or without extended encryption?

Within the sandbox, you can turn this on or off in the Sandbox Manager via the "Advanced Encryption" setting. In a production environment this is configured by us for you (see also the first two questions regarding security above).

Contact Us

Do you need assistance? Is anything unclear?

We're more than happy to help. Just send us an e-mail: ahoi-api@starfinanz.de

We also welcome your feedback on our documentation.

Glossary