Beneficiary Account Validation API - details
Beneficiary Account Validation API (application programming interface) is a service which enables corporate customers to reduce risk when making cross-border payments. We do so by enabling our corporate customers to confirm the validity of a beneficiary’s account number before sending the payment, both incorrect and fraudulent payments can be reduced in an automated way via API.
During the subscription process of the BAV production version you will see the BAV product plan, which is stating: “10 000 calls per hour”. Please be informed, that this number is related to the maximum allowed amount of calls per hour from you to Nordea (rate limit). Pricing of the calls will always be according to your agreement with Nordea.
The service is available in Finland, Sweden, Norway and Denmark.
Changes in version 4
The debtor_country is now mandatory. This change ensures that your queries are handled in your home country by specialists understanding your business. Towards the end of year 2023 you can also expect faster responses for requests with Nordea BIC code and the support of Scandinavian characters on beneficiary name and address.
Sandbox version includes error_reason field in case of error to provide e.g. more information which field validation failed. This error response field is not available in version 2 in the production environment and this should be considered during client error handling.
Sandbox version
In the Sandbox API console the following configuration should be used: Choose Application: Choose Flow: No Authentication Client Secret:
Postman collection can be used instead of Sandbox API console if preferred.
Postman collection with examples can be utilized for testing requests to Sandbox BAV. Following headers has to be filled out :X-IBM-Client-Id and X-IBM-Client-Secret.
You can find the Postman collection here: BAV API SANDBOX
Changes in version 4
The version has been adjusted to match changes done for production version - additional_notes and debtor_country fields are now supported in sandbox version. The debtor_country field is from version 4 mandatory. New version is available under following URL: /payment-creditors/v4/prevalidations
New PUT endpoint has been added to manually change the status and result for a given case. This endpoint is available only for sandbox version. This endpoint URL has the following form:
PUT /payment-creditors/v4/prevalidations
Request will look like this:
{
"id": "02bc6c8f-b9ce-4a0f-a9b2-ac8a795e3a3d",
"case_status": "CLOSED_TIMEOUT",
"prevalidation_result": "BENEFICIARY_BANK_REFUSAL"
}
Response will look like this:
{
"prevalidations": [
{
"creditor_account_number": "FI4250001510000023",
"case_status": "closed_timeout",
"prevalidation_result": "beneficiary_bank_refusal",
"additional_notes": "BENEFICIARY_BANK_POLICY",
"last_modified_timestamp": "2021-10-06T10:52:37.845Z",
"original_request_timestamp": "2021-09-16T11:39:10.872Z",
"expiry_timestamp": "2021-09-19T16:00:00Z",
"id": "02bc6c8f-b9ce-4a0f-a9b2-ac8a795e3a3d"
}
]
}
Input Validation
Some changes to input validation has been introduced to provide more informative responses. Below you can find incorrect messages and responses for such messages.
Some fields contain illegal characters
Request:
{
...
"address_line": [
"addressline1 #"
],
...
}
Response
{
"error": "Data binding and validation failure",
"description":"One of address lines contains at least one illegal character : < > ; # $ ^ & ? ` \\ \" �"
}
Some fields contain some unexpected characters for field that allow only letters, digits or whitespaces
Request:
{
...
"value_added_tax_number": "FI2112345600000666@",
...
}
Response
{
"error": "Data binding and validation failure",
"description": "Value Added Tax number field can contains only letters, digits or whitespaces"
}
Some fields contain some unexpected characters for field that allow only letters, digits or whitespaces
Request:
{
...
"creditor_bank_bic": "ddNDEADKK K",
...
}
´´´
##### Response
```bash
{
"error": "Data binding and validation failure",
"description": "BIC code is not valid (ISO 9362:2009)"
}
The expiry field limit have been exceeded
Request:Some fields contain some unexpected characters for field that allow only letters, digits or whitespaces
{
...
"expiry": 55
...
}
´´´
##### Response
``` bash
{
"error": "Illegal request",
"description": "expiry valid range between 3-31"
}
The expiry field limit allow only two digits
Request:
{
...
"expiry": 123
...
}
Response
{
"error": "Data binding and validation failure",
"description": "Expiry time field character limit has been exceeded. Maximum size is two digits."
}
The country code must be compliant with ISO 3166
Request:
{
...
"country_code": "FId"
...
}
Response
{
"error": "Data binding and validation failure",
"description": "Country code is not a valid or allowed ISO_3166-1_alpha-2 code"
}
The debtor country code must be FI, NO, DK or SE
Request:
{
...
"debtor_country": "PL"
...
}
Response
{
"error": "Decoding failure",
"description": "The client request was invalid. Cannot parse value of fields: debtor_country."
}
API endpoints
The prerequisite for integration, is client’s capability to keep track on opened pre-validation cases and polling on regular basis, e.g. twice a day, to collect status changes and available results from beneficiary banks. In the future there will be more and more banks, that will be capable of providing real-time responses, which will be returned by POST response directly.
Beneficiary Account Validation API has three endpoints:
Endpoint | Supported HTTP Methods |
---|---|
Send a pre-validation request: /v4/prevalidations | POST |
List pre-validations: /v4/prevalidations | GET |
Get a pre-validation case: /v4/prevalidations/{id} | GET |
As you can see from the table, the Beneficiary Account Validation API supports HTTP GET and HTTP POST requests.
The first endpoint can be used to open a pre-validation request case at beneficiary bank. The case starts with “pending_created” status. The second endpoint can be used to poll for all the cases or by a status, which have been active cases within 30 days period. A status filter can be applied by adding ?status=pending or ?status=closed to URI path. The third endpoint can be used to poll for a single case. This endpoint can return a result of a case opened within a year, and is not subject to limitation of 30 days.
Pre-validation Results
The following table presents the available return values returned by API.
Result | Status | Explanation |
---|---|---|
pending | pending_created | Initial result value when a case is opened. |
pending | pending_beneficiarybank_response | Request is sent out to beneficiary bank and waiting for its reply. |
pending | pending_beneficiarybank_response_reminded | Beneficiary bank has been reminded of an open case. |
invalid_request | closed_resolved | The end result in case the request is rejected by Swift and cannot be delivered to beneficiary bank. |
beneficiary_validation_match | closed_resolved | The end result in case beneficiary bank can confirm validity of beneficiary data. |
beneficiary_validation_mismatch | closed_resolved | The end result in case beneficiary bank flags invalidity of provided beneficiary data. |
beneficiary_validation_incomplete | closed_resolved | The end result in case beneficiary bank flags inconsistency in provided beneficiary data. Reserved for future usage, not applicable in current API version. |
beneficiary_bank_refusal | closed_timeout | Beneficiary bank declines to respond to a pre-validation request. Sending another request to the same beneficiary bank in question is discouraged. |
beneficiary_bank_refusal | closed_resolved | Beneficiary bank has responded and they have explicitly refused to provide any information. |
Tips & Tricks
Address is optional - if creditor name is correct but the address is incorrect, the case would be resolved as a mismatch. Beneficiary should give the name and address information in a format that can be effected in a cross-border payment via SWIFT. BIC codes ending with 1 are not supported, since there iso direct SWIFT connection available. Example: HJELN021. In addition to diacritics (ä, ö, å etc.), the creditor_name field cannot contain some special characters such as ‘&’. Please note, that the beneficiary vendors name should be in the same format as the account holders name. For the ‘expiry’ field in the prevalidation request, we recommend to use a bit higher values (i.e. 7 days and more), as some beneficiary banks might be not responding quickly. Please note during the onboarding process to production BAV, that the credentials for production version have different naming, compared to the Sandbox version. In Sandbox, it is “Client ID” and “Client secret” and in production “API Key” and “API Credentials”.
Case Statuses
When a pre-validation case is opened at Nordea, it initially returns pending_created status. This will be followed by pending_beneficiarybank_response once the request is delivered to beneficiary bank. In case beneficiary bank does not react in respect to delivering the response within expected expiry time, Nordea sends reminder and updates the status to pending_beneficiarybank_response_reminded. The first reminder is sent after 2 days and the next one after another 2 days. The final status of a pre-validation case can be closed_timeout or closed_resolved. Expiry time is only for customer information - it is not passed to the beneficiary bank. After the expiry date we will no longer send reminders to the beneficiary bank. However the beneficiary bank may still respond after the expiry date, and we will in this case make the response available to you. The expiry date is set in the ‘expiry’ field, which is optional in the prevalidation request and if not set, 7 days default value is used.
Beneficiary Account Validation API examples
Here you can find examples on how to use the Beneficiary Account Validation API endpoints.
You can find the client id, and client secret from your app console. As a part of the production onboarding you will create an application subscribing to the API and generate a client-id, as explained here: https://guide.nordeaopenbanking.com/.
Example: Send a pre-validation request
This endpoint URL has the following form:
POST /payment-creditors/v4/prevalidations
The request body is constructed in following way: creditor_account_number, creditor_name, creditor_bank_bic are mandatory values. Creditor business-id, value_added_tax_number and creditor_address are used to provide accuracy in identifying and validating creditor information. Expiry is given in calendar days and defaults to 7 if no value is provided.
If field values such as address contain letters with diacritical marks, they should be replaced with the closest basic letter without the marks. For Swedish, Norwegian, Danish and Spanish names with tildes, a-rings and o-slashes, the diacritical should be simply ignored: Ä = A, ÄŒ = C, Ñ = N, Ø=O, Œ = OE.
Some special character for e.g. ’&’ are also not allowed. Those special characters should be replaced with allowed ones - for example instead of ’&’ character the phrase ‘AND’ should be used. The allowed character set is as follows: 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 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 1 2 3 4 5 6 7 8 9 / - ? : ( ) . , ’ + Space CrLf
Request will look like this:
{
"creditor_account_number": "DK5000400440116243",
"creditor_name": "Test Creditor Name",
"business_id": "2858394-9",
"value_added_tax_number": "FI2112345600000666",
"creditor_address": {
"address_line": [
"addressline1 "
],
"city": "Helsinki",
"postal_code": "01000",
"country_code": "FI"
},
"creditor_bank_bic": "NDEADKKK",
"debtor_country": "FI"
"expiry": 7
}
Response will look like this:
{
"prevalidations": [
{
"creditor_account_number": "DK5000400440116243",
"case_status": "pending_created",
"prevalidation_result": "pending",
"last_modified_timestamp": "2020-04-30T11:12:43.782Z",
"original_request_timestamp": "2020-04-30T11:12:43.782Z",
"expiry_timestamp": "2020-05-05T16:00:00Z",
"id": "edb69879-4136-4308-8447-3f3607146691"
}
]
}
List of possible return codes:
Error code | Error Description |
---|---|
201 | Success |
400 | The request is invalid. |
415 | Unsupported media type. |
500 | Internal server error. The request could not be delivered. |
Example: Get a list of pre-validations This endpoint URL has the following form:
GET /payment-creditors/v4/prevalidations Response will look like this:
{
"prevalidations": [
{
"creditor_account_number": "DK5000400440116243",
"case_status": "closed_resolved",
"prevalidation_result": "beneficiary_validation_match",
"last_modified_timestamp": "2020-04-15T07:55:59.241Z",
"original_request_timestamp": "2020-04-15T07:52:34.706Z",
"expiry_timestamp": "2020-04-20T16:00:00Z",
"id": "228cf900-8e17-4c99-abf0-1da7756a7e1f"
},
{
"creditor_account_number": "DK5000400440116243",
"case_status": "pending_beneficiarybank_response",
"prevalidation_result": "pending",
"last_modified_timestamp": "2020-04-27T09:37:01.979Z",
"original_request_timestamp": "2020-04-27T09:34:44.435Z",
"expiry_timestamp": "2020-05-02T16:00:00Z",
"id": "0a84bf9a-236d-47eb-bcbb-2063f06a1d7b"
}
],
"disclaimer": "When sending the enquiry Nordea acts at request and on behalf of the customer. Nordea exclusively relays the reply it receives to its enquiry from the foreign bank as such and does not check, or attempt to check, the received information in any way. Nordea is not responsible for the contents or correctness of the information relayed from the foreign bank or potential delays related to the receipt of the information. Nordea is not responsible for the actions, omissions or services of the relevant foreign bank."
}
List of possible return codes:
Error code | Error Description |
---|---|
200 | Success |
400 | The request is invalid. |
404 | Resource not found. |
500 | Internal server error. The request could not be delivered. |
Example: Get a pre-validation case This endpoint URL has the following form:
GET /payment-creditors/v4/prevalidations/228cf900-8e17-4c99-abf0-1da7756a7e1f Response will look like this:
{
"prevalidations": [
{
"creditor_account_number": "DK5000400440116243",
"case_status": "closed_resolved",
"prevalidation_result": "beneficiary_validation_match",
"last_modified_timestamp": "2020-04-15T07:55:59.241Z",
"original_request_timestamp": "2020-04-15T07:52:34.706Z",
"expiry_timestamp": "2020-04-20T16:00:00Z",
"id": "228cf900-8e17-4c99-abf0-1da7756a7e1f"
}
],
"disclaimer": "When sending the enquiry Nordea acts at request and on behalf of the customer. Nordea exclusively relays the reply it receives to its enquiry from the foreign bank as such and does not check, or attempt to check, the received information in any way. Nordea is not responsible for the contents or correctness of the information relayed from the foreign bank or potential delays related to the receipt of the information. Nordea is not responsible for the actions, omissions or services of the relevant foreign bank."
}
List of possible return codes:
Error code | Error Description |
---|---|
200 | Success |
400 | The request is invalid. |
403 | The access to request resource was denied. |
404 | Resource not found. |
500 | Internal server error. The request could not be delivered. |