How to get started with our APIs

Get Started

 

Introduction

Welcome to the ABN AMRO Developer Portal. ABN AMRO sees APIs as a way to make a huge contribution to creating secure, social and ground-breaking digital ecosystems. We believe that working more closely with third parties will offer opportunities to accelerate innovation and further improve our services to our clients. That is why we provide you our ‘Developer Portal’ and APIs.

Our APIs offer the following advantages:

  • Get started right away: Visit our Developer Portal to find out what our APIs do, how they work and what you need to do to interface with them. Use our sandboxes and get building now. Our APIs need just a few lines of code to run in your applications.
  • Clear overview: You always know what is happening. Use our API analytics to track your users’ activity in your applications and adjust your tactics if necessary.
  • Be creative: We are giving you the opportunity to use exclusive APIs to help shape the future of banking.

 

PSD2

The revised Payment Services Directive (PSD2) enables customers to make use of payment services of a bank through third parties. Do you want to make use of the Account Information and Payment Initiation APIs for PSD2 use cases? Please visit the Documentation pages of these APIs for instructions.

How to Use

 

Registration

To use our API products, an account on our Developer Portal is needed.

Creating an account is simple and fast:

  • Click on Sign Up
  • Fill in the form with your details like name, email address and username
  • Submit the form

We will send you an email with an activation link. Click on the link, and you are ready to go.

 

Explore API Products

Want to be inspired and learn what you could build? Our available APIs are displayed on the API Products page. From here you can navigate to the underlying API Overview pages for details of a specific API. Next, go to the Documentation pages for technical information.

Besides fully usable live API Products, we also provide early access to APIs that are in development and our (experimental) ideas. Each indicated by different coloured banners, these are the development stages we use:

  • Idea: Ideas for API Products that we might create in the future, depending on testing results and user interest.
  • Prototype: Simulated environment which can be used for development, but not in a live digital product.
  • Upcoming: API that is in development and publicly announced, but not available for testing.
  • Closed Beta: Beta version of an API Product available for testing by a limited amount of participants.
  • Live (no banner): Full working API Product available for third parties to use.

 

Subscribe to API Products

Once you have created the account and explored our API products, you are ready to create an App.

  • Login to your account. If you are already logged in, click on My Apps.
  • On the My Apps page, click on Add a new App.
  • Provide the name of your App and select the API product(s) you want to use.
  • Click on Submit.

Now, you'll be redirected to the My Apps page, where you can see the status of your App(s). If you click on your App, you will also see the related API product(s), API-Key and secret.

Note: Use the API-Key to access products associated with your App. For more details, please check the API documentation.

 

Start Developing

The next step is to start experimenting with our APIs. The Sandbox environment enables you to test your App.

  • In this environment, you can access dummy data, to safely try out all the functionalities of our APIs.
  • The sandbox environment is mostly identical to production. The similarity may variate per API product.
  • You will find detailed information about the Sandbox of an API product on the specific API documentation page.

Take a look at the tutorials in the documentation to guide you through it step by step.

How to Go Live

Once you have tested your application and related proposition(s) in our sandbox environment, you can submit a request to go live.

  • First, create a new App for production. By doing so, you will get a different API-Key which you can use for your production environment.
  • To get production access, it is important that both your account and App details are registered correctly.
  • Subscribe to the API products you want to use in the production environment.
  • Submit your request and contact us to request production access. Depending on the API, our API Services team might contact you to discuss the details of your request.
  • Once approved, you are ready to use our API in a live environment.

Authentication

The authentication for this API is done on the basis of access token. To obtain an access token, you need to call our OAuth API. The authentication mechanism can vary per API depending on the required level of authentication.

 

Environments

These are the URLs for the endpoints to get the tokens.

Sandbox: https://auth-sandbox.connect.abnamro.com
Production: https://auth.connect.abnamro.com

 

OAuth Flows

Our APIs are secured using OAuth 2.0. This means you will need to pass an access token when making your request to the APIs. This page will explain how to obtain an access token. We use the following three flows for getting an access token: Client credentials, Authorization code flow and Refresh token.

If you want to go more in depth on some of the OAuth protocol, have a look at the OAuth RFC.

POST /as/token.oauth2

Client credentials are used in scenarios where no ABN AMRO client consent is required. A Third Party Payment Service Provider (TPP) will be authorized for resources purely based on their identity. For this flow the TPP will have to provide their credentials to the OAuth server to obtain a token. This token is then used for authorization at the API gateway.

 

Generate token

 

Request Attributes
Name Type In Required Description
grant_type String Body true The indicator of the type of flow being used, it should contain 'client_credentials'
client_id String Body true The ID that identifies you as an client / TPP
scope String Body true Scope(s) for which the access token is to be created. Multiple scopes can be requested at once by separating them using a space

 

Sample Request

curl -X POST \
{base_url}/as/token.oauth2 \
--cert {location_of_your_certificate} \
--key {location_of_your_private_key} \
--cacert {location_of_your_ca_certificate_chain} \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'client_id={your_id}&scope={the_scopes_you_want}&grant_type=client_credentials'
	

 

Response Attributes
Name Type In Required Description
access_token String Body true The access token which is used to access an API
token_type String Body true The type of token provided
expires_in Number Body false Expiry time of the access token, in seconds

 

Sample Response
		
{
	"access_token": "{your_new_access_token}",    
	"token_type": "Bearer",
	"expires_in" : 3599
}
	

The Authorization Code is used when consent by the ABN AMRO client is required to provide the Third Party Payment Service Provider (TPP) access to a resource.

The TPP redirects the ABN AMRO client to the OAuth server, so that the ABN AMRO client can provide his consent. The ABN AMRO client is then returned to the TPP with an access code. This access code can be exchanged by the TPP for an access token and (if applicable) a refresh token. This access token can then be used to gain access to an API.

Access tokens are valid for a limited time, depending on the context. A refresh token is also provided, enabling the TPP to obtain new access token at a later time. Refresh tokens can also expire. When this occurs, the ABN AMRO client is requested to provide consent again, thus repeating the earlier process. The refresh token reflects the time for which the ABN AMRO client has provided consent, when the refresh token has expired, so has the consent.

 

Request Consent

GET /as/authorization.oauth2

This operation asks the ABN AMRO client to give consent on requested resources or a specific transaction. The scopes determine which resources are being requested.

 

Request Attributes
Name Type In Required Description
scope String Query true Scope(s) for which the access token is to be created. Multiple scopes can be requested at once by separating them using the + character
client_id String Query true The ID that identifies you as an client / TPP
flow String Query true The type of OAuth flow that is started. Should contain the value 'code' for the OAuth/consent API
redirect_uri String Query false Mandatory if multiple redirect url's or wildcard url's are registered at ABN AMRO for the client / TPP
state String Query false A parameter that is returned to the calling party which can be used for session management
transactionId String Query false Unique id generated during the registration of a payment that needs to be authorized by the ABN AMRO client
bank String Query false ID of the bank of the ABN AMRO client, see table Bank Parameter Values. Defaults to NLAA01, unless otherwise specified
response_type String Query true For the authorization code the value should be 'code'

 

Bank Parameter Values
Value Associated bank
BEPB01 Belgium private banking
BEPB02 Belgium independant asset management
NLAA01 ABN AMRO NL

 

Sample Request

curl -X GET \
'{base_url}/as/authorization.oauth2?scope={the_scope(s)_you_want}&client_id={your_client_id}&response_type=code&flow=code' \
-H 'Cache-Control: no-cache' 
		

 

Response Attributes

The result of this request is not an response but a redirect to the specified redirect_uri.

Name Type In Required Description
code String Query true A unique authorization code representing the given consent
state String Query false If the state was provided in the original request, the same value will be present in the redirect request

 

Sample Response
https://{your_chosen_location.org}?code={authorization_code}
	

 

Exchange Authorization Code for an Access Token

POST /as/token.oauth2

This operation will exchange the authorization code for an access token. The authorization code is only valid for 60 seconds, during which it needs to be exchanged for an access token.

 

Request Attributes
Name Type In Required Description
grant_type String Body true The indicator of the type of flow being used, it should contain 'authorization_code'
client_id String Body true The ID that identifies you as an client / TPP
code String Body true The authorization code
redirect_uri String Body false If the Request Consent request contained a redirect_uri the same parameter should be passed in the request

 

Sample Request

curl -X POST {base_url}/as/token.oauth2 \
-v \
--cert {location_of_your_certificate} \
--key {location_of_your_private_key} \
--cacert {location_of_your_ca_certificate_chain} \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=authorization_code&client_id={your_id}&code={short_lived_authorization_code}'
	

 

Response Attributes
Name Type In Required Description
access_token String Body true The access token which is used to access an API
refresh_token String Body false Long validity token
scope String Body false Scope(s) for which the access token is created.
token_type String Body true The type of the access token generated
expires_in Number Body false Expiry time of the access token, in seconds

 

Sample Response
		
{
	"access_token": "{your_access_token}",    
	"refresh_token": "{your_refresh_token}",
	"token_type": "Bearer",
	"expires_in" : 7193
}
	

POST /as/token.oauth2

This operation will generate an access token and a new refresh token for an existing consent.

 

Request Attributes
Name Type In Required Description
grant_type String Body true The indicator of the type of flow being used, it should contain 'refresh_token'
client_id String Body true The ID that identifies you as an client / TPP
refresh_token String Body true The refresh token obtained during the exchange of authorization code or a previous refresh request

 

Sample Request

curl -X POST {base_url}/as/token.oauth2  \
-v \
--cert {location_of_your_certificate} \
--key {location_of_your_private_key} \
--cacert {location_of_your_ca_certificate_chain} \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=refresh_token&client_id={your_client_id}&refresh_token={your_refresh_token}'

 

Response Attributes
Name Type In Required Description
access_token String Body true The access token which is used to access an API
refresh_token String Body false Long validity token
token_type String Body true The type of the access token generated
expires_in Number Body false Expiry time of the access token, in seconds

 

Sample Response
		
{
	"access_token": "{your_new_access_token}",    
	"refresh_token": "{your_new_refresh_token}",
	"token_type": "Bearer",
	"expires_in" : 7193
}
	

 

Authentication Methods

During the OAuth flows, you are required to authenticate using your OAuth client. There are several methods available for authentication. The API you want to use determines which method has to be used.

TLS-MA is a form of mutual authentication and is also known as Mutual TLS or 2way SSL. It is similar to the normal TLS used by most websites where the server authenticates itself using a server certificate. TLS-MA has the extra step of having the client send it's certificate as proof of it's identity too. The OAuth client is configured to accept one certificate for authentication, this is certificate has to be used to set up TLS-MA. There is no certificate pinning involved, a check is done of the certificates validity, issuer DN, and the subject DN. This allows expired certificates to be renewed without having to update the configuration of your client.

 

Authorization Server's Certificate

Our certificate has been signed by Quovadis. subject DN:

/C=NL/ST=NH/L=Amsterdam/O=ABN AMRO Bank N.V./OU=Identity Federation/ CN=auth.connect.abnamro.com

 

issuer DN:

/C=BM/O=QuoVadis Limited/CN=QuoVadis Global SSL ICA G2

 

How to do TLS-MA

Most of the work will be taken care of by using the appropriate libraries. As it depends on the language and library used, it is best to search the web which libraries are available and how they work.

An example in curl:


curl -X GET \
{base_url} \
--cert {location_of_your_certificate} \
--key {location_of_your_private_key} \
--cacert {location_of_your_ca_certificate_chain}

 

Which Certificate Authorities (CA) does ABN AMRO support?

For PSD2 we support QWAC Eidas certificates. If you want to see the list of currently suported CA, you can issue the following command to find out which CA ABN AMRO trusts.


openssl s_client -connect {host}:8443

This will prompt the server to tell you which Certificate Authorities it accepts under the header "Acceptable client certificate CA names".

 

Can I use a different Certificate Authority (CA) than specified in the list of accepted CAs?

Yes, it is possible to use a different CA. Let us know which CA you would like to use. We will check if this CA is acceptable. If it is, we will add it to the list. Please be aware that this process may take up to several weeks.

Using this method, you will create and sign a JSON Web Token (JWT) using your private key. The client is configured with a public key to validate the signing. The private and public key need to be part of the same key pair for the authentication to be successfull. Please, note that with the signed JWT method no certificates are involved in the authentication.

 

API Endpoint

This OAuth API has one endpoint. By making a post request to this endpoint, you can obtain an access token for the other APIs.

To make the request to this endpoint, you need the following settings:

Request Attrtibutes Value
Method POST
Path https//api-sandbox.abnamro.com/v1/oauth/token
Headers Content-Type: application/x-www-form-urlencoded
API-Key: (your API key)
Form-data client_assertion: (JSON Web token required to authenticate client)
client_assertion_type: urn:ietf:params:oauth:client-assertion-type:jwt-bearer
grant_type: client_credentials
scope: (the desired scope)(Optional)

The request body will contain a json payload with an attribute named "client_assertion". This attribute will contain the JSON Web token. The token will be used to authenticate the consumer and send back an access token in response.

A JSON web token is a string which consists of three parts where is part is separated by a dot: header.payload.signature. The API consumer needs to generate the JSON web token. Please refer the following steps to create the JSON web token.

 

1. Create public/private key pair

The above OAuth API to be used for authentication requires a JSON web token, which requires signing by a private key from at least a 2048 bit size public/private key pair. The public key of the key pair needs to be shared with ABN AMRO. Following are sample commands to generate a 2048 bit size key pair:


#generates RSA private key of 2048 bit size
openssl genrsa -out private_rsa.pem 2048

#generates public key from the private key
openssl rsa -in private_rsa.pem -outform PEM -pubout -out public_rsa.pem

The keys need to be in PEM format.

Note: Please share your public key along with your app name and developer email id at api.support@nl.abnamro.com. Token generation will not work unless public key is associated with your app.

 

2. Create the header

The header describes how the signature should be generated. It is a JSON object of the following format:


{
	"typ": "JWT",
	"alg": "RS256"
}

In the above json the value of "typ" specifies that this is a JSON web token (JWT), and the value of "alg" specifies the hashing algorithm used to generate the signature component of the JSON web token. Following is the list of alogrithms supported by our OAuth API.

  • RS256
  • RS384
  • RS512

 

3. Create the payload

The payload component of the JSON web token stores the data to be passed in the web token. This data is referred to as "claims" of the JSON web token. The required claims are "exp", "nbf", "sub", "iss" and "aud". It can have an optional claim as "nbf". Following are the definitions of each claim:

Claim Description Mandatory
exp This claim will contain the expiry time in seconds since 1st January, 1970. It cannot be before the current time. This is an integer value, don't put quotes around the value Yes
nbf This claim will contain the time in seconds since 1st January, 1970 before which the JSON web token cannot be processed. Current date date/time must be equal to or after this value. This is an integer value, don't put quotes around the value Yes
iss This claim contains the name of the issuer Yes
sub This claim will contain the api key of the consumer. Refer this link Yes
aud This claim will contain the token URL which are fixed strings.
For sandbox: `https://auth-sandbox.abnamro.com/oauth/token`
For production: `https://auth.abnamro.com/oauth/token`
true

Note: The difference between "exp" and "nbf" cannot be greater than 20 minutes. A sample payload is as following:


{
	"nbf": 1499947668,
	"exp": 1499948668,
	"iss": "me",
	"sub": "anApiKey",
	"aud": "https://auth-sandbox.abnamro.com/oauth/token"
}

 

4. Create the signature

The signature is created using the following pseudocode.


data = base64urlEncode( header ) + “.” + base64urlEncode( payload )
signature = Hash( data, secret );

What this pseudocode does is base64url encodes the header and the payload created in steps 1 and 2. The algorithm then joins the resulting encoded strings together with a period (.) in between them. This joined string is assigned to data. To get the JSON web token signature, the data string is hashed with the private key(generated in first step) using the hashing algorithm specified in the JWT header. The Base64 url encoded values and the signature are as following:


header = eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9
payload = eyJzdWIiOiJ4eHh5eHgiLCJleHAiOiIxNDk5OTQ3NjY4IiwiaXNzIjoibWUiLCJhdWQiOiJodHRwczovL2F1dGgtc2FuZGJveC5hYm5hbXJvLmNvbS9vYXV0aC90b2tlbiJ9
signature = jGwHKG_YjgKpR8NPpaLu6nJ97obeP2vcxg6fOWBKdJ0

The JSON web token will be like the following:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ4eHh5eHgiLCJleHAiOiIxNDk5OTQ3NjY4IiwiaXNzIjoibWUiLCJhdWQiOiJodHRwczovL2F1dGgtc2FuZGJveC5hYm5hbXJvLmNvbS9vYXV0aC90b2tlbiJ9.jGwHKG_YjgKpR8NPpaLu6nJ97obeP2vcxg6fOWBKdJ0

Sample JSON web tokens can be generated at jwt.io You can also use the following node.js code snippet to generate a JSON web token. The code snippet reads the private key from a file named "private_rsa.pem".


var jwt = require('jsonwebtoken');
var fs = require('fs');
var algo='RS256';
var payload={
nbf:Math.floor(Date.now() / 1000),
	exp:Math.floor(Date.now() / 1000) + 300,
	sub:'DLjpQoVpzPshdnwIJEMXnTUhGzGrCG2m',
	iss:'me',
	aud:'https://auth-sandbox.abnamro.com/oauth/token'
};

// sign with RSA SHA256
var cert = fs.readFileSync('private_rsa.pem');  // get private key
jwt.sign(payload, cert, { algorithm: algo},function(error,token){
console.log(token);
});

A complete example call made with curl:


curl -X POST https://api-sandbox.abnamro.com/v1/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "API-Key: xxxxxx" \
-d 'client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&grant_type=client_credentials&client_assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ4eHh4eHgiLCJleHAiOiIxNDk5OTQ3NjY4IiwiaXNzIjoibWUiLCJhdWQiOiJodHRwczovL2F1dGgtc2FuZGJveC5hYm5hbXJvLmNvbS9vYXV0aC90b2tlbiJ9.jGwHKG_YjgKpR8NPpaLu6nJ97obeP2vcxg6fOWBKdJ0&scope=tikkie'

If the request is successful, you can expect the following response:


{
	"access_token": "{your access token}",
	"expires_in": "{duration of validity in seconds}",
	"scope": "{scope(s) for which the access token is valid}",
	"token_type": "{it is always Bearer}"
}

Error Handling

This section provides an overview of the ABN AMRO APIs error model.

 

Error Format

All ABN AMRO APIs throw errors in following JSON format:

	
{
	"errors": [
		{
			"code": "ERROR_UNIQUE_CODE",    
			"message": "ERROR_MESSAGE",
			"category" : "SHORT_DESCRIPTION/ERROR_CATEGORY",
			"reference" : "API_DOCUMENTATION_LINK",
			"status" : "HTTP_STATUS_CODE",
			"traceId" : "UUID"
			
		}
	]

}

These response attributes are explained below:

Name Type Required Description
code String true Code that uniquely identifies the error for the API
message String true Long text message describing the error
category String true Short description or category of the error
reference String true API Documentation link
status String true HTTP Status code
traceId String true Unique request ID associated with the API call

 

HTTP Status Codes

ABN AMRO uses standard HTTP response codes(i.e. 2xx for success, 4xx for invalid information and 5xx for server side errors) to indicate success or failure of an API request.

 

Error Codes

Error codes in the error response uniquely describe the error. Whenever you contact API Support for any specific error you are seeing in an API please provide the error code and traceId.

Details of generic error codes are as follows:

Code Category Description
ERR_1001_001 INCORRECT_HEADER Malformed or incorrect Authorization header
ERR_1002_001 MISSING_HEADER Basic authentication header missing
ERR_1002_002 MISSING_HEADER Access token header missing
ERR_1002_003 MISSING_HEADER API Key Header missing
ERR_1003_001 MALFORMED_REQUEST JSON Request: Container Depth exceeded
ERR_1003_002 MALFORMED_REQUEST JSON Request: Number of elements/ properties in an object exceeded the allowed limit
ERR_1003_003 MALFORMED_REQUEST JSON Request: Number of elements in an array exceeded the allowed limit
ERR_1003_004 MALFORMED_REQUEST JSON Request: Object entry/property name too long
ERR_1003_005 MALFORMED_REQUEST JSON Request: Object property value too long
ERR_1003_006 MALFORMED_REQUEST Request message malformed
ERR_1003_007 MALFORMED_REQUEST SOAP Request Message malformed
ERR_1004_001 INCORRECT_PARAMETER Incorrect or missing value for {parameter name}
ERR_1004_002 INCORRECT_PARAMETER Incorrect value of grant type
ERR_1004_003 INCORRECT_PARAMETER Token passed is not a valid token type
ERR_1004_004 INCORRECT_PARAMETER Incorrect or missing value for client_assertion_type
ERR_1005_001 JWT_LIFESPAN_TOO_LONG JWT lifespan too long
ERR_1006_001 JWT_INCORRECT Some attribute is incorrect, see the error message
ERR_1007_001 JWT_INCOMPLETE Some attribute is missing, see the error message
ERR_1008_001 JWT_EXPIRED The presented JWT has expired
ERR_1009_001 JWT_INACTIVE The presented JWT is not active yet
ERR_1010_001 JWT_INVALID The signature of the presented JWT is not valid
ERR_1010_002 JWT_INVALID The algorithm used to sign the presented JWT is not supported
ERR_1011_001 JWT_MALFORMED The presented JWT is malformed
ERR_2001_001 INVALID_CLIENT_IDENTIFIER Client identifier is either missing or invalid
ERR_2002_001 INVALID_ACCESS_TOKEN Invalid access token
ERR_2003_001 ACCESS_TOKEN_EXPIRED Access token expired
ERR_2004_002 APIKEY_STATUS_NOT_ACTIVE The developer who created the the Developer App that has the API key you are using has an inactive status
ERR_2004_003 APIKEY_STATUS_NOT_ACTIVE The Developer App associated with the API key is revoked
ERR_2005_001 INVALID_API_KEY Invalid API Key
ERR_2005_002 INVALID_API_KEY API Key cannot be used for the API call
ERR_3001_001 ACCESS_DENIED Acccess denied for this IP address
ERR_3002_001 INSUFFICIENT_SCOPE Insufficient scope of the token. Token cannot be used for this call
ERR_3002_002 INSUFFICIENT_SCOPE Insufficient scope of the token. Token cannot be used for this call
ERR_7001_001 QUOTA_VIOLATION Quota for the call exceeded
ERR_7002_001 TOO_MANY_REQUESTS Spikes in API Call
ERR_8XXX_XXX INTERNAL_SERVER_ERROR All errors of this range of codes corresponds to internal server error
ERR_9001_001 SERVICE_UNAVAILABLE Service is currently unavailable

 

Note: Details for error codes specific to APIs are described in respective API documentation.

Support

Do you have any questions or problems? We are happy to help you. Please check the support page for frequently asked questions.

Were you unable to find the answer you need? Please contact us and we will get back to you as soon as possible.

Happy developing! We are looking forward to seeing what you create.