# BANKSapi Documentation — Full Guides > All BANKSapi developer guides concatenated into a single document. For the > structured index, the OpenAPI specifications and the docs MCP server, see > https://docs.banksapi.de/llms.txt --- # Overview BANKSapi provides a comprehensive suite of financial APIs and Web UIs that enable seamless integration with banking services. Our platform offers secure access to account information, payment initiation, and AI-powered financial data enrichment. Whether you're building a personal finance app, enabling account aggregation or automating payment workflows, BANKSapi delivers the tools you need with a developer-friendly interface. In this documentation you will find everything to get started. Check out our [Quick Start](/guide/quickstart) guide or try [ATLAS ↗](https://banksapi.io/atlas/){target="_blank"} to get started without coding efforts. ## OpenAPI If you are interested in API references, you can find our OpenAPI v3 documentation in the navigation bar at the top. You can also download the specifications directly: - [Download BANKS/Connect OpenAPI](/openapi/banksapi-v2-openapi-3_0.yaml) - [Download AI/Connect OpenAPI](/openapi/banksapi_ai_connect.json) - [Download PAY/Connect OpenAPI](/openapi/pay-connect-openapi-3_0.yaml) Alternatively you can view the OpenAPI specifications as Swagger UIs: - [BANKS/Connect Swagger UI](https://banksapi.io/swagger/banks-connect/) - [AI/Connect Swagger UI](https://banksapi.io/swagger/ai-connect/) - [PAY/Connect Swagger UI](https://banksapi.io/swagger/pay-connect/) - [ONE/Connect Basic Swagger UI](https://banksapi.io/swagger/one-connect-basic/) - [ONE/Connect Classic Swagger UI](https://banksapi.io/swagger/one-connect/) ## Interface strategy The APIs are created according to the [REST](/guide/concepts#rest) paradigm with respect to the architectural style [HATEOAS](/guide/concepts#hateoas). Because of the addressing logic shifted to the server, it is possible to extend the API organically without causing breaks for the callers. We ship rolling releases: changes go live continuously, several times a week, without prior announcement. Backward compatibility is our standard, so a correctly implemented client is not affected by them. In the rare case that a modification cannot be implemented in a backward-compatible manner, we inform every affected client individually, months in advance, and accompany the migration where needed. See [Versioning](/guide/concepts#versioning) for details. The interface is always called via HTTPS encryption. We currently offer JSON as a data exchange format, but if required, an extension by further formats in the future is not excluded. ## Structure of interface and documentation The **BANKS/Connect** interface is divided into three sub-APIs: [**Auth API**](/guide/auth), [**Customer API**](/guide/customer), and [**Providers API**](/guide/providers). Additionally, we offer [**AI/Connect**](/guide/ai-connect) for AI-powered financial data enrichment and [**PAY/Connect**](/guide/pay-connect) as an eCommerce checkout based payment solution. If you are using [**ONE/Connect**](/guide/one-connect), BANKSapi's single-user multibanking product, see its guide for how to obtain a token and access your connected accounts via the BANKS/Connect API. For further information please refer to the comprehensive API documentation in the sidebar. [Central concepts](/guide/concepts) like [Authentication](/guide/concepts#authentication) are described in the chapter of the same name. Furthermore, concepts applicable to each API are described in the respective API documentation. ### Feedback This documentation is primarily intended to be helpful. We are therefore pleased to receive your criticism and suggestions, which you can send to [support@banksapi.de](mailto:support@banksapi.de?subject=A%20Suggestion%20to%20docs.banksapi.de). --- # Quick Start ::: tip You can create your first user and add your first bank access without any coding efforts using [ATLAS ↗](https://banksapi.io/atlas/){target="_blank"}. ::: ## What We're Going to Do We'd like to guide you through the first steps you're probably going to take with our interface: You will probably want to create a first user and add a bank access for them. This will give you a good first impression on what data is available through our API, how to interact with it in general as well as some of the concepts we're using. For starters, bear in mind we're basing our authentication on the (2-legged) [OAuth2 protocol](/guide/concepts#oauth2). Therefore, you will be supplied with a "refresh token" in order to fetch a new access token. ::: info You can find information on token types and levels in the chapter on the [OAuth2 protocol](/guide/concepts#oauth2). We recommend you read this first and then return here. ::: ## Create a Client Token ```http POST /auth/oauth2/token HTTP/1.1 Host: banksapi.io Authorization: Basic c29<...>U= Content-Type: application/x-www-form-urlencoded grant_type=client_credentials ``` The first step will be to fetch a fresh access token on management level in order to be able to create a new user. For this, we will use the [Create Token](/api/banks-connect.html#CreateToken) call. You can see the call above. If you don't have API credentials yet, [request API access ↗](https://banksapi.de/en/free-trial/){target="_blank"}. ::: tip In order to adhere to the OAuth2 standard, this call is the only one in the API that uses content type `application/x-www-form-urlencoded` for the payload. ::: The only required field of this call is `grant_type`, which we fill with `client_credentials`, because we want to create a token on management (i.e. client) level. The `scope` parameter can be left out, in which case we will receive the full scope. If at a later point we want to limit this for security or design reasons, we can add the scopes that we'd like this token to have. ```json { "scope": "http://banksapi.io/customer/read http://banksapi.io/provider/read http://banksapi.io/customer/modify http://banksapi.io/customer/ueberweisung auth/tenants/users/create", "tenant": "demotenant", "tenantId": "550e8400-e29b-41d4-a716-446655440000", "client": "demoTenantClient", "additionalData": {}, "validTo": "2026-01-20 22:38:39", "active": true, "issuedAt": 1737408119, "expiresAt": 1737415319, "access_token": "edbc0a13-19c3-4a10-ac96-bbfe900a0a06", "token_type": "Bearer", "expires_in": 7200 } ``` The response we can see above: Together with some additional data, we receive an `access_token` of type `Bearer`, valid for two hours, for our tenant `demotenant`. Make note of the tenant name, we'll need it in the next call. ## Create a User With the new token we've just created, we will now create our first user. ::: tip A "user" in BANKSapi terminology is a technical user, corresponding 1:1 to a "customer" in the customer API. Most often, this will be a human user (i.e. end consumer). Although technically both terms signify different objects, for the sake of simplicity you can use them interchangeably. ::: ```http POST /auth/mgmt/v1/tenants/demotenant/users HTTP/1.1 Host: banksapi.io Content-Type: application/json Authorization: Bearer edbc0a13-19c3-4a10-ac96-bbfe900a0a06 { "username": "user1", "password": "Password123" } ``` For this, we will use the [Create User](/api/banks-connect.html#CreateUser) call. You can see the call above. The required fields are `username` and `password`, so we will set these values. ::: tip How you fill these values is up to you. For an app design, it might make sense to use the actual or derived password of the end consumer, or a hash of the same. This will result in you only being able to access data of the user when the user is online and has entered their password. Alternatively, you might want to create a new secret for the user and persist it in encrypted form (e.g. encrypted with a user PIN, or some other value that makes sense in your design) in your database. ::: The `Content-Type` is `application/json` in this (as in every other) case, and we use the new `Bearer` token as `Authorization`. As a last parameter, note the tenant id in the URL, because we're creating a user for that (your) tenant. This is the same tenant that we have received in the response of the previous call. The response will be an HTTP `201 Created` success status response with no body, indicating the user has been created. ## Create a User Token ```http POST /auth/oauth2/token HTTP/1.1 Host: banksapi.io Authorization: Basic c29<...>U= Content-Type: application/x-www-form-urlencoded grant_type=password&username=user1&password=Password123 ``` Now we need to fetch a fresh access token on the user level. As in the first call, we will use the [Create Token](/api/banks-connect.html#CreateToken) call, but with different parameters. You can see the call above. This time, as we're fetching a token on user level, we are using `grant_type=password`, not `client_credentials`. This is according to the OAuth2 password grant. Of course, for `username` and `password` we're using the values that we have specified in the previous call. ```json { "scope": "http://banksapi.io/provider/read http://banksapi.io/customer/read http://banksapi.io/customer/modify http://banksapi.io/customer/ueberweisung auth/tenants/users/create", "tenant": "demotenant", "tenantId": "550e8400-e29b-41d4-a716-446655440000", "client": "demoTenantClient", "user": "0049e4d6-824f-4839-823d-7a2ad4660c4e", "additionalData": { "username": "user1" }, "validTo": "2026-01-20 22:56:47", "active": true, "issuedAt": 1737409007, "expiresAt": 1737416207, "access_token": "0bac1d52-4eb0-4fe2-951e-cf6ff9dc4235", "token_type": "Bearer", "expires_in": 7200 } ``` As a response, we receive a similar JSON object as before. This time, as `additionalData` we receive the `username` to indicate it's a token on user level. That's it for the Auth API, all subsequent calls we'll make with the Customer API with our new Bearer token on user (i.e. customer) level. ## Create Bank Access ::: tip There is also an embedded way to create a bank access by utilizing WEB/Connect, a collection of web components. For more details, see the [WEB/Connect](/guide/webconnect) chapter. ::: With the new token, we can access the full range of customer interactions. But as the user has not added a bank access yet, our options are somewhat limited. So next we're going to add a bank access for that user. **Now it gets tricky**: For this operation, you will need to differentiate whether you are a regulated or a non-regulated customer. Non-regulated customers will not be allowed to receive the credentials to a provider (e.g. a bank) on their own domain. These are considered sensitive payment information and the handling of this is regulated by the authorities. Therefore, they will have to redirect the customer to us, the customer will select a bank and enter sensitive payment information on a BANKSapi frontend (REG/Protect) and complete the authorization flow, then the customer is redirected back to you. ::: tip For simplicity's sake, we are going to follow the non-regulated client flow, as this will not require us to go through the SCA cases (these are handled completely by REG/Protect). ::: ```http POST /customer/v2/bankzugaenge HTTP/1.1 Host: banksapi.io Content-Type: application/json Authorization: Bearer 0bac1d52-4eb0-4fe2-951e-cf6ff9dc4235 { "629e4510-5331-47d4-9bad-8902039ff762": { } } ``` For adding a new bank access, we will use the [Add Bank Access](/api/banks-connect.html#AddBankAccess) call. You can see the call above. No surprises in the headers, `Content-Type` is `application/json` as with all the calls in the Customer API, Authorization is our new Bearer token on user level. ::: info For interactive operations like adding bank access, you should include the `Customer-IP-Address` header with the user's IP address (e.g., `Customer-IP-Address: 123.234.123.234`). This is required by banks post-PSD2 as proof of user interaction. For details, see the [Customer IP Address](/guide/customer#customer-ip-address) section. ::: The payload requires a bit of explanation: A bank access is referenced by a UUID. Because it might be necessary for you to query the bank access object without any response from BANKSapi, this UUID needs to be chosen and set by you. Therefore, the UUID visible in the body is a new UUID that you need to create with a suitable UUID generator. ::: info It is **very advisable** except in some very rare cases to use a completely new UUID, rather than any UUID corresponding to the user. Don't be tempted to use the `user` UUID that was returned in the previous call. Although it looks simple, it will lead to problems when you add the second bank access for this user, because what will it be referenced by? ::: The banks access object (referenced by the UUID) is empty in this case as in `{}`. The reason is that in the REG/Protect case, you can neither send us a credentials object (this would require a regulatory license to handle sensitive payment data) nor a provider ID (the user will be able to select the bank in the REG/Protect wizard). The last optional flag, `sync`, indicates whether the bank access should be persisted on BANKSapi end. For REG/Protect clients, this must be true (which is also the default value) and can therefore be omitted. ```http HTTP/1.1 451 Unavailable For Legal Reasons Location: https://banksapi.io/customer/v2/webform?session=ef2fdd3b-a087-447b-843c-670325d003f4&useCase=CREATE_ACCOUNT ``` The result will be an HTTP `451 Unavailable for Legal Reasons` status response with no body. Admittedly used rarely, for this case it's the perfect response code, indicating you are not allowed to create a bank access yourself (for legal reasons) but will have to have us do it for you. In the background, we have created a corresponding short-lived frontend session and are prepared to have the user come to our domain for completing the process. The URL of our frontend will be delivered through the `Location` response header. In order for us to know where to redirect the user after completion, you will need to add a `callbackUrl` query parameter to the URL before redirecting the user there, as indicated in the docs on [Adding and authenticating bank access](/guide/customer#adding-and-authenticating-a-bank-access). This callback URL needs to be URL encoded In our example, we would therefore redirect the user to `https://banksapi.io/customer/v2/webform?session=ef2fdd3b-a087-447b-843c-670325d003f4&useCase=CREATE_ACCOUNT&callbackUrl=http%3A%2F%2Fexample.com` (or, for the first tests, open it in the browser yourself). Now you can relax for a bit, the user will be completing the process on our frontend: | Step | Screenshot | | ------ | -------------- | | Accepting our T&Cs *(only once per user, for the second bank access this step will be omitted)*| ![AGB](/images/regprotect1.png) | | Selecting a provider (see [Demo Provider](/guide/demo-provider) for test credentials) | ![Select a bank](/images/regprotect2.png) ![Select demo provider](/images/regprotect3.png) | | Entering the credentials | ![Entering credentials](/images/regprotect4.png) | | Confirming accounts | ![Confirming accounts](/images/regprotect5.png) | | Being redirected back to you | ![Redirect](/images/regprotect6.png) | The user will be redirected back to the URL you specified previously in `callbackUrl`, together with a query parameter `baReentry` indicating the result (normally `ACCOUNT_CREATED`). That's it, the account has been created. In the background, we were already communicating with the user's bank or provider, fetching and analyzing data. You can now query the data, continuing with the next requests. ## Query Bank Access ```http GET /customer/v2/bankzugaenge HTTP/1.1 Host: banksapi.io Authorization: Bearer 0bac1d52-4eb0-4fe2-951e-cf6ff9dc4235 ``` Next up, let's check if the bank access is there and what options we have to go on. We'll use the [Get Bank Accesses](/api/banks-connect.html#GetBankAccesses) call, so query all bank accesses of that user instead of a specific one referenced by the ID you chose earlier. You can see the call above. ::: tip Use the access token on the user level for this call. ::: ```json { "629e4510-5331-47d4-9bad-8902039ff762": { "id": "629e4510-5331-47d4-9bad-8902039ff762", "providerId": "00000000-0000-0000-0000-000000000000", "aktualisierungszeitpunkt": "2026-01-20 13:26:13", "tanMedien": [ { "name": "Mobil", "medienklasse": "MOBIL", "gueltigVon": "2026-01-20 13:26:13", "gueltigBis": "2026-01-20 13:26:13" } ], "sicherheitsverfahren": [ { "kodierung": 902, "name": "mockPhotoTAN", "hinweis": "Scanne das Bild. Das Ergebnis ist \"8534842\"" }, { "kodierung": 1, "name": "mockTAN", "hinweis": "Gib eine durch 2 teilbare Zahl ein" } ], "aktivesSicherheitsverfahren": { "kodierung": 1, "name": "mockTAN", "hinweis": "Gib eine durch 2 teilbare Zahl ein" }, "relations": [ { "rel": "self", "href": "https://banksapi.io/customer/v2/bankzugaenge/629e4510-5331-47d4-9bad-8902039ff762" }, { "rel": "delete_bankzugang", "href": "https://banksapi.io/customer/v2/bankzugaenge/629e4510-5331-47d4-9bad-8902039ff762" }, { "rel": "get_issues", "href": "https://banksapi.io/customer/v2/bankzugaenge/629e4510-5331-47d4-9bad-8902039ff762/issues" } ], "status": "VOLLSTAENDIG", "bankprodukte": [ { "id": "DE00123456789012345678", "status": "VOLLSTAENDIG", "bezeichnung": "Girokonto", "kategorie": "GIROKONTO", "saldo": 2145.78, "aktualisierungszeitpunkt": "2026-01-20 13:26:13", "saldoDatum": "2026-01-20 00:00:00", "waehrung": "EUR", "kontonummer": "9012345678", "iban": "DE00123456789012345678", "bic": "XXX12345678", "blz": "12345678", "kreditinstitut": "Demo Provider", "inhaber": "Fritz Testmüller", "relations": [ { "rel": "start_ueberweisung", "href": "https://banksapi.io/customer/v2/ueberweisung/00000000-0000-0000-0000-000000000000/DE00123456789012345678" }, { "rel": "self", "href": "https://banksapi.io/customer/v2/bankzugaenge/629e4510-5331-47d4-9bad-8902039ff762/DE00123456789012345678" }, { "rel": "get_kontoumsaetze", "href": "https://banksapi.io/customer/v2/bankzugaenge/629e4510-5331-47d4-9bad-8902039ff762/DE00123456789012345678/kontoumsaetze" }, { "rel": "get_kontoumsaetze_tagged", "href": "https://banksapi.io/customer/v2/bankzugaenge/629e4510-5331-47d4-9bad-8902039ff762/DE00123456789012345678/kontoumsaetze?tag=true" }, { "rel": "get_kontoumsaetze_insurances", "href": "https://banksapi.io/customer/v2/bankzugaenge/629e4510-5331-47d4-9bad-8902039ff762/DE00123456789012345678/kontoumsaetze?tag=insurances" }, { "rel": "get_kontoumsaetze_business_partners", "href": "https://banksapi.io/customer/v2/bankzugaenge/629e4510-5331-47d4-9bad-8902039ff762/DE00123456789012345678/kontoumsaetze?tag=business-partners" } ], "messages": [], "ueberziehungslimit": 3000.0, "verfuegungsrahmen": 2045.78, "verfuegterBetrag": 100.0 } ], "sync": true } } ``` As a response, the server will return the (now filled) bank access object we created earlier. Find a sample response above. Wow, there is a lot going on, so let's dissect: Top level, we have an object representing a collection of all bank accesses of that user. In this case, we have yet only created one, so the collection has one entry with the key `629e4510-5331-47d4-9bad-8902039ff762`, which is the UUID we chose earlier for the bank access. In that object, representing this specific bank access, we have some attributes: There's the `id` again, no surprise there, there is a `providerId`, which we could use to query some info on the bank the user chose through a [Get Provider](/guide/providers) call, there is an `aktualisierungszeitpunkt` which represents the timestamp of the last update (in which we fetched fresh data from the bank), there is some meta info on SCA (`sicherheitsverfahren` and `aktivesSicherheitsverfahren`) which is probably not interesting for you right now, a `status` flag which should be `VOLLSTAENDIG` by now and an indication of the `sync` flag, i.e. whether this bank access is persisted on BANKSapi side, can be queried by you any time in the future and will be refreshed from the bank up to four times a day. Next, there is an array `relations`, that contains actions that you can take with this bank access and the corresponding URL. See our chapter on [HATEOAS](/guide/concepts#hateoas) for more info on this design. Then there is another array, `bankprodukte`. Remember, under one bank access can be multiple bank products, as you can have several accounts with a bank that you can all access with the same set of credentials. ```json { "id": "DE00123456789012345678", "status": "VOLLSTAENDIG", "bezeichnung": "Girokonto", "kategorie": "GIROKONTO", "saldo": 2145.78, "aktualisierungszeitpunkt": "2026-01-20 13:26:13", "saldoDatum": "2026-01-20 00:00:00", "waehrung": "EUR", "kontonummer": "9012345678", "iban": "DE00123456789012345678", "bic": "XXX12345678", "blz": "12345678", "kreditinstitut": "Demo Provider", "inhaber": "Fritz Testmüller", "relations": [{ "rel": "start_ueberweisung", "href": "https://banksapi.io/customer/v2/ueberweisung/00000000-0000-0000-0000-000000000000/DE00123456789012345678" }, { "rel": "self", "href": "https://banksapi.io/customer/v2/bankzugaenge/629e4510-5331-47d4-9bad-8902039ff762/DE00123456789012345678" }, { "rel": "get_kontoumsaetze", "href": "https://banksapi.io/customer/v2/bankzugaenge/629e4510-5331-47d4-9bad-8902039ff762/DE00123456789012345678/kontoumsaetze" }, { "rel": "get_kontoumsaetze_tagged", "href": "https://banksapi.io/customer/v2/bankzugaenge/629e4510-5331-47d4-9bad-8902039ff762/DE00123456789012345678/kontoumsaetze?tag=true" }, { "rel": "get_kontoumsaetze_insurances", "href": "https://banksapi.io/customer/v2/bankzugaenge/629e4510-5331-47d4-9bad-8902039ff762/DE00123456789012345678/kontoumsaetze?tag=insurances" }, { "rel": "get_kontoumsaetze_business_partners", "href": "https://banksapi.io/customer/v2/bankzugaenge/629e4510-5331-47d4-9bad-8902039ff762/DE00123456789012345678/kontoumsaetze?tag=business-partners" } ], "messages": [], "ueberziehungslimit": 3000.0, "verfuegungsrahmen": 2045.78, "verfuegterBetrag": 100.0 } ``` This array contains (probably multiple) bank products. Let's dissect also one of the bank products, e.g. the one above. Again, there is an `id`, this time of this specific product, there is a `status` which is the same as for the bank access. Again there is a lot of meta info (see the corresponding [Bank Product Schema](/api/banks-connect.html#GetBankProduct) for a complete list). And there are some relations in the `relations` array, indicating which actions you can take next: | Relation | Explanation | Corresponding call | | ------ | -------------- |-------------- | | `self` | Query only this bank product | [Get Bank Product](/api/banks-connect.html#GetBankProduct) | | `initiate_single_transfer` | Initiate a wire transfer from this account. This relation is only returned for accounts from which BANKSapi supports transfers, mainly payment accounts | [Initiate Single Transfer](/api/banks-connect.html#InitiateSingleTransfer) | | `get_kontoumsaetze` | Get transactions for this product | [Get Transactions](/api/banks-connect.html#GetTransactions) | | `get_kontoumsaetze_tagged` | Get transactions for this product, tagged (categorized) | [Get Transactions](/api/banks-connect.html#GetTransactions) with the "categories" as tag query param | | `get_kontoumsaetze_insurances` | Get transactions for this product, tagged with insurance tags (only the ones that are insurance transactions of course) | [Get Transactions](/api/banks-connect.html#GetTransactions) with the "insurance-types" as tag query param | | `get_kontoumsaetze_business_partners` | Get transactions for this product, tagged with normalized business partners | [Get Transactions](/api/banks-connect.html#GetTransactions) with the "business-partners" as tag query param | We're interested in the transactions of this account, so we'll fetch those next, using the `get_kontoumsaetze` relation. ## Query Transactions ```http GET /customer/v2/bankzugaenge/629e4510-5331-47d4-9bad-8902039ff762/DE00123456789012345678/kontoumsaetze HTTP/1.1 Host: banksapi.io Authorization: Bearer 0bac1d52-4eb0-4fe2-951e-cf6ff9dc4235 ``` The transactions we can query with a bank-product-specific URL, given to us through the `get_kontoumsaetze` relation earlier. We'll use that URL with the [Get Transactions](/api/banks-connect.html#GetTransactions) call. You can see the call above. ::: tip Use the access token on the user level for this call. ::: ```json [ { "id": "1975f080-0001-b4f7-727b-aec310895541", "betrag": -100.0, "verwendungszweck": "GA NR00006110 BLZ70020270 3 07.02/14.29UHR MÜNCHEN,KARD EUR 100,00 ENTGELT 0,00 Ref. 3QL15041A1357856/83343", "buchungstext": "", "buchungsdatum": "2026-01-18 00:00:00", "wertstellungsdatum": "2026-01-15 00:00:00", "gegenkontoInhaber": "", "gegenkontoIban": "", "gegenkontoBic": "", "primanotaNummer": "0", "hash": "1b4f7727-baec-3107-9554-1cf472933ccf" } ] ``` As a result, we're greeted with an array of transactions. For details on the attributes, head over to the [Transaction Schema](/api/banks-connect.html#GetTransactions) ## Force a Refresh of Data From the Bank ```http POST /customer/v2/bankzugaenge?refresh=true HTTP/1.1 Host: banksapi.io Content-Type: application/json Authorization: Bearer 0bac1d52-4eb0-4fe2-951e-cf6ff9dc4235 { "629e4510-5331-47d4-9bad-8902039ff762": { } } ``` Although we refresh `sync`ed bank accesses up to four times a day, in some cases, you might want to force BANKSapi to fetch fresh data from the provider. It is therefore a good idea to implement some kind of refresh button for the user, which in turn should force an actual refresh from the bank and not just return cached data from BANKSapi. In order to force BANKSapi to fetch fresh data, we will use the same call that we used when creating a bank access, only this time we are using the UUID of the bank access we want to refresh, and add a `refresh=true` as a query parameter, as in the example above. This time, this will be confirmed by a `201 Created` HTTP status, indicating the refresh has been triggered. You can now query the bank access again and should see fresh data. ## Renew Consent with SCA / TANs At some point, the user consent we create implicitly with the previous calls will run out. Bear in mind, this is the consent the users gave to us to fetch data from the bank, so the bank will honour this consent and we have no choice but to renew it. Usually, under PSD2, the consent is valid for 180 days, although some products from some banks require more frequent renewals (some even for every refresh) and there are always things that can prevent us from fetching fresh data from the bank, e.g. a locked account or the user manually removing the consent. A *renewal of consent* is a fancy way of saying the user has to enter a TAN or going through a similar process with a TAN-less SCA method such as AppTAN. We will indicate the necessity of SCA renewal with a `start_sca` relation. In this case, we might have been able to refresh some but not all bank products, or none at all, and will remain in this state until the user refreshes their consent. In the meantime, you will still be able to query data from BANKSapi, but it will not be the most recent but the last state that we were still be able to fetch. ```json { "rel": "start_sca", "href": "https://banksapi.io/customer/v2/bankzugaenge/629e4510-5331-47d4-9bad-8902039ff762/consent/59f168d6-3a45-4db5-bcd5-94f29d64bbfa" } ``` Therefore, if you encounter a `start_sca` relation, you will have to have the user go through the SCA process again, similar to when they added the bank access, but without them having to choose the provider or enter their credentials. In this case, it's just the SCA process they will have to go through ::: tip It depends a lot on your use case and UX design when you should have the user go through the SCA process. As you're still able to fetch (old) data, it doesn't have to be immediately. In fact, we recommend you choose a time that is convenient for the user to go through a TAN process. I.e., you would not want to blast a popup in the user's face first thing after app opening, because chances are they had some other task in mind that they wanted to achieve. Thus, they are very likely to cancel the process or close the app. Instead, wait for them to complete the task they were likely going to do and ask them afterwards. ::: ```http HTTP/1.1 451 Unavailable For Legal Reasons Location: https://banksapi.io/customer/v2/webform?session=c2a71efd-71b0-47ea-951a-2abcea1c8578&useCase=AUTHENTICATE_ACCOUNT ``` So we realize the consent has expired and the user has to complete the SCA process, because we received a `start_sca` relation with the bank access. Now we proceed as documented in [Operations with SCA](/guide/customer#operations-with-sca) and `POST` to the `start_sca` relation. In response, we will receive a response like the one above. Now, the HTTP `451 Unavailable for Legal Reasons` status code seems familiar, doesn't it? Now, we follow the same procedure as before while [Creating the bank access](#create-bank-access), adding a `callbackUrl` and sending the user over to BANKSapi. When the user returns, the bank access should be fully accessible again and `start_sca` gone. ## Query Issues The bank access, bank products and transactions we return are in a so-called "stable" state, meaning that this is the best data that is available to us. We update this stable state only if a refresh from a bank is successful. However, if fetching a bank access yields any issues, e.g. when the user has changed their login credentials without our knowledge, the stable state is unchanged because we do not want to taint the data with "bad" new data, potentially removing transactions from the storage you are relying on because we do not "see" them. ::: tip Issues that the user can react on, such as the necessity for consent renewal, we deliver inside the stable object. All other issues (e.g. an error in the communication with the bank) will be accessible to you only through the issues endpoint. ::: Inevitably, there will be an account that is not refreshed any more. It is therefore a good practice to implement the call to fetch potentials issues as well. Best case, the list of messages is returned empty and there is nothing to do. ```json { "rel": "get_issues", "href": "https://banksapi.io/customer/v2/bankzugaenge/629e4510-5331-47d4-9bad-8902039ff762/issues" } ``` To fetch bank access issues, we will use `get_issues` relation that is returned as part of the bank access. We will receive what will look like a subset of a bank access, but in this case it is not in the "stable" state but in a state we call "tentative", i.e. containing not the best data available to us, but the latest state, and thus any issues that might have arisen during fetching updated data from the bank. ```json { "id": "629e4510-5331-47d4-9bad-8902039ff762", "tanMedien": [], "providerId": "00000000-0000-0000-0000-000000000000", "sicherheitsverfahren": [], "aktualisierungszeitpunkt": "2026-01-20 13:26:13", "messages": [{ "code": "BA1011", "level": "ERROR", "details": "Ungültige Zugangsdaten", "message": "Zugangsdaten nicht korrekt" }], "relations": [{ "rel": "delete_bankzugang", "href": "https://banksapi.io/customer/v2/bankzugaenge/629e4510-5331-47d4-9bad-8902039ff762" }] } ``` For all errors and issues that can arise, head over to the docs on [Message codes](/guide/errors-messages#message-codes). ## REG/Protect Session Management **Best Practice:** We recommend [deleting all REG/Protect sessions](/api/banks-connect.html#DeleteAllRegprotectSessions) before starting new processes. This is important because previous processes might have ended abruptly (e.g., by closing the browser prematurely), which could leave sessions in an inconsistent state. ## Where to Go From Here You've done the first steps with our API - why not explore a bit yourself? HATEOAS makes it very easy to start exploring the API through relations - or you can go on reading this documentation. Some hints on what to do next: - You can try to add real bank access and see what real-world data looks like - You could implement features for [brokerage accounts](/api/banks-connect.html#GetPortfolio) - You can explore our [AI/Connect](/api/ai-connect.html) features to learn more about the user --- # Central Concepts ## Authentication > Authentication is important, but in our [Quick Start Guide](/guide/quickstart) we minimize coverage of authentication details so you can focus on your core requirements and address authentication later. With **BANKS/Connect**, there are three authentication methods: - Authentication as a [client](#client) using an OAuth 2.0 client token. - Authentication as a [user](#user) using an OAuth 2.0 user token. - Authentication with the bank or service provider using [encrypted](#encryption) provider credentials. Additionally, the **BANKSapi Auth API** includes an admin client that you can use to create and manage users. The authentication method required for each operation is specified in the corresponding sub-API documentation. As a general rule, all requests to **BANKS/Connect** are made in the context of a client, which is sufficient for operations like querying providers. Other operations require a user token and appropriate bank access consents. ## Bank In **BANKS/Connect**, the institutions from which we collect data on your behalf are referred to as "banks". Banks and [service providers](#service-provider) are collectively called [Providers](#provider). The banks activated for you in **BANKS/Connect** can be accessed via the **BANKS/Connect Providers API**. ## User > The unique user is the primary billing unit. Additional details are defined in your service agreement. A user encompasses all data retrieved about a person from various banks or service providers. With **BANKS/Connect**, users belong to you, the [client](#client). Access to the financial data of your users is provided via the **BANKS/Connect Customer API**. With the [**BANKS/Connect Auth API**](#authentication), you can manage your users. ## Client We use the term *client* to refer to both your application(s) and an "admin client" for managing users. From our perspective, a client is a set of access credentials for **BANKS/Connect**. Using a client ID, you can obtain client tokens via the **BANKS/Connect Auth API** using [OAuth2](#oauth2). These tokens can then be used to access functions in the **BANKS/Connect Customer API** and the **BANKS/Connect Providers API**. ::: info Client credentials must be kept secret. However, since typical clients require limited access, an admin client is available for user management. Standard user creation is usually possible with a normal client. We will define the exact process with you during the integration phase. ::: ## Correlation ID ```http GET / HTTP/1.1 x-correlation-id: c129b93a-9b5c-11e6-a112-480fcfb9550f ``` The Correlation-ID is used to track requests across all systems. The Correlation-ID can be passed to the **BANKSapi APIs** as HTTP header **X-Correlation-ID**. If it is not passed, the **BANKSapi APIs** generate their own ID. In any case, the value is also returned as the HTTP response header **X-Correlation-ID**. ::: info The correlation ID **must** be a UUID ::: ## CORS > [More information about CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) on Wikipedia. **BANKS/Connect** supports Cross-Origin Resource Sharing (CORS), allowing you to call our APIs directly from the browser, for example in single-page applications. ## Errors Errors cannot always be avoided, but they can be handled gracefully. External dependencies such as banks and service providers connected via **BANKS/Connect** may have varying availability beyond our control. Therefore, the **BANKS/Connect Customer API** provides *message objects* containing a code, a generic error description suitable for your end customers, and a detailed message for internal error handling. For more technical errors, we use the full range of [HTTP status codes](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes), including syntax errors, authentication failures, concurrent requests, network problems, and similar conditions. For details about the possible message objects and the HTTP status codes, see the [Errors and Messages](/guide/errors-messages) section in the **BANKS/Connect Customer API** documentation. ## HATEOAS > [More information about HATEOAS](https://en.wikipedia.org/wiki/HATEOAS) on Wikipedia. HATEOAS stands for "Hypermedia as the Engine of Application State." With HATEOAS, a [REST interface](#rest) client navigates only to URLs provided by the server that are relevant in the current context. These URLs are identified by relation names that convey semantic meaning, so clients only need to know a few fixed entry points. These URLs are communicated to clients as [relations](#relation) in resource representations or in the HTTP "Location" header. ## Timestamp > For example: > > `2016-09-03 04:27:00` > `2019-12-04 13:37:00` > `2010-01-01 22:03:54` Timestamps are always output without time zone information, using the ISO 8601 format `YYYY-MM-DD hh:mm:ss`. Values must be interpreted in the `Europe/Berlin` time zone. ## JSON ```json { "aString": "Lorem ipsum dolor sit amet", "anInteger": 42, "aFloat": 42.1337, "aBool": true, "aDate": "1969-07-20", "aTimestamp": "2016-09-03 04:27:00", "anArrayOfInteger":[1,2,3], "anArrayOfStrings":["one", "two", "three"], "anObject":{ "cat": "kitten", "dog": "puppy" } } ``` The **BANKS/Connect** interfaces use JSON (JavaScript Object Notation) for data exchange. Attributes without values are omitted rather than returned as `null`. Dates and timestamps are represented as ISO 8601-formatted strings. Consumers must ignore unknown attributes in JSON documents. This is particularly important for enumeration types, where adding new values is considered backward-compatible. When delivering JSON, the `Content-Type: application/json` header must always be included. For `null` values, fields may be omitted or sent with a `null` value unless they are mandatory. ## Your client > There is also a demo client, for example in our [Quick Start Guide](/guide/quickstart). Your client is you or the company that has entered into a cooperation agreement with us. For definitions, see [Client](#client) and [User](#user). As a client, you have access to our first-class support and benefit from the ongoing development of **BANKS/Connect**. You will also see more data than just our demo bank. If you are interested, please [contact us](https://banksapi.de/kontakt/). ## OAuth2 All calls to the BANKSapi interfaces must be made with a valid OAuth2 token. For some operations, a client token (without a specific user) is sufficient. Details on user and client management are described in the **BANKSapi Auth API**. ### Token types BANKSapi is working in a 2-legged OAuth2 setting. This means you will be supplied a **refresh token**. With this, you will have to fetch a fresh **access token** for almost all calls within our APIs. The refresh token (actually a set of Basic Auth credentials) is valid for a long time and used exclusively to fetch new access tokens. It is a Basic token, you will have to authenticate with `Authorization: Basic ` An access token has a validity of 2 hours, after which you will need to create a new token. Depending on your design and use case, we recommend that you either keep track of the validity and fetch a new token in time, or you fetch a new access token per business transaction, in which case you can go without persistence of the token. You will have to authenticate with `Authorization: Bearer ` ### Token levels Access tokens can be on client or on user level. If nothing is explicitly documented in the corresponding use case, the call with a [unique user](#user) is assumed. Bear in mind you can't do calls like e.g. add a new bank access on a client (i.e. management) level as these would be available for all users, but only on user level. But a user can't create new users, this must be done on a management level. ::: tip There are two levels of tokens in BANKSapi: Management level (e.g. to create new users) and user level (e.g. to add bank accesses for a specific user). ::: ### Token usage When calling, the token must be transferred according to the OAuth2 standard in the header "Authorization: Bearer ...". If this header is missing or the token is invalid, the interface responds with the HTTP status code 401 (Unauthorized). If the token does not contain the necessary authorizations, the HTTP status code 403 (Forbidden) is reported. ## Provider As providers we refer to the connected [banks](#bank) and [service providers](#service-provider) in a very abstract way. The connection is made using a wide variety of technologies and in the end the collected data will be converted into a uniform format for you. ## Relation ```json { "rel": "say_hello", "href": "https://banksapi.io/hello/" } ``` A relation corresponds to an application or business transaction that is supported by the surrounding data object. For every application and business transaction, there is a separate documentation that describes both the call and the return or the possible alternative response scenarios in the in detail. Each relation consists of a keyword (e.g. "get_kontoumsaetze") and a URL. A client that is interested in the transactions of a bank product calls the specified URL with the HTTP verb specified in the documentation. ## REST > Recommended reading: [Roy Fielding: REST APIs must be hypertext-driven](http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven) Our APIs are implemented as REST patterns (Representational State Transfer). Consequently, they are usable via the HTTP protocol and use more HTTP verbs than just GET and POST. Furthermore, we strive to meet the requirements of the REST inventor Roy Fielding for a REST API by reflecting on the [HATEOAS architectural style](#hateoas) to do justice to this. ## Service Provider Service providers are connected financial institutions that are not a [bank](#bank). In the context of **BANKS/Connect** they are also more generally referred to as [Provider](#provider). Information about service providers can be obtained through the **BANKS/Connect Providers API**. ## Language The German banking domain contains many technical terms without clear English equivalents. To avoid awkward "Denglisch", we retain established German terms in German and use English for all other concepts. Speaking of languages, **BANKS/Connect** is primarily implemented in Java and other JVM languages. ## Encryption ```json { "plaintext": "BANKSapi", "Ciphertext": "ONAXFncv" } ``` To allow **BANKS/Connect** to access bank data, your access credentials must be available. Since this information is highly sensitive, the credentials are protected by strong asymmetric encryption. You will receive an RSA public key at the start of the integration; the private key remains securely with BANKSapi. This ensures credentials can be encrypted but not decrypted by third parties. The procedure is described in detail in the documentation for the [BANKS/Connect Customer API](/guide/customer). > We check the quality of our TLS configuration with the tool [Qualys SSL Labs](https://www.ssllabs.com/ssltest/analyze.html?d=banksapi.io&latest). Otherwise, of course, the transport route is encrypted using TLS (HTTPS). ## Versioning > The `v2` in a URL such as `/customer/v2` denotes the interface generation, not a release. It has been unchanged for years. We do not use semantic versioning and we do not publish versioned releases. **BANKS/Connect** is developed with rolling releases: changes go live continuously, several times a week, without prior announcement. Our standard is backward compatibility. New attributes, new enumeration values, new endpoints and new [relations](#relation) can appear at any time. A correctly implemented client — one that ignores unknown attributes and unknown enumeration values (see [JSON](#json)) and follows [relations](#relation) instead of hardcoding URLs (see [HATEOAS](#hateoas)) — continues to work without modification and simply does not use the new features. Should a feature not be implementable in a backward-compatible manner, we inform every affected client individually, months in advance, and accompany the migration where needed. This is the rare exception rather than a regular occurrence. The version in the URL path therefore does not change with releases. It would only change with a fundamentally new interface generation, which is not planned. --- # BANKS/Connect Auth API At **BANKSapi**, protecting personal data is our highest priority. Encryption and the use of security tokens throughout the entire process are central components of our security concept. The **BANKSapi Auth API** provides functions for managing [Users](/guide/concepts#user). Using the [OAuth2 protocol](/guide/concepts#oauth2), you can create tokens to authorize only the functions required for your use case. The API also includes a ONE/Connect token endpoint that uses API key authentication for single user scenarios. This API is required to access all BANKSapi APIs. ::: info The entry point for the **BANKSapi Auth API** is [**https://banksapi.io/auth**](https://banksapi.io/auth). The API is divided into management ([**https://banksapi.io/auth/mgmt/v1**](https://banksapi.io/auth/mgmt/v1)) and OAuth2 ([**https://banksapi.io/auth/oauth2**](https://banksapi.io/auth/oauth2)). ::: ## API Reference - [BANKS/Connect OpenAPI Reference](/api/banks-connect.html) - [Download OpenAPI Specification](/openapi/banksapi-v2-openapi-3_0.yaml) --- # BANKS/Connect Customer API At the heart of **BANKS/Connect** is the **BANKS/Connect Customer API**, which enables your end customers to access their financial lives and make payments within your product. The core element of the API is the [Customer](/api/banks-connect.html#GetCustomer), which you can use via [Relations](/guide/concepts#relation) to dive in detail into the data that can be determined about your customer. To get started, see our [Quick Start Guide](/guide/quickstart). ::: info The entry point to **BANKS/Connect Customers API** is [**https://banksapi.io/customer/v2**](https://banksapi.io/customer/v2). ::: ## Example Response The following example is slightly shortened. In practice, there would be additional relations on the bank access and bank products regarding payment and AI features. ```json { "id": "0b7f4783-4c93-4820-8e73-354a0f1c469e", "providerId": "00000000-0000-0000-0000-000000000000", "status": "VOLLSTAENDIG", "aktualisierungszeitpunkt": "2025-10-15 09:13:44", "sync": true, "tanMedien": [{ "name": "Mobil", "medienklasse": "MOBIL", "gueltigVon": "2025-10-15 09:13:44", "gueltigBis": "2025-10-15 09:13:44" }], "sicherheitsverfahren": [{ "kodierung": 1, "name": "mockTAN", "hinweis": "Gib eine durch 2 teilbare Zahl ein" }, { "kodierung": 999, "name": "iTAN", "hinweis": "Gib die TAN \"12\" an." }], "aktivesSicherheitsverfahren": { "kodierung": 999, "name": "iTAN", "hinweis": "Gib die TAN \"12\" an." }, "relations": [{ "rel": "self", "href": "https://banksapi.io/customer/v2/bankzugaenge/0b7f4783-4c93-4820-8e73-354a0f1c469e" }, { "rel": "delete_bankzugang", "href": "https://banksapi.io/customer/v2/bankzugaenge/0b7f4783-4c93-4820-8e73-354a0f1c469e" }], "bankprodukte": [{ "id": "DE00123456789012345679", "status": "VOLLSTAENDIG", "bezeichnung": "Tagesgeldkonto", "kategorie": "TAGESGELDKONTO", "saldo": 27365.56, "aktualisierungszeitpunkt": "2025-10-15 09:13:44", "saldoDatum": "2025-10-15 00:00:00", "waehrung": "EUR", "kontonummer": "9012345679", "iban": "DE00123456789012345679", "bic": "XXX12345678", "blz": "12345678", "kreditinstitut": "Demo Provider", "inhaber": "Fritz Testmüller", "transferSupport": true, "relations": [{ "rel": "get_kontoumsaetze", "href": "https://banksapi.io/customer/v2/bankzugaenge/0b7f4783-4c93-4820-8e73-354a0f1c469e/DE00123456789012345679/kontoumsaetze" }, { "rel": "initiate_single_transfer", "href": "https://banksapi.io/customer/v2/payment/single-transfer" }, { "rel": "initiate_bulk_transfer", "href": "https://banksapi.io/customer/v2/payment/bulk-transfer" }], "messages": [], "verfuegungsrahmen": 27365.56, "verfuegterBetrag": 0.0 }] } ``` ## API Reference - [BANKS/Connect OpenAPI Reference](/api/banks-connect.html) - [Download OpenAPI Specification](/openapi/banksapi-v2-openapi-3_0.yaml) ## Concepts ### REG/Protect (redirect solution) The BANKSapi [REG/Protect](#reg-protect) allows users to perform authorization completely in a frontend provided by BANKSapi. The account information is stored by BANKSapi. The sensitive payment data is transferred directly from the end user to the BANKSapi systems, processed by BANKSapi and stored by BANKSapi. It is not possible to read the sensitive payment data from BANKSapi. In addition to regulated clients, as a non-regulated client you can also use BANKSapi REG/Protect to extend your range of services to include use cases based on the use of an account information service (KID) and a payment initiation service (ZAD), but without your own ZAD license or KID registration. Since 2018, BaFin has been obliged to register/license payment accounts if online banking is used to access payment account data and trigger payments. For enhanced security, tenants can configure allowed callback URL patterns to restrict which URLs can be used when returning from REG/Protect processes. This provides additional protection for end users by preventing unauthorized redirects. Patterns support wildcards (e.g., `https://*.banking.com/*`, `intent://banksapi.finished/`). If you wish to implement such restrictions, please contact BANKSapi to configure these security settings. ### Background update A background update can be requested when adding a bank access. The bank access and its products and transactions are then queried and updated up to four times (4x) a day. The amount of background updates regresses over time if the user activity declines. ### Strong customer authentication A Strong Customer Authentication (SCA) ensures that accesses to a user's payment account online and initiations of electronic payment transactions are performed with multi-factor authentication. An SCA uses two out of three factors of: - Knowledge - Possession - Inherence We differentiate between TAN (i.e. embedded) and TAN-less (i.e. decoupled) security procedures. TAN procedures such as smsTAN, eTAN, chipTAN, photoTAN, pushTAN etc. are most frequently used. TAN-less procedures include apps provided by the banks to the end customers that can be used to just approve of activities. In this case the phone itself is the possession factor. For [Update Bank Access Consent](/api/banks-connect.html#UpdateBankAccessConsent), this means that an empty object can be submitted to indicate the user indicated that he meanwhile confirmed the activity, e.g. through the bank app. There is also the case of a redirect SCA, which is a special type of a decoupled SCA, which redirects from your application directly to a bank interface, where the user will authenticate himself. This authentication can include a TAN, but since the user is on the bank interface it is still considered a decoupled procedure from your application's or BANKSapi's point of view. Please note that not all safety procedures are supported by FinTS/HBCI. ### TAN medium The TAN medium is used to generate (e.g. chipTAN) or receive (e.g. smsTAN) TANs. BANKSapi will provide you with a list of TAN Media, while an SCA is in progress and if an SCA demands it. Here are a few examples of TAN procedures and TAN media: | TAN procedure | Media class | Name | | ------------- | ------------ | ---- | | mobileTAN (mTAN) | Mobile phone | +49-1111-1111111 | | smsTAN | Mobile | +49-1111-111111 | | chipTAN | Generator with EC Card | Sample Bank Card 1234567890 | | Sm@rtTAN | Generator with bank card | Sample bank card 1234567890 | | e-TAN | Generator | Generator | | photoTAN | App or generator | Phone of User X | | PushTAN / appTAN | App | Phone of User X | ::: info The exact characteristics of the media class and the name are not necessarily identical for each security procedure, as they depend on the respective provider. ::: ## Customer IP Address Post-PSD2, we can do interactive actions with the bank only if supplying the IP address of the user. In order to support manual refreshs, adding bank access, and other actions with user interaction, we need to indicate that the user is active (interactive calls). As proof of user interaction, the banks require the current IP address of the user. In order to supply this to the banks, as we do not have direct interaction with the user, you will have to supply this IP address. You may supply it at any time (we will not persist this and ignore if not needed), but should supply when doing the following requests: * `add_bankzugang` * `start_ueberweisung` * `delete_bankzugang` * `delete_bankzugaenge` * `start_sca` The header should be sent as a standard HTTP request header in the following format: ```Customer-IP-Address: 123.234.123.234``` ## REG/Protect The REG/Protect redirect solution provides a web frontend for adding bank accesses and triggering payments and therefore handling complex interactions with the provider for you. #### Context info when returning to your app The return of the user can happen for different reasons. The reason is provided in the query parameter `baReentry`. | Type of return | Example | Value for baReentry | |-----------------------------------------------|-----------------------------------------------------------------------------------------------------|------------------------------------| | User does not agree with terms and conditions | User declined the terms and conditions, or opened a page in the web form without accepting them | LEGAL_NOT_ACCEPTED | | Termination of the process | User terminated process | USER_CANCELLED | | Unexpected HTTP Response | Unhandled and unexpected backend error | BACKEND_ERROR | | Access data incorrectly entered | | INVALID_CREDENTIALS | | TAN incorrectly entered | | INVALID_TAN | | General error | Guard prevents mask access; possible manipulation attempt; various errors | ERROR | | No accounts found for bank transfer | No accounts or no accounts suitable for bank transfer were found when the bank transfer was started | NO_ACCOUNTS | | Account successfully created | | ACCOUNT_CREATED | | Payment successfully executed | Payment triggered via a payment endpoint (e.g. single transfer) completed | PAYMENT_SUCCESS | | Bank is slow to provide data | The bank needs more time to deliver the requested data; the query continues in the background | WAITING_FOR_PROVIDER | | Error creating initialization letter | | ERROR_CREATING_INI_LETTER | | Initialization letter created | | INI_LETTER_CREATED | | No accounts could be retrieved | No accounts could be retrieved while creating the bank access | ERROR_NO_ACCOUNTS | | Invalid bank transfer data | | INVALID_BANK_TRANSFER_DATA | | Invalid callback URL | | INVALID_CALLBACK_URL | | Callback URL not allowed | The callback URL does not match the allow-list configured for the tenant | INVALID_CALLBACK_URL_BASE | | No callback URL provided | | NO_CALLBACK_URL | | No security method provided | | NO_SECURITY_METHOD | | Concurrent bank access creation | The same bank access is already being created at the same time | CONCURRENT_CREATION_OF_SAME_ACCESS | | Session timed out | | SESSION_TIMEOUT | | No session provided | The web form was opened without a session ID | NO_SESSION | | Invalid session | The session ID is invalid or has expired | INVALID_SESSION | | No use case provided | The web form was opened without a use case | NO_USE_CASE | ::: info This list may be extended over time. To detect success, rely on the explicit success values for your use case (`ACCOUNT_CREATED`, `PAYMENT_SUCCESS`, `INI_LETTER_CREATED`). ::: ### Adding and authenticating a bank access ```bash $ curl https://banksapi.io/customer/v2/bankzugaenge \ -X POST \ -H 'authorization: Bearer 0defaced-1337-d00d-c0de-face8badcafe' \ -H 'content-type: application/json' \ -d '{"637a3945-bb02-4e82-ac9e-f7c26d2568ce": {}}' < HTTP/1.1 451 < Content-Length: 0 < Location: https://banksapi.io/customer/v2/webform?session=b19c3937-...-3b861be7e71e&useCase=CREATE_ACCOUNT ``` When you create a bank access as a non-regulated client, you will receive the URL for this call with a `451` HTTP-Response in the `Location`-Header. The status code serves as an indicator that the use case must be continued in the context of the BANKSapi REG/Protect. When BANKSapi synchronizes your account data with your banking provider, we might encounter an expired consent (cf. [Operations with SCA](#operations-with-sca)). A consent renewal has to be performed then, which we will communicate with an `authenticate` relation. ::: info Where the ASPSP (i.e. the bank) has opted for a redirection or a decoupled approach, the payment service user (PSU) has to be redirected to the ASPSP's domain to authenticate. The customer journey designed by the ASPSP must not be re-engineered, and the redirection provided by the ASPSP must not be embedded into your own environment in order to provide the PSU with a user interface of your own. The technical specifications set out by the ASPSP have to be followed when accessing its interface (see EBA Q&A [2021_6044](https://www.eba.europa.eu/single-rule-book-qa/qna/view/publicId/2021_6044) and [2021_6245](https://www.eba.europa.eu/single-rule-book-qa/qna/view/publicId/2021_6245)). This concerns the authentication procedure of the ASPSP only. REG/Protect is a BANKSapi frontend, so how you integrate it is up to you. Where a redirection to the ASPSP is part of the process, REG/Protect performs it for you; your integration has to let that step take place in the ASPSP's own environment. ::: The location header then contains the URL to be called on the BANKSapi page. You can open the web form in the current browser window, in a separate window, or integrate it into your own application, for example with the [REG/Protect web component](/guide/webconnect). For security reasons, it can only be called up once. This starts the RegProtect process at BANKSapi and the end customer has the possibility to select a provider and enter his online banking credentials in the following forms delivered by BANKSapi. You must append a query parameter `callbackUrl` to this URL (URL-encoded), which is called again by BANKSapi after the successful (or failed) registration of the end customer's bank access. Overview of all REG/Protect query parameters: | Field | Type | Required | Description | | ---- | --- | ----------- | ------------ | | **refresh** | Boolean | false | Refresh an existing account | | **callbackUrl** | String | true | The URL on your page that the user will be redirected to after registering with BANKSapi. **Warning: Must be [URL-encoded](https://de.wikipedia.org/wiki/URL-Encoding) *** | The **callbackUrl** is then the URL to which the user is forwarded after registration. It is called by the user's browser (in the popup window you open, as `GET`) with the entire query string you supply, so you can also specify your own parameters, which are then handled transparently by BANKSapi. Logically, there should be a frontend page under the URL, since it is then displayed to the user. ::: tip It makes sense, for example, to append your own reference IDs to the callbackUrl as query parameters in order to recognize the user after a redirect and to continue the process correctly. ::: In addition to the query string you specified in the `callbackUrl`, the following query parameters are also sent (appended to the URL, `?parameter1=value1¶meter2=value2`): | Field | Type | Included | Description | | ---- | --- | ----------- | ------------ | | **baReentry** | String | Always | If successful `ACCOUNT_CREATED`, see [Context info when returning to your app](#context-info-when-returning-to-your-app) for all possible values | | ### Changing credentials for an existing bank access If the user has changed their online banking credentials (e.g. a new PIN or password) at their bank, the stored credentials in BANKSapi need to be updated as well. To update the credentials, use the same call as when adding a bank access, but with the UUID of the existing bank access and `refresh=false`: ```bash $ curl https://banksapi.io/customer/v2/bankzugaenge?refresh=false \ -X POST \ -H 'authorization: Bearer 9df54960-f678-47ec-84dc-6c771f9c980c' \ -H 'content-type: application/json' \ -d '{"637a3945-bb02-4e82-ac9e-f7c26d2568ce": {}}' < HTTP/1.1 451 < Content-Length: 0 < Location: https://banksapi.io/customer/v2/webform?session=b19c3937-...-3b861be7e71e&useCase=CREATE_ACCOUNT ``` As with the initial bank access creation, you will receive a `451` response with a `Location` header pointing to the REG/Protect web form. Append your `callbackUrl` and redirect the user to the web form. The user will then be able to enter their new credentials and complete the process. After completion, the user is redirected back to your `callbackUrl` with the `baReentry` query parameter indicating the result. > **Note:** Changing credentials is not supported for EBICS bank accesses. If different EBICS credentials (e.g. a new UserId or PartnerId) are needed, a new bank access must be created. ### Triggering a payment ```bash curl https://banksapi.io/customer/v2/ueberweisung/e1f30693-bab3-4c8b-9b3c-bc2/DE00123456789012345679 \ -X POST \ -H 'authorization: Bearer 9df54960-f678-47ec-84dc-6c771f9c980c' \ -H 'content-type: application/json' \ -d '{}' < HTTP/1.1 451 < Content-Length: 0 < Location: https://banksapi.io/customer/v2/webform?session=b19c3937- ... -3b861be7e71e &useCase=START_PAYMENT_SINGLE_TRANSFER ``` A payment is triggered in the same way as a bank access is added, first by calling a payment endpoint (e.g. [Initiate Single Transfer](/api/banks-connect.html#InitiateSingleTransfer)) using HTTP POST. Since all payment data can be determined in REG/Protect, it is sufficient here to send an empty JSON object as a payload only. You can also prefill payment data and define whether the prefilled data will be editable in REG/Protect, this behaviour is enforced by all bulk payments. As in the use case before, a *451 (Unavailable For Legal Reasons)* is delivered in the `Location`-HTTP header. To this URL you have to append a query parameter `callbackUrl` ([URL-encoded](https://de.wikipedia.org/wiki/URL-Encoding)), which is called again by BANKSapi after the successful or failed triggering of the payment. Overview of all query parameters for REG/Protect when triggering a payment: | Field | Type | Included | Description | | ---- | --- | ----------- | ------------ | | **useCase** | String | Always | REG/Protect use case, which is already provided by the Location field in HTTP 451 response, e.g. `START_PAYMENT_SINGLE_TRANSFER` | | | **callbackUrl** | String | Always | The URL on your page that the user will be redirected to after the BANKSapi referral process. **Warning: Must be [URL-encoded](https://de.wikipedia.org/wiki/URL-Encoding) *** | The **callbackUrl** is then the URL to which the user is redirected after the payment. It is called by the user's browser (in the window you open, as `GET`) with the entire query string you provide, so you can also specify your own parameters, which are then handled transparently by BANKSapi. Logically, there should be a frontend page under the URL, since it is then displayed to the user. In addition to the query string you specified in the callbackUrl, the following query parameters are also sent (appended to the URL, `?parameter1=value1¶meter2=value2`): | Field | Type | Included | Description | | ---- | --- | ----------- | ------------ | | **baReentry** | String | Always | If successful `PAYMENT_SUCCESS`, see [Context info when returning to your app](#context-info-when-returning-to-your-app) for all possible values | | ## Operations with SCA Due to the PSD2 requirements in respect to SCA, there is a multi-step process involved in order to add a bank access. The process differs depending on whether you are using REG/Protect or not: |REG/Protect|Task|Process description| |-----------|-------|-------| |**Yes**|Create a bank access|When creating a bank access, the multi-step process will be covered by us through the REG/Protect frontend. Find the documentation in [Adding bank access with REG/Protect](#adding-and-authenticating-a-bank-access)| |**Yes**|Refresh a bank access|During usage, the consent of the customer might expire at some point and new data can't be fetched from the bank. You can refresh with new data from the bank with a `refresh`-flag as documented. Whenever there is a relation `start_sca`, `POST` to the `start_sca` relation to indicate the user is ready to start an SCA process. You will receive a `451` status with a `Location`-header. Display the contents of the `Location`-Header to the user in the same way you would with the `Location`-Header when adding a bank access. This is to refresh the SCA with the bank in order to get up-to-date data from the bank.| |**No**|Create or update a bank access|When using the embedded approach (without REG/Protect), there are several steps you need to follow.

When creating or updating the bank access and in case of an SCA, there will be one of the following relations:
There can be multiple SCAs for a single bank access, so your application needs to be able to handle any of the above mentioned relations at any point of the creation/update. If any of the SCAs fail, there will be `start_sca` relation when the bank access reaches the status `VOLLSTAENDIG`| |**No**|Background update of a bank access|The consent of the customer might expire at some point and new data can't be fetched from the bank. In this case, the [BankAccess](/api/banks-connect.html#GetBankAccess) object will contain a relation `start_sca`. `POST` an empty object to this relation in order to indicate that the user is ready to start an SCA process and renew the consent.
| ## Encryption To encrypt the Credentials, the asymmetric crypto procedure RSA is used. If you become our customer, you will receive a public key from us with which the encryption is performed. Since the concrete implementation of encryption in the different programming environments is different from each other the characterizing properties of the process (specified in the following table) are used. [PKCS #1](https://tools.ietf.org/html/rfc8017)), with which the conversion in your preferred development environment should not be a problem: * Encryption algorithm: **RSA** * Operating mode: none (pure block encryption) * Padding: **OAEP** (Optimal Asymmetric Encryption Padding) with **SHA-1** (hash function) and **MGF1** (_mask generation function_) ::: info The description of the method used is described in the Java-specific [JCA Standard Algorithm Name Documentation](https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html) as follows: `RSA/NONE/OAEPWithSHA1AndMGF1padding` ::: ## Transactions older than 90 days It is possible to fetch transactions older than 90 days from the banks. This makes sense to do especially in the case of the initial addition of the bank access, as there is no history yet in the BANKSapi storage. We are able to fetch transactions back as far as the bank will serve (in some cases years). Please be aware that this functionality is best effort and while more than 90 days is possible for the majority of accounts, there are banks that still only return 90 days. The obvious drawback is that there is the need of theoretically up to three additional [SCA processes](#operations-with-sca) the customer has to undergo. Usually though none or only one additional SCA process will be required. This of course depends on the bank, and there is no way yet to foresee the number of SCAs. We recommend to use this functionality in cases where it is vital to fetch a history for the user. To indicate you would like BANKSapi to try and fetch more than 90 days, you can use the optional parameter `maxTransactions` as a query parameter when [adding or refreshing a bank access](/api/banks-connect.html#AddBankAccess). If indicating `paymentAccounts`, more than 90 days will only be fetched for payment accounts (Girokonto), if indicating `all` this will be tried for all kinds of bank products. Whenever sending this parameter, be prepared for SCA requests to come up for the bank access, so this should be used whenever the user is active on your application. ::: tip **Best Practice:** Use the `maxTransactions` parameter when first creating a bank access to fetch the complete transaction history, if necessary. Avoid using it during refresh operations, as this would cause unnecessary SCAs since the transaction history will already be available from the initial creation and as well as the ongoing background synchronization. ::: ::: warning **Using `maxTransactions` on an existing bank access:** It is possible to send `maxTransactions` for an existing bank access to retroactively fetch older transactions. However, this will nearly **always** require an SCA, meaning the end user must be actively present to complete the process. It cannot be done in the background automatically. When sending `maxTransactions` for an existing bank access, the bank access will immediately return a `BA3000` status along with a `start_sca` relation. You must then perform a `POST` on the `start_sca` relation and redirect the end user to the BANKSapi frontend via the `451` response to complete the SCA. ::: ::: info Please note that for fetching transactions more than 90 days from the BANKSapi storage, you will additionally have to indicate the `from` parameter when [fetching transactions](/api/banks-connect.html#GetTransactions), otherwise although we have a history more than 90 days for the user, you will not get it from BANKSapi storage as the default from is 90 days in the past. ::: ## Transaction tags (categorization) The current list of categories for the categorization can change at any time, even without changing the version number of the API. --- # BANKS/Connect Providers API Not all banks are the same. Via the **BANKS/Connect Providers API** you get access to a comprehensive, machine-readable configuration database of banks and service providers supported by **BANKS/Connect**. In addition to primary data such as name, banking group, bank code (BLZ), and BIC, you receive detailed information on login methods to help you optimize the user experience when setting up bank access. ::: info The entry point to **BANKS/Connect Providers API** is [**https://banksapi.io/providers/v2**](https://banksapi.io/providers/v2). ::: ## Example Response ```json [ { "id": "00000000-0000-0000-0000-000000000000", "name": "Demo Provider", "consumerRelevant": true, "group": "demo", "blz": "12345678", "bic": "DEMO1234", "relations": [ { "rel": "self", "href": "https://banksapi.io/providers/v2/00000000-0000-0000-0000-000000000000" }, { "rel": "logo", "href": "https://banksapi.io/providers/v2/demo.svg" } ], "capabilities": [ "KONTEN", "KARTEN", "DEPOTS" ], "channels": [ [ "GIROKONTO" ], [ "KREDITKARTE", "TAGESGELDKONTO" ] ], "authenticationInfo": { "loginHint": "Der Demo Provider bietet den Zugang demo/demo", "fields": [ { "fieldkey": "userid", "label": "Demo-User", "secret": false, "hint": "demo", "format": "^.{1,50}$" }, { "fieldkey": "pin", "label": "Demo-Passwort", "secret": true, "hint": "demo", "format": "^.{1,50}$" } ] } } ] ``` ## API Reference - [BANKS/Connect OpenAPI Reference](/api/banks-connect.html) - [Download OpenAPI Specification](/openapi/banksapi-v2-openapi-3_0.yaml) --- # AI/Connect API Every user is different. The **AI/Connect API** translates account information into specific insights about each customer's finances, allowing financial service providers to offer tailored financial solutions. Unlike our other APIs, AI/Connect provides derived data. Our AI models first categorize individual transactions by spending type, spending frequency, and counterparty. These categorized transactions are then aggregated per user and used as input to machine learning models that profile users on dimensions such as monthly budget structure, spending habits over time and across categories, and life stage. ::: info The entry point for the **AI/Connect API** is [**https://banksapi.io/ai/v2**](https://banksapi.io/ai/v2). ::: ## API Reference - [AI/Connect OpenAPI Reference](/api/ai-connect.html) - [Download OpenAPI Specification](/openapi/banksapi_ai_connect.json) --- # Transaction Categories [//]: # (#################################################) [//]: # (# WARNING: This file is machine generated. Any changes will be lost) [//]: # (#################################################) # Transaction Categories BANKSapi automatically categorizes transactions using AI. Each transaction is assigned a category and optionally a subcategory for more detailed classification. ::: info This page lists all available transaction categories. Use the category codes when filtering or analyzing transactions via the API. ::: | Category | Subcategory | Description | |----------|-------------|-------------| | `BANKFINANCE` | | Bank und Finanzen | | `BANKFINANCE` | `BANKFINANCE_CASHWITHDRAWAL` | Barauszahlung | | `BANKFINANCE` | `BANKFINANCE_CREDITPAYMENT` | Kredittilgung | | `BANKFINANCE` | `BANKFINANCE_CURRENCY` | Devisen- / Sortengeschäfte | | `BANKFINANCE` | `BANKFINANCE_FEES` | Bankgebühren | | `BANKFINANCE` | `BANKFINANCE_INVESTMENT` | Investment | | `BANKFINANCE` | `BANKFINANCE_OTHER` | Bank und Finanzen - Sonstiges | | `BILLS` | | Vertragsrechnungen | | `BILLS` | `BILLS_ENERGY` | Energiekosten | | `BILLS` | `BILLS_OTHER` | Vertragsrechnungen - Sonstiges | | `BILLS` | `BILLS_PUBLICRADIO` | Öffentlich-rechtlicher Rundfunk | | `BILLS` | `BILLS_TELECOMMUNICATIONS` | Internet und Telekommunikation | | `BILLS` | `BILLS_WATERANDDISPOSAL` | Wasser und Entsorgung | | `BUSINESS` | | Geschäftlich | | `BUSINESS` | `BUSINESS_ADVERTISEMENT` | Werbekosten | | `BUSINESS` | `BUSINESS_ASSOCIATION` | Berufsverbandsbeiträge | | `BUSINESS` | `BUSINESS_CONSULTING` | Beratungskosten (geschäftlich) | | `BUSINESS` | `BUSINESS_CREDITPAYMENT` | Kredittilgung (geschäftlich) | | `BUSINESS` | `BUSINESS_ENERGY` | Energiekosten (geschäftlich) | | `BUSINESS` | `BUSINESS_EQUIPMENT` | Arbeitsmittel | | `BUSINESS` | `BUSINESS_HOSPITALITY` | Bewirtungskosten (geschäftlich) | | `BUSINESS` | `BUSINESS_INVESTMENT` | Investment (geschäftlich) | | `BUSINESS` | `BUSINESS_LEASING` | Leasinggebühren (geschäftlich) | | `BUSINESS` | `BUSINESS_LEGAL` | Anwaltskosten (geschäftlich) | | `BUSINESS` | `BUSINESS_MOBILITY` | Mobilität (geschäftlich) | | `BUSINESS` | `BUSINESS_OTHER` | Geschäftlich - Sonstiges | | `BUSINESS` | `BUSINESS_RENT` | Miete (geschäftlich) | | `BUSINESS` | `BUSINESS_SALARY` | Personalkosten | | `BUSINESS` | `BUSINESS_TAXES` | Betriebssteuern | | `BUSINESS` | `BUSINESS_TELECOMMUNICATIONS` | Internet und Telekommunikation (geschäftlich) | | `BUSINESS` | `BUSINESS_TRAINING` | Fortbildungs- und Schulungskosten (geschäftlich) | | `BUSINESS` | `BUSINESS_TRAVEL` | Geschäftsreisekosten | | `BUSINESS` | `BUSINESS_WATERANDDISPOSAL` | Wasser- und Entsorgungsgebühren (geschäftlich) | | `EDUCATION` | | Bildungswesen | | `EDUCATION` | `EDUCATION_ACADEMIC` | Universität | | `EDUCATION` | `EDUCATION_OTHER` | Bildungswesen - Sonstiges | | `EDUCATION` | `EDUCATION_SCHOOL` | Schulbildung | | `EDUCATION` | `EDUCATION_TRAINING` | Fortbildung | | `FAMILY` | | Kinder und Familie | | `FAMILY` | `FAMILY_CHILDACTIVITIES` | Kinderaktivitäten | | `FAMILY` | `FAMILY_CHILDCARE` | Kinderbetreuung | | `FAMILY` | `FAMILY_CHILDNECESSITIES` | Kinder- und Babybedarf | | `FAMILY` | `FAMILY_OTHER` | Familie - Sonstiges | | `FAMILY` | `FAMILY_SUPPORT` | Unterhalt | | `FAMILY` | `FAMILY_TOYS` | Spielwaren | | `HEALTH` | | Gesundheit | | `HEALTH` | `HEALTH_CONSUMABLES` | Arznei und Heilmittel | | `HEALTH` | `HEALTH_OPTICS` | Augenoptik | | `HEALTH` | `HEALTH_OTHER` | Gesundheit - Sonstiges | | `HEALTH` | `HEALTH_SERVICES` | Arzt/Krankenhaus/Pflege | | `HOUSING` | | Wohnen | | `HOUSING` | `HOUSING_ANCILLARYCOSTS` | Nebenkosten | | `HOUSING` | `HOUSING_FINANCING` | Immobilienkredit | | `HOUSING` | `HOUSING_FURNISHING` | Möbel und Haushaltsgeräte | | `HOUSING` | `HOUSING_OTHER` | Wohnen - Sonstiges | | `HOUSING` | `HOUSING_RENOVATION` | Renovierung & Reparatur | | `HOUSING` | `HOUSING_RENT` | Miete/Wohngeld | | `HOUSING` | `HOUSING_SERVICES` | Haushaltsdienstleistungen | | `INCOME` | | Einnahmen | | `INCOME` | `INCOME_BUSINESS` | Geschäftseinnahmen | | `INCOME` | `INCOME_CASHDEPOSIT` | Bareinzahlung | | `INCOME` | `INCOME_CREDIT` | Krediteinnahme | | `INCOME` | `INCOME_INSURANCE` | Versicherungseinnahmen/-gutschriften/-rückzahlungen | | `INCOME` | `INCOME_INVESTMENT` | Kapitaleinkommen | | `INCOME` | `INCOME_OTHER` | Einnahmen - Sonstiges | | `INCOME` | `INCOME_PENSION` | Rente und Pension | | `INCOME` | `INCOME_REFUND` | Gutschriften und Erstattungen | | `INCOME` | `INCOME_RENTAL` | Vermietung und Verpachtung | | `INCOME` | `INCOME_RETURNDEBIT` | Rücklastschriften | | `INCOME` | `INCOME_SALARY` | Gehalt | | `INCOME` | `INCOME_SALES` | Verkaufseinnahmen | | `INCOME` | `INCOME_SAVINGS` | Spareinnahmen | | `INCOME` | `INCOME_SOCIALBENEFIT` | Sozialleistung | | `INCOME` | `INCOME_STATEEDUCATION` | Staatliche Förderung für Bildung | | `INCOME` | `INCOME_STATEFAMILY` | Staatliche Förderung für Familie und Kinder | | `INCOME` | `INCOME_TAXES` | Steuerrückzahlungen und -erstattungen | | `INSURANCE` | | Versicherungen | | `INSURANCE` | `INSURANCE_ACCIDENT` | Unfallversicherung | | `INSURANCE` | `INSURANCE_BUSINESS` | Gewerbliche Versicherung | | `INSURANCE` | `INSURANCE_HEALTH` | Krankenversicherung | | `INSURANCE` | `INSURANCE_LEGAL` | Rechtsschutzversicherung | | `INSURANCE` | `INSURANCE_LIABILITY` | Haftpflichtversicherung | | `INSURANCE` | `INSURANCE_LIFE` | Lebensversicherung | | `INSURANCE` | `INSURANCE_OTHER` | Versicherungen - Sonstiges | | `INSURANCE` | `INSURANCE_PROPERTY` | Sachversicherung | | `INSURANCE` | `INSURANCE_TRANSPORT` | Transportversicherung | | `INSURANCE` | `INSURANCE_TRAVEL` | Reiseversicherung | | `INSURANCE` | `INSURANCE_VEHICLE` | KFZ-Versicherung | | `LIVING` | | Lebenshaltung | | `LIVING` | `LIVING_CHARITY` | Spenden & Wohltätigkeit | | `LIVING` | `LIVING_DRUGSTORE` | Drogerie | | `LIVING` | `LIVING_GROCERIES` | Lebensmittel | | `LIVING` | `LIVING_OTHER` | Lebenshaltung - Sonstiges | | `MOBILITY` | | Mobilität | | `MOBILITY` | `MOBILITY_BIKESHARE` | Bike-Sharing | | `MOBILITY` | `MOBILITY_CARSHARE` | Car-Sharing | | `MOBILITY` | `MOBILITY_FUEL` | Tanken | | `MOBILITY` | `MOBILITY_OTHER` | Mobilität - Sonstiges | | `MOBILITY` | `MOBILITY_PARKING` | Parken | | `MOBILITY` | `MOBILITY_PUBLICTRANSPORT` | ÖPNV | | `MOBILITY` | `MOBILITY_SERVICES` | Wartung, Pflege und Reparaturen | | `MOBILITY` | `MOBILITY_TAXES` | KFZ-Steuer | | `MOBILITY` | `MOBILITY_TAXI` | Taxi | | `MOBILITY` | `MOBILITY_VEHICLEACQUISITION` | KFZ - Kredit/Kauf/Leasing | | `OTHER` | | Sonstiges | | `OTHER` | `OTHER_OTHER` | Sonstiges | | `RECREATION` | | Freizeit und Unterhaltung | | `RECREATION` | `RECREATION_CULTURAL` | Kultur | | `RECREATION` | `RECREATION_FOODANDDRINKS` | Ausgehen und Essen | | `RECREATION` | `RECREATION_GAMBLING` | Glücksspiel | | `RECREATION` | `RECREATION_HOBBYANDSOCIAL` | Hobbys und soziale Aktivitäten | | `RECREATION` | `RECREATION_ONLINE` | Spiele und Online-Unterhaltung | | `RECREATION` | `RECREATION_OTHER` | Freizeit und Unterhaltung - Sonstiges | | `RECREATION` | `RECREATION_PETS` | Haustier | | `RECREATION` | `RECREATION_PRINTED` | Bücher und Zeitschriften | | `RECREATION` | `RECREATION_SPORTS` | Sport und Fitness | | `RECREATION` | `RECREATION_STREAMING` | Streaming und Pay-TV | | `SAVINGS` | | Sparen | | `SAVINGS` | `SAVINGS_ACCOUNT` | Sparguthaben | | `SAVINGS` | `SAVINGS_BUILDING` | Bausparguthaben | | `SAVINGS` | `SAVINGS_OTHER` | Sparen - Sonstiges | | `SERVICES` | | Dienstleistungen | | `SERVICES` | `SERVICES_MAIL` | Porto- und Versandkosten | | `SERVICES` | `SERVICES_ONLINE` | Software und Online-Dienstleistungen | | `SERVICES` | `SERVICES_OTHER` | Dienstleistungen - Sonstiges | | `SERVICES` | `SERVICES_PERSONAL` | Persönliche Dienstleistungen | | `SERVICES` | `SERVICES_PROFESSIONAL` | Professionelle Dienstleistungen | | `SHOPPING` | | Shopping | | `SHOPPING` | `SHOPPING_BEAUTY` | Schönheitsprodukte | | `SHOPPING` | `SHOPPING_CLOTHINGACCESSORIES` | Kleidung und Accessoires | | `SHOPPING` | `SHOPPING_DEPARTMENTSTORE` | Kaufhaus | | `SHOPPING` | `SHOPPING_ELECTRONICS` | Elektrogeräte | | `SHOPPING` | `SHOPPING_ONLINE` | Online-Shopping | | `SHOPPING` | `SHOPPING_OTHER` | Shopping - Sonstiges | | `TAXES` | | Steuern | | `TAXES` | `TAXES_CAPITALGAINS` | Kapitalertragsteuer | | `TAXES` | `TAXES_CHURCH` | Kirchensteuer | | `TAXES` | `TAXES_FLAT` | Abgeltungsteuer | | `TAXES` | `TAXES_INCOME` | Einkommensteuer | | `TAXES` | `TAXES_OTHER` | Steuern - Sonstiges | | `TAXES` | `TAXES_PROPERTY` | Grundsteuer | | `TAXES` | `TAXES_SALES` | Umsatzsteuer | | `TRANSFER` | | Transfer | | `TRANSFER` | `TRANSFER_BANKFINANCE` | Kontotransfer | | `TRANSFER` | `TRANSFER_CREDITCARDSETTLEMENT` | Kreditkartenabrechnung | | `TRANSFER` | `TRANSFER_OTHER` | Transfer - Sonstiges | | `TRANSFER` | `TRANSFER_SAVINGS` | Transfer - Sparen | | `TRAVEL` | | Reisen | | `TRAVEL` | `TRAVEL_ACCOMMODATION` | Unterkunft | | `TRAVEL` | `TRAVEL_INCLUSIVEOFFERS` | Pauschalreisen | | `TRAVEL` | `TRAVEL_OTHER` | Reise - Sonstiges | | `TRAVEL` | `TRAVEL_TRANSPORT` | Transport | --- # PAY/Connect API **PAY/Connect** is an Open Banking eCommerce payment solution that enables direct account-to-account (A2A) payments through SEPA transfers. The API provides a seamless checkout experience for online merchants with coverage of >99% of payment accounts. The solution offers PSD2-compliant payment processing with flexible frontend integration, making it a cost-effective alternative to traditional payment methods for eCommerce platforms. ## Integration Overview PAY/Connect uses an **embedded JavaScript library** that renders the payment UI directly within your checkout page. The integration flow consists of four steps: 1. **Create Transaction**: Your backend [authenticates](/api/pay-connect.html#createToken) and [creates a transaction](/api/pay-connect.html#createTransaction) to obtain a session ID 2. **Pass Session ID**: Your backend passes the session ID to your frontend 3. **Initialize**: Your frontend embeds and initializes the PAY/Connect JS library 4. **Callback**: After payment completion, handle the success or error callback and [verify the transaction status](/api/pay-connect.html#getTransaction) ```mermaid flowchart LR A[Your Backend] -->|1. Create transaction| B[PAY/Connect API] B -->|sessionId| A A -->|2. Pass sessionId| C[Your Frontend] C -->|3. Initialize| D[PAY/Connect JS] D -->|4. callback| C ``` ## Backend Integration The following steps correspond to the integration flow shown in the diagram above. ### Step 1.1: [Obtain Access Token](/api/pay-connect.html#createToken) First, authenticate with your tenant credentials to obtain an access token: ```bash curl -X POST https://banksapi.io/payconnect/backend/token \ -H "Authorization: Basic $(echo -n 'username:password' | base64)" \ -H "Content-Type: application/json" ``` **Response:** ``` "your-access-token-uuid" ``` ### Step 1.2: [Create Transaction](/api/pay-connect.html#createTransaction) Use the access token to create a transaction and obtain a session ID: ```bash curl -X POST https://banksapi.io/payconnect/backend/transaction \ -H "Authorization: Bearer your-access-token-uuid" \ -H "Content-Type: application/json" \ -d '{ "transactionType": "PAYMENT", "recipient": "Merchant Name", "recipientIban": "DE89370400440532013000", "amount": "49.99", "currency": "EUR", "purpose": "Order 12345", "callbackUrl": "https://yourshop.com/checkout/callback", "instant": true }' ``` **Response:** ```json { "sessionId": "base64-encoded-session-id", "transactionId": "transaction-uuid" } ``` ### Transaction Parameters | Parameter | Required | Description | |-----------|----------|-------------| | `transactionType` | Yes | `PAYMENT` for payment, `VERIFICATION` for account verification only | | `recipient` | Yes | Name of the payment recipient | | `recipientIban` | No | IBAN of the recipient account (required for `PAYMENT` transactions) | | `recipientBic` | No | BIC of the recipient bank (optional) | | `amount` | Yes | Payment amount (e.g., `"49.99"`) | | `currency` | Yes | Currency code (e.g., `"EUR"`) | | `purpose` | Yes | Payment reference/purpose | | `callbackUrl` | Yes | URL for redirect after completion | | `instant` | No | Set to `true` to request SEPA Instant payment. Defaults to `false`. | | `senderIban` | No | Pre-fill sender IBAN (optional) | | `endUserAccessToken` | No | Reuse existing user token for returning customers | ## Frontend Integration ### Step 3.1: Add Container Element Add a container element where the PAY/Connect UI will be rendered: ```html
``` ### Step 3.2: Include the JavaScript Library Include the PAY/Connect JavaScript library in your page: ```html ``` ### Step 3.3: Initialize PAY/Connect Initialize PAY/Connect with the session ID obtained from your backend: ```javascript window.payConnect.start( { sessionId: "base64-encoded-session-id-from-backend" }, function(success) { // Payment completed successfully console.log("Payment successful:", success); // Redirect to success page or update UI window.location.href = "/checkout/success"; }, function(error) { // Payment failed or was cancelled console.error("Payment error:", error); // Handle error - show message or redirect window.location.href = "/checkout/error"; } ); ``` ### Configuration Options | Option | Required | Description | |--------|----------|-------------| | `sessionId` | Yes | Base64-encoded session ID from `POST /backend/transaction` | | `providerId` | No | UUID to pre-select a specific bank provider | | `senderIban` | No | Pre-fill the sender IBAN field | ## The Payment Flow Once initialized, PAY/Connect renders as an overlay on top of your checkout page and guides the user through the payment. The screenshots below show the flow with the [Demo Provider](/guide/demo-provider) (credentials `demo` / `demo`). | Step | Screenshot | | ------ | -------------- | | Searching for the bank by name, city, bank code or BIC *(skipped if you pass `providerId`)* | ![Search for a bank](/images/payconnect2-search-bank.png) | | Logging in with the online banking credentials | ![Bank login](/images/payconnect3-login.png) | | Choosing the account to pay from | ![Select account](/images/payconnect4-select-account.png) | | Confirming the transfer, including the Verification of Payee result for recipient name and IBAN | ![Confirm transfer](/images/payconnect5-confirm-transfer.png) | | Payment completed — the success callback fires and the overlay closes | ![Payment successful](/images/payconnect6-success.png) | Depending on the bank, additional steps can appear between login and confirmation — for example selecting an SCA method or entering a TAN. ## Step 4: Handle Callback After the user completes (or cancels) the payment flow, PAY/Connect calls your success or error callback. Use this to redirect the user or update your UI, and verify the transaction status on your backend. ## Complete Integration Example ```html Checkout - Your Shop

Complete Your Payment

``` ## [Checking Transaction Status](/api/pay-connect.html#getTransaction) After the payment flow completes (via callback), you can verify the transaction status: ```bash curl -X GET https://banksapi.io/payconnect/backend/transaction/{transactionId} \ -H "Authorization: Bearer your-access-token-uuid" ``` ## Important Notes - **No Redirect URL**: PAY/Connect is an embedded library, not a redirect-based solution. Do not try to redirect users to a PAY/Connect URL - instead, embed the library on your page. - **Session Expiry**: Sessions expire after 10 minutes of inactivity. - **HTTPS Required**: The frontend must be served over HTTPS in production. - **Container Element**: The `#pay-connect-app` container must exist before calling `window.payConnect.start()`. ## API Reference - [PAY/Connect OpenAPI Reference](/api/pay-connect.html) - [Download OpenAPI Specification](/openapi/pay-connect-openapi-3_0.yaml) --- # WEB/Connect For developers who want to integrate banking functionality quickly into their web applications, BANKSapi offers pre-built web components through our **WEB/Connect** product. These secure, framework-independent widgets provide ready-to-use banking features: **REG/Protect Web Component**
Connect to the bank and handle Strong Customer Authentication (SCA) and secure payment processes.
NPM Package: [`@banksapitechnology/regprotect-web-component`](https://www.npmjs.com/package/@banksapitechnology/regprotect-web-component) **Embeddable Finance Components (EFC)**
Complete multi-banking interface with bank access management, transaction lists, budget-analysis and account details.
NPM Package: [`@banksapitechnology/embeddable-finance-web-components`](https://www.npmjs.com/package/@banksapitechnology/embeddable-finance-web-components) **Key Benefits**: Secure encapsulation, fast implementation, framework independence, cost-effectiveness and low maintenance overhead. **Demo & Reference**: Check out our [open-source demo application](https://github.com/BANKSapi/banking-widgets-demo) for implementation examples. You can also see the web components in action in [ATLAS ↗](https://banksapi.io/atlas/){target="_blank"}, our product discovery web app. For more information about our banking widgets, visit [banksapi.de/banking-widgets](https://banksapi.de/banking-widgets/). Additional implementation details can be found in the READMEs of the respective repositories. --- # EBICS This guide is intended to help you integrate EBICS bank accesses via our API. EBICS (Electronic Banking Internet Communication Standard) is a widely adopted banking transmission protocol in several European countries, particularly in Germany, France, and Switzerland. It is primarily used by corporate clients and financial institutions to facilitate the secure transfer of payment and financial transaction data over the internet. ::: info EBICS is primarily used by large and medium enterprises. If you don't know what EBICS is, you probably want to start your BANKSapi journey with the non-EBICS accounts; the process is illustrated in our [Quick Start](/guide/quickstart). ::: Designed for high-volume transactions, EBICS offers a robust and secure method for businesses to communicate with their banks. It standardizes the electronic exchange of banking business data and ensures secure, direct communication between clients and banks. ::: tip At BANKSapi, you can use EBICS in the same way you would interact with non-EBICS bank accesses. The connection process differs a bit, but once the bank access has been set up correctly, you may use the exact same endpoints. ::: Remember, we're using the OAuth2 protocol for authentication, and you will be supplied with a "refresh token" to fetch a new access token. It's advised to [read about OAuth2 protocol](/guide/concepts#oauth2) in our documentation if unfamiliar, then proceed with the steps mentioned here. ## Create an EBICS Account The user should create an EBICS account with their bank and receive credentials: `Host-ID`, `Host-URL`, `Partner-ID`, and `User-ID`. The account should have the following permissions: **Download** - Standard download order types for subscriber data (e.g. `HTD`, optional but recommended `HAC`/`PTK` for protocols) - `C53`/`C52` (preferred) or `STA`/`VMK` for transaction retrieval - `C54`/`Z54` for camt.054 documents (only needed when requesting `transactionDocuments: ["XML"]`) - `BKA` for PDF account statements (only needed when requesting `transactionDocuments: ["PDF"]`) **Upload** `AuthorizationLevel="T"` for all needed upload order types: - `CCT` (SEPA Credit Transfer) - `CIP` (SEPA Instant Credit Transfer) - `CTV` (SEPA Credit Transfer with Verification of Payee) - `CIV` (SEPA Instant Credit Transfer with Verification of Payee) - `AXZ` (cross-border/international credit transfer) - `XE2` (Swiss domestic payments; on EBICS 3.0 granted as BTF service `MCT` with scope `CH`) - `CDB` (SEPA Direct Debit for companies) - `CDD` (SEPA Direct Debit for end users) These need to be set by account (by bank product) usually. ## Call the Add Bank Access Endpoint ```http POST /customer/v2/bankzugaenge HTTP/1.1 Host: banksapi.io Content-Type: application/json Authorization: Bearer 0bac1d52-4eb0-4fe2-951e-cf6ff9dc4235 { "629e4510-5331-47d4-9bad-8902039ff762": { "ebics": true } } ``` Call the endpoint at [Add Bank Access](/api/banks-connect.html#AddBankAccess) with `ebics: true`. ```http HTTP/1.1 451 Unavailable For Legal Reasons Location: https://banksapi.io/customer/v2/webform?session=ef2fdd3b-a087-447b-843c-670325d003f4&useCase=CREATE_ACCOUNT ``` This will result in a HTTP 451 Code, with a location header. Follow the instructions similar to [Create Bank Access](/guide/quickstart#create-bank-access). ## Redirect the User Add a `callbackUrl` to the Location-Header and redirect the user to enter their EBICS credentials. | Step | Screenshot | | ------ | -------------- | | Entering the EBICS credentials | ![EBICS](/images/regprotect_ebics.png) | | Receiving the ini letter | ![INI Letter Download](/images/regprotect_iniletter_download.png) | | The resulting ini letter that needs to be signed | ![INI Letter](/images/regprotect_iniletter.png) | ## Initialization Letter Generation BANKSapi has at this point generated an initialization letter containing the hash of the keys generated. The user should download this letter, and the keys will not leave BANKSapi's servers. ## Verify the Bank Access ```json { "id": "189d22f6-2d1a-4fa3-a22e-8db0d7e47453", "providerId": "00000000-0000-0000-0000-000000000000", "aktualisierungszeitpunkt": "2023-09-14 13:40:20", "messages": [{ "level": "INFO", "code": "BA2004", "message": "Bankzugang noch nicht freigeschaltet", "details": "Der EBICS Zugang ist noch nicht freigeschaltet." }], "tanMedien": [], "sicherheitsverfahren": [], "challenge": { "name": "EBICS Initialisierungsbrief", "content": { "instructions": "Bitte senden Sie den Initialisierungsbrief unterschrieben an die Bank.", "PDF": "data:application/pdf;base64,JVBERi0xLjQN ... 3MzUNCiUlRU9G" }, "decoupled": false, "redirect": false }, "relations": [{ "rel": "self", "href": "https://banksapi.io/customer/v2/bankzugaenge/189d22f6-2d1a-4fa3-a22e-8db0d7e47453" }, { "rel": "refresh_bankzugang", "href": "https://banksapi.io/customer/v2/bankzugaenge" }, { "rel": "delete_bankzugang", "href": "https://banksapi.io/customer/v2/bankzugaenge/189d22f6-2d1a-4fa3-a22e-8db0d7e47453" }, { "rel": "get_issues", "href": "https://banksapi.io/customer/v2/bankzugaenge/189d22f6-2d1a-4fa3-a22e-8db0d7e47453/issues" }, { "rel": "get_challenge_pdf", "href": "https://banksapi.io/customer/v2/bankzugaenge/189d22f6-2d1a-4fa3-a22e-8db0d7e47453/challenge/pdf" } ], "type": "EBICS", "status": "VOLLSTAENDIG", "bankprodukte": [], "sync": true } ``` After redirection to the `callbackUrl` and the user completing the process and returning to your website, the bank access should be in a `VOLLSTAENDIG` state with a `BA2004` message indicating that bank access is not yet activated. The ini letter can be retrieved by you as well: 1. By the base64 encoded string in `challenge.content.PDF` 1. By the relation `get_challenge_pdf` which makes the PDF available for download through `Content-Disposition: attachment;` ::: tip BANKSapi will now attempt to fetch data 4x a day until the bank confirms the hash. ::: ## User Sends Initialization Letter to the Bank The user needs to print, sign, and send the letter to the bank. Some banks might accept electronic versions. Once the bank confirms the hash and activates the account, BANKSapi will be able to fetch data. ::: info If the user has permissions beyond T-grants, BANKSapi will delete the set of keys, resulting in a `BA1020` message. The EBICS user needs to be re-created with the correct credentials, and the process needs to be reiterated. ::: ## Successful Connection If all steps are successful, and the bank has confirmed the hash, the status will be `VOLLSTAENDIG` with an `ebics: true` flag, and all endpoints for fetching the bank access, transactions, and payments will be available for this account. ## Comparison to Non-EBICS Bank Accesses To summarize, the difference to non-EBICS bank accesses is primarily a more heavy interaction by the user with their bank. Primarily, the EBICS account (`T-User`) needs to already have been created at the time the user attempts to add the EBICS bank access / is redirected to our REG/Protect frontend. Afterwards, the bank access is not immediately available, but needs to be confirmed by the bank after the REG/Protect process. ## Caveats ### Initializing multiple times Depending on the bank, an EBICS access cannot be initialized several times, but must be reset by the bank. ### Balance Retrieval Limitation In EBICS, there's no way to get the balance of an account without fetching its transactions. There might not be any transactions, i.e. also no balance, because of the historical transaction limitation ### Historical Transaction Limitation With EBICS, we might not be able to get transactions that are older than when the bank access was created. ### Transaction History Range Currently, we will fetch transactions up to 90 days back. --- # BANKSapi Documentation via MCP The BANKSapi Documentation [MCP](https://modelcontextprotocol.io/) server connects AI assistants and coding agents directly to the BANKSapi documentation. Claude, ChatGPT, Cursor, GitHub Copilot and other MCP clients can search our docs, fetch specific pages and access the OpenAPI specifications while they help you build your integration. ## Why Use This? When integrating BANKSapi into your application, AI assistants can help you write code faster. But they need access to accurate, up-to-date documentation to do so effectively. **Without the MCP server**, your AI assistant might: - Hallucinate API endpoints that don't exist - Use outdated authentication patterns - Miss important concepts like REG/Protect or SCA handling **With the MCP server**, your AI assistant can: - Search the BANKSapi documentation semantically - Fetch the exact Markdown content of any docs page - Access the OpenAPI specifications for code generation, one operation at a time - Understand BANKSapi-specific concepts (Users, Bank Accesses, HATEOAS) ## Example Prompts Once connected, try these prompts with your AI assistant: **Getting started:** > "I want to integrate BANKSapi into my Node.js app. Show me how to authenticate and create a user." **Understanding concepts:** > "Explain the difference between REG/Protect and regulated client flows in BANKSapi." **Code generation:** > "Generate TypeScript types from the BANKSapi OpenAPI spec for the Customer API endpoints." **Specific implementation:** > "How do I handle SCA/TAN renewal when a bank access consent expires?" ## Available Tools The MCP server exposes four tools. All of them only read documentation: none accesses bank accounts, customer data or the BANKSapi API. | Tool | Description | When to use | |------|-------------|-------------| | `search-banksapi-docs` | Semantic search across all documentation | Broad questions like "How do I authenticate?" | | `get-banksapi-docs-page` | Fetch a page's Markdown; for `/api/*` paths returns a compact operation index rendered from the spec | When you need specific page content, code samples, or the list of operations in an API | | `get-banksapi-openapi-spec` | Get an OpenAPI 3.0 spec, or a slice by `operation_id` / `tag` | For code generation; prefer `operation_id` for one endpoint since the full specs are large (`banks-connect`, `ai-connect`, `pay-connect`) | | `get-banksapi-overview` | Return the [llms.txt](/llms.txt) index of all documentation pages | At the start of a task, to see which pages exist | ## Installation The server is public and needs no account or API key. Every client below connects to the same address: ``` https://banksapi.io/docs-mcp ``` ### Claude (claude.ai and desktop app) **Free, Pro or Max plan:** 1. Go to **Customize > Connectors**. 2. Click **Add custom connector**. 3. Enter `https://banksapi.io/docs-mcp` as the server URL and click **Add**. On the Free plan you can add one custom connector. **Team or Enterprise plan:** an Owner adds the connector for the whole organization under **Organization settings > Connectors > Add > Custom**. Members then find it under **Customize > Connectors**. No OAuth credentials are needed. ### Claude Code Add the MCP server via CLI: ```bash claude mcp add --transport http banksapi-docs https://banksapi.io/docs-mcp --scope user ``` `--scope user` makes the server available in all your projects. Run `claude mcp get banksapi-docs` to check the connection.
Share the server with your team To make the server available to everyone working on a repository, add a `.mcp.json` file to the repository root: ```json { "mcpServers": { "banksapi-docs": { "type": "http", "url": "https://banksapi.io/docs-mcp" } } } ``` Claude Code asks each team member to approve the server the first time they start it in that repository. MCP servers aren't configured in `settings.json`.
### ChatGPT 1. Open [chatgpt.com/plugins](https://chatgpt.com/plugins). 2. Click **+** and choose **Add custom MCP server**. 3. Enter `BANKSapi Docs` as the name and `https://banksapi.io/docs-mcp` as the URL. 4. Choose no authentication. 5. Confirm the warning and choose **Create as a plugin**. Availability depends on your ChatGPT plan and workspace settings. In Business and Enterprise workspaces, an admin may need to add the server or allow it first. See OpenAI's article [Connecting custom MCP servers in ChatGPT](https://help.openai.com/en/articles/12584461-connecting-custom-mcp-servers-in-chatgpt). ### Codex Add the server via CLI: ```bash codex mcp add banksapi-docs --url https://banksapi.io/docs-mcp ``` Or add it to `~/.codex/config.toml` yourself: ```toml [mcp_servers.banksapi-docs] url = "https://banksapi.io/docs-mcp" ``` The Codex CLI, desktop app and IDE extension share this configuration. In the desktop app, you can also add the server under **Settings > MCP servers > Add server** with the **Streamable HTTP** transport. ### Cursor Add to Cursor The button opens Cursor, which adds the server after you confirm. Or add the server to `.cursor/mcp.json` in your project, or to `~/.cursor/mcp.json` to use it in all projects: ```json { "mcpServers": { "banksapi-docs": { "url": "https://banksapi.io/docs-mcp" } } } ``` ### VS Code with GitHub Copilot Install in VS Code The button opens VS Code, which adds the server to your user profile after you confirm. Or add it from the command line: ```bash code --add-mcp '{"name":"banksapi-docs","type":"http","url":"https://banksapi.io/docs-mcp"}' ``` Or add it in VS Code: 1. Open the Command Palette (⌘+Shift+P / Ctrl+Shift+P). 2. Run **MCP: Add Server**. 3. Choose **HTTP (HTTP or Server-Sent Events)** and enter `https://banksapi.io/docs-mcp`. 4. Enter `banksapi-docs` as the server name. ### Devin Desktop (formerly Windsurf) Devin Desktop connects to remote MCP servers directly. Its Devin Local agent shares the MCP configuration with the Devin CLI. Add the server to `~/.config/devin/mcp_config.json` on macOS and Linux, or to `%APPDATA%\devin\mcp_config.json` on Windows: ```json { "mcpServers": { "banksapi-docs": { "url": "https://banksapi.io/docs-mcp" } } } ``` With the Devin CLI installed, you can add it from the command line instead: ```bash devin mcp add -s user banksapi-docs https://banksapi.io/docs-mcp ``` ### Gemini CLI Add the server via CLI: ```bash gemini mcp add --scope user --transport http banksapi-docs https://banksapi.io/docs-mcp ``` Or add it to `~/.gemini/settings.json` yourself: ```json { "mcpServers": { "banksapi-docs": { "httpUrl": "https://banksapi.io/docs-mcp" } } } ``` ### Perplexity Custom connectors are available on the Pro, Max and Enterprise plans. 1. Open **Plugins** in the sidebar, or **Customize > Connectors** if Plugins isn't shown yet. 2. Choose **Add custom**, then **Connector**, then **Add MCP connector**. 3. Select **Remote**, enter `BANKSapi Docs` as the name and `https://banksapi.io/docs-mcp` as the URL. 4. Set the authentication to **None** and the transport to **Streamable HTTP**. 5. Confirm the risk acknowledgement and click **Add**. On Enterprise plans, members can add their own custom connectors only after an admin turns on **Allow members to add custom connectors**. Admins can also add the connector for the whole organization. ### Other MCP Clients The server uses the Streamable HTTP transport and needs no authentication. Connect to `https://banksapi.io/docs-mcp` with your client's HTTP transport. ## Technical Details - **Endpoint**: `https://banksapi.io/docs-mcp` - **Transport**: Streamable HTTP - **Authentication**: none - **Tools**: four, all read-only - **Privacy**: search queries sent to `search-banksapi-docs` are processed by Inkeep, our documentation search provider. All other tools are served by BANKSapi. The server doesn't ask for an account or personal data. See our [privacy policy](https://banksapi.de/datenschutz/) (German). --- # Demo Provider BANKSapi provides a **Demo Provider** (mock bank) that you can use for testing and development purposes. The Demo Provider simulates a real bank and can be selected via the provider search. The provider ID of the Demo Provider is `00000000-0000-0000-0000-000000000000`. ::: warning Important The credentials listed below are **not** BANKSapi technical users (as created via the [Create User](/api/banks-connect.html#CreateUser) call). They are login credentials for the mock bank itself, similar to the online banking credentials a real end user would enter when connecting their bank account. ::: ## Selecting the Demo Provider When [adding a bank access](/guide/quickstart#create-bank-access), search for "Demo" in the provider search to find and select the Demo Provider: ![Select Demo Provider](/images/regprotect3.png) ## Test Credentials The following test credentials can be used to log in to the Demo Provider: | Username | Password | Description | | --- | --- | --- | | `demo` | `demo` | Standard test access | | `test_sca_method` | `test_sca_method` | Test access for SCA method flows. Every refresh requires a new SCA, making it useful for testing the [consent renewal flow](/guide/quickstart#renew-consent-with-sca-tans). | | `test_failing_payment` | `test_failing_payment` | Test access that simulates a failing payment | ## Additional Information The Demo Provider supports a `+` notation on usernames for additional testing scenarios: - **Unique bank accesses**: Bank accesses with identical credentials are shared across users, which means all users benefit from synchronized account data. Since the Demo Provider uses the same fixed credentials for everyone, this can cause issues with concurrent synchronizations or unexpected refresh behavior. Append `+` followed by an arbitrary string to create a unique bank access when needed. For example, `demo+alice` and `demo+bob` both behave like `demo` but are treated as separate bank accesses. - **Simulating slow responses**: Append `+wait=` to simulate a slow bank connection. For example, `demo+wait=30` will add a 30-second delay to the bank access. Both modifiers can be combined: `demo+mytest+wait=30`. --- # Errors and Messages In the communication between client, BANKS/Connect and the providers, errors can occur which can be caused by a wide variety of constellations. We always make every effort to transport the cause of an error to you as informatively as possible so that you can react accordingly. A simple use case is, for example, that the login of a customer to his bank is not worked. As an error message, the system returns, for example, that the user ID is not was 10 digits long and so the login data was not correct. The customer is thus in a position to "problem" quickly. ## HTTP status codes | Status | Name | Meaning API | Handling | | ------ | -------------- | ------------- | ---------- | | 200 | OK | The request has been successfully executed | - | | 201 | Created | The request was executed successfully and the data object was created | Evaluate and call location header | | 400 | Bad Request | The request is syntactically wrong | Program error at the caller, manual intervention necessary | | 401 | Unauthorized | The *authorization: bearer TOKEN* header was not sent | Send header | | 403 | Forbidden | The OAuth2 token has expired, is invalid or the required scope is missing | Request new token, extend scopes | | 404 | Not found | The URL does not point to a valid object | Start new data retrieval and update relations | | 451 | Unavailable for Legal Reasons | The requested resource cannot be returned for regulatory reasons. | This is used in the course of the [REG/Protects](/guide/customer#reg-protect), the HTTP response contains a `Location` header with the URL for the redirect | | 500 | Internal Server Error | This shouldn't have happened | We're already working on it | | 504 | Gateway Timeout | The started request could not be answered within the specified time | Repeat request shortly | ## Message codes ```json { "level": "ERROR", "code": "BA1011", "message": "Access data not correct ", "details": "Please check your access data and try again. Please note that your access data will be blocked if you enter it incorrectly three times." } ``` | Code | Level | Message | Details | |--------| ----- | ------ | ------- | | BA998 | ERROR | Timeout | The bank is taking a long time to provide the requested data. The query continues in the background and should be completed in a few minutes. | | BA999 | ERROR | Internal error | | | BA1000 | ERROR | Maintenance work provider | | | BA1001 | ERROR | Provider no longer active | | | BA1010 | ERROR | Access blocked | Your PIN for Internet banking was entered incorrectly three times. So we've temporarily suspended your access for security reasons | | BA1011 | ERROR | Access data not correct | Please check your access data and try again. Please note that your access data will be blocked after three incorrect entries. | | BA1012 | ERROR | Incomplete access data | The following access data is required: Authfields 1 = Example user name 2 = Example PIN 3 = Example key | | BA1013 | ERROR | Bank access not activated | | | BA1014 | ERROR | Too many unsuccessful logins | | | BA1020 | ERROR | Account has improper permissions | | | BA1051 | ERROR | Bank access not available | Maintenance: A technical malfunction has occurred at your bank. Please update your bank access at a later date. | | BA1052 | ERROR | Bank access not fully accessible | | | BA1053 | ERROR | Access exceeded | | | BA1060 | ERROR | Product could not be updated | | | BA1062 | ERROR | Revenues could not be updated | | | BA1063 | ERROR | Depot positions could not be updated | | | BA1064 | ERROR | Message bank | | | BA1100 | ERROR | Invalid bank transfer data | Please check your entries. Transfers are only possible to the reference account. | | BA1101 | ERROR | Invalid TAN procedure | | | BA1102 | ERROR | Invalid TAN medium | | | BA1103 | ERROR | TAN invalid | Error during transmission, or mTan not (any longer) valid | | BA1104 | ERROR | Bank transfer not possible | Bank transfers are only supported for checking accounts or HBCI message 9390 Order rejected due to double submission. | | BA1110 | INFO | TAN input required | Please enter the SMS-TAN | | BA1111 | INFO | The transfer was successfully completed | | BA1112 | INFO | The transfer was successfully submitted | | BA1200 | ERROR | Invalid debit data | Please check your input data. | | BA1204 | ERROR | Debit not supported | | BA1212 | INFO | The debit was successfully submitted | | BA2002 | INFO | There are messages from your bank | There are messages from your bank, please log into your online banking. | | BA2003 | INFO | Product type not supported | | | BA2004 | INFO | Bank access not activated yet | | | BA2021 | INFO | Missing permission | | | BA2062 | INFO | Transactions not available | | | BA3000 | INFO | SCA required | SCA required | | BA3005 | INFO | SCA redirect required | | | BA3010 | INFO | Select SCA method | Select SCA method | | BA3020 | INFO | Select SCA medium | Select SCA medium | | BA3030 | INFO | SCA Challenge | SCA Challenge | | BA3040 | ERROR | SCA failed | SCA failed | | BA3060 | ERROR | No supported SCA method found | No supported SCA method found | ::: info It should be noted that the error codes can be extended at any time. The structure is retained as described in this document. ::: --- # Frequently Asked Questions ## How do I get API access? Get your [free trial here](https://banksapi.de/en/free-trial/). For more information: [Contact us!](https://banksapi.de/en/contact/) ## How do I get the banking products for my customer? The banking products are available via the [BANKS/Connect Customer API](/guide/customer). The end user must [add a Bank Access](/api/banks-connect.html#AddBankAccess) before. If the data retrieval is successful, the data is ready for retrieval via the API. ## What are credentials? Credentials are defined as the customer's access data for their online banking. The credentials usually consist of a user ID/login name and a password/PIN. The concrete specification is different per [provider](/guide/concepts#provider) and can be queried via the [**BANKS/Connect Providers API**](/guide/providers). ## What's a TAN? A TAN (transaction number) is a random code that can only be used once. In the [**BANKS/Connect Customer API**](/guide/customer) the TAN is needed for the transfer process. After the transfer data has been transmitted to the provider, the TAN or the instruction for TAN generation (e.g. chip card reader) is then sent directly from the provider to the customer. The TAN must then be queried by the customer and forwarded to [**BANKS/Connect Customer API**](/guide/customer) to confirm the order. ## Is there a test account or a demo account? Yes, there is a [Demo Provider](/guide/demo-provider), a fictitious bank with fictitious but not unrealistic banking products. This test access demonstrates the possibilities our API offers you. There is no connection to the real world. For further information please refer to the [Demo Provider](/guide/demo-provider) page or our [Quickstart Guide](/guide/quickstart). ## What is BANKS/Connect? BANKS/Connect is an interface through which a large number of providers can obtain their customers': - accounts including account details, account transactions, and transfers - custody accounts including total custody account holdings, valued individual custody account holdings, and custody account risk - credit cards including credit card details and credit card transactions ## How often are bank accesses synchronized in the background? BANKSapi automatically synchronizes bank accesses in the background 4 times per day (the regulatory limit for non-user-induced refreshes). The first synchronization takes place in the early morning between 05:30 and 07:50 CET, the remaining three are spread over the rest of the day until 21:00 CET. The exact timing of each synchronization is randomized to avoid peak concentrations. ## Which cross-border transfers are supported? We support SEPA credit transfers, including transfers to other SEPA countries, via the JSON transfer endpoints (single and bulk transfer). Transfers outside the SEPA area are only possible via EBICS and the XML endpoint (PAIN format) using the query parameter `crossBorder=true`, which internally selects the `AXZ` order type for foreign payments. ## Are Swiss domestic payments (CHF, QR-bill) supported? Yes, via EBICS and the XML endpoint (PAIN format). Files debited from a Swiss or Liechtenstein account are automatically submitted via the Swiss Payment Standards service (EBICS 3.0 BTF service `MCT` with scope `CH`; order type `XE2` on EBICS 2.5). No query parameter is needed. This also applies to payments outside the SEPA area, so do not set `crossBorder=true` for these accounts. ## Why does my transfer or direct debit fail due to invalid characters? When submitting transfers or direct debits, we recommend using only characters from the basic SEPA character set: | Category | Allowed characters | |---|---| | a - z | `a b c d e f g h i j k l m n o p q r s t u v w x y z` | | A - Z | `A B C D E F G H I J K L M N O P Q R S T U V W X Y Z` | | 0 - 9 | `0 1 2 3 4 5 6 7 8 9` | | Special characters | `/ ? : ( ) . , ' + -` | | Whitespace | Space | Characters outside this set, such as German umlauts (ä, ö, ü, ß), accented letters, or other special characters, may cause the payment to be rejected depending on the bank. To avoid issues, we recommend replacing such characters before submitting the request. ## Where and how is the data stored? Depending on the selected range of services, we store the data for you permanently or only for a few minutes, but in any case in the high-security data center of noris network or your own. --- # ONE/Connect **ONE/Connect** is BANKSapi's single-user multibanking product for individuals and small companies: you connect your own bank accounts in a hosted web application, covered by BANKSapi's PSD2 license, and access the data through the [BANKS/Connect API](/api/banks-connect.html). See the [product page](https://banksapi.de/en/one-connect-en/) for details and pricing, and to get ONE/Connect. ONE/Connect comes in two variants: **Basic** (account information) and **Classic** (additionally payments via SEPA transfers and direct debits). Creating a token works the same for both; only the endpoint differs. ## 1. Get your API key Log in to your ONE/Connect application ([Basic](https://banksapi.io/onebasic/), [Classic](https://banksapi.io/one/)). Your personal API key is displayed on the dashboard. Copy it from there and treat it like a password: it grants access to your connected bank data. ::: info Registration token vs. login A **registration token** is not a login credential and not an API key. If you received one, use it once on the registration page of your variant ([Basic](https://banksapi.io/onebasic/register), [Classic](https://banksapi.io/one/register)): there you enter the registration token and choose a username, e-mail address and password. Those credentials are what you log in with from then on — the registration token is used up by the registration and is not needed again. ::: ## 2. Create a token Exchange the API key for an [OAuth2](/guide/concepts#oauth2) bearer token using the token endpoint of your variant ([Basic](/api/banks-connect.html#CreateOneConnectBasicToken), [Classic](/api/banks-connect.html#CreateOneConnectClassicToken)): ::: code-group ```bash [ONE/Connect Basic] curl -X POST 'https://banksapi.io/onebasic/bc-token' \ -H 'X-API-KEY: ' ``` ```bash [ONE/Connect Classic] curl -X POST 'https://banksapi.io/one/bc-token' \ -H 'X-API-KEY: ' ``` ::: The response contains the `access_token`, which is usually valid for two hours. ## 3. Call the BANKS/Connect API Use the access token as a bearer token against the [Customer API](/guide/customer), for example to list your bank connections: ```bash curl 'https://banksapi.io/customer/v2/bankzugaenge' \ -H 'Authorization: Bearer ' ``` Continue with [Create Bank Access](/guide/quickstart.html#create-bank-access) in the Quick Start guide to add bank connections and query accounts and transactions via the API. --- # API Reference The full endpoint reference is served as interactive pages and as OpenAPI 3.0 specs (this text file contains the prose guides only): - BANKS/Connect: https://docs.banksapi.de/api/banks-connect — spec: /openapi/banksapi-v2-openapi-3_0.yaml - AI/Connect: https://docs.banksapi.de/api/ai-connect — spec: /openapi/banksapi_ai_connect.json - PAY/Connect: https://docs.banksapi.de/api/pay-connect — spec: /openapi/pay-connect-openapi-3_0.yaml Via the docs MCP server, fetch a compact operation index with get-banksapi-docs-page('/api/banks-connect') and a single operation with get-banksapi-openapi-spec(spec_name='banks-connect', operation_id='...').