How to get started with our APIs

Get Started

ABN AMRO Bank offers a collection of APIs that will allow you to integrate our services into your applications. This page will guide you through all the steps you need to take before you can make your first API call.

  1. Registration
  2. Obtaining an API key
  3. Authentication
  4. Sandbox testing



Before you can start using our APIs, you will first need to register on the developer portal.

  1. Go to the Registration page.
  2. Fill in the form with your details.
  3. Submit the form!

After submitting, we will send you an email with an activation link. Activate your account by following that link and you are ready to go!


Obtaining an API Key

To actually start using APIs, you need to get an API key. This you can do from the My Apps page. To go to your My Apps:

  • Log in to your developer account. You will automatically land on the My Apps page.
  • If you are already logged in, click on My Apps.

On the My Apps page, you will be able to register an app. This is necessary to get an API key. To register an app do the following:

  1. Click the ‘Request API Key’ button. Or, if you already have an app registered, click ‘Add a new App’.
  2. Submit a name and choose which API product(s) you want to associate with your app. Click submit.
  3. You will return to the My Apps page. There you can see the status of your app(s).

Once your app’s status is approved, you can use the API key. You can see your API key and secret by:

  1. Clicking on your app
  2. Selecting the ‘Keys’ tab
  3. Your API key is listed as ‘Consumer Key’. The corresponding secret is listed as ‘Consumer secret’.



To use any of our APIs, you need to authenticate yourself. The authentication is done on the basis of access tokens. To obtain an access token, you need to call our OAuth API. This API is included in all our API products. The authentication mechanism can vary per API depending on the required level of authentication. Currently we support only client assertion based OAuth which is described below.

OAuth API (Client assertion based)

The 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 attributes Value
Method POST
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)


Client Assertion (JSON Web Token)

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 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:
    For production:


    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": ""


  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 = eyJzdWIiOiJ4eHh4eHgiLCJleHAiOiIxNDk5OTQ3NjY4IiwiaXNzIjoibWUiLCJhdWQiOiJodHRwczovL2F1dGgtc2FuZGJveC5hYm5hbXJvLmNvbS9vYXV0aC90b2tlbiJ9
    signature = jGwHKG_YjgKpR8NPpaLu6nJ97obeP2vcxg6fOWBKdJ0

    The JSON web token will be like the following:


    Sample JSON web tokens can be generated at 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( / 1000),
            exp:Math.floor( / 1000) + 300,
    // sign with RSA SHA256
    var cert = fs.readFileSync('private_rsa.pem');  // get private key
    jwt.sign(payload, cert, { algorithm: algo},function(error,token){


A complete example call made with curl:

curl -X POST -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}"

You can now start using the APIs using your access token!

Click here to download the Open API Specification of OAuth API in yaml format.


Error Handling

This section provides an overview of the ABN AMRO APIs error model as well as guidance to developers on how to handle these errors.

  1. Error Format
  2. HTTP Status Codes
  3. Error Codes
Error Format

All ABN AMRO APIs throw errors in following JSON format:

"errors": [
	  "code": "ERROR_UNIQUE_CODE",    
	  "message": "ERROR_MESSAGE",
	  "reference" : "API_DOCUMENTATION_LINK",
	  "status" : "HTTP_STATUS_CODE",
	  "traceId" : "UUID"

These response attributes are explained in more detail:

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

The category of an error will indicate what a specific problem is. For example suppose there is a category that indicates “invalid IBAN”. There could be multiple reasons why the IBAN is invalid: “illegal country code”, “IBAN too long”, “IBAN too short” just to mention a few. That would result in three unique error codes, all with the same category.

For a consumer of the API the exact reason why the IBAN is invalid may not matter. When an “invalid IBAN” is reported an interactive application will prompt the user to enter the correct IBAN. A non-interactive system may flag an input record as having an invalid IBAN which needs to be investigated later on by an operator.

An API consumer should always first consider if the category suffices. If more specific error handling is needed the entire code can be considered however an API consumer should never assume that only a fixed set of error codes are used. At a later point in time additional errors can be added for the same category.

For the “invalid IBAN” category another reason could be that the checksum on the IBAN fails. The addition of the checksum validation could result in another “invalid IBAN” error that should be treated by API consumers as any other “invalid IBAN” error. The code of the API-consumer should never break on additional reasons (like IBAN checksum failed). API consumers should not throw "unknown reason" exceptions, just treat it as another error in the same category.


HTTP Status Codes

The ABN AMRO API attempts to return appropriate HTTP status codes for every request. HTTP Status codes used in APIs are as follows:

Code Text Description
200 OK Request successful and Response not empty (e.g. used with POST or GET requests)
201 Created Resource successfully created (used with POST requests)
202 Accepted Response to long-running processes / Start of an asynchronous process. The response body contains a way to monitor the process.(e.g used with DELETE requests where the action will likely succeed but has not yet been enacted)
204 No Content Request successful and Response empty (e.g. used with PUT or DELETE requests; also used with partial updates / POST requests with patch keyword)
301 Moved Permanenently This and all future requests should be directed to the provided URI. (used with All)
303 See Other The response to the request can be found under another URI. (used with PATCH,POST,PUT, DELETE)
304 Is Modified Not Modified - resource has not been modified since the date or version passed via request headers If-Modified-Since or If-None-Match
400 Bad Request Validation errors or missing data in request
401 Unauthorized Authentication errors (Access token not valid or API key not valid)
403 Forbidden Authorization error (Insufficient scope)
404 Not Found Requested resource not found
415 Unsupported Media Type Media type not supported
429 Too Many Requests Quota exceeded
500 Internal Server Error Technical errors
503 Service Unavailable Service Unavailable
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 Malformed request body
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.


Sandbox Testing

The next thing to do is to start experimenting with our APIs. You should do this in the sandbox environment we provide specifically for this purpose. In this environment you can access dummy data and accounts, to safely try out all the functionalities of our APIs. The interface is identical to the interface of our production APIs, the only difference is the data that is accessed through the API. Making a call to a sandbox API functions the same as making a call to a regular API.

As the interface is different for each API, please have a look at the documentation of the API you have registered your app with. There you will find a Tutorials section which will tell you all you need to know to make a first call. Or take a look at the Operations & Sandbox pages to see a list of all the operations offered for that specific API. And if you are looking for a more in-depth description of the API interface, just visit the Technical Details.