Payout Banklink API
One PSD2-based API for your users' accounts at their banks:
- Read account information and transactions
- Initiate payments
- Verify a user's identity through their bank account
The Banklink guide shows how the calls fit together.
Amounts are absolute values; creditDebitIndicator gives the sign or direction. Balance
amounts are JSON numbers (1520.35), transaction amounts are decimal strings ("12.50") with
the precision the bank reports, and Initiate payment takes
instructedAmount.amount as a decimal string ("1.00").
Environments
| Environment | Base URL |
|---|---|
| Sandbox | https://wap-sa.payout.one/api |
| Production | https://wap.payout.one/api |
Authentication
Call the API with an OAuth2 access token issued by PayoutID, from the
authorization_code grant (on behalf of a user) or the client_credentials grant. Send it in
the Authorization: Bearer <access_token> header.
| Environment | Authorization endpoint | Token endpoint |
|---|---|---|
| Sandbox | https:// |
https:// |
| Production | https:// |
https:// |
Each endpoint requires one scope:
| Scope | Grants | Endpoints |
|---|---|---|
BLAISP |
Read the user's bank accounts | List accounts, Retrieve account details, Retrieve account details and balances, Retrieve account balances, List transactions, List accounts by consent |
BLIBAN |
Verify that the user has access to a bank account | Verify IBAN |
BLPISP |
Create payments on behalf of the user | Initiate payment, Retrieve payment status |
VERIFY |
Verify the user's identity. Request it with the client_credentials grant |
Create verification, Retrieve verification status |
List integrations needs a valid access token but no specific scope.
A missing, invalid or expired token, or a token without the required scope, is rejected with
403 and error code UNAUTHORIZED.
Authorizing access to the bank account
When the account is not connected yet, or its authorization at the bank has expired, account
endpoints respond with 403 and a body with consent_id and redirect_url. Then:
- Redirect the user to
redirect_urlwith the query parametersredirect_uri(one of the redirect URIs registered for your application) and optionallystate. - The user authorizes access at the bank and is redirected back to
redirect_uritogether withstate. - Repeat the request. To get every account the user authorized, call
List accounts by consent with
consent_id.
Payments and verifications use the same redirect: _links.sca.href from
Initiate payment and redirect_url from
Create verification.
Errors
Errors use HTTP status codes and return a tppMessages array:
{
"tppMessages": [
{
"category": "ERROR",
"code": "INVALID_INPUT",
"text": "Unsupported IBAN country",
"xpath": "/debtorAccount/iban"
}
]
}
xpath is present only for validation errors (INVALID_INPUT).
| HTTP | Code | Meaning |
|---|---|---|
| 400 | INVALID_REQUEST |
Missing or invalid header or body |
| 400 | INVALID_INPUT |
A request body field failed validation, see xpath |
| 400 | UNSUPPORTED_BANK |
Bank could not be recognised from iban and bank, or unknown verification |
| 400 | INVALID_PAYMENT_PRODUCT |
Unknown payment_product path parameter |
| 401 | INVALID_TOKEN |
Token does not identify the application (aud, auu claims) |
| 403 | UNAUTHORIZED |
Missing, invalid or expired token, or missing scope |
| 500 | INTERNAL_SERVER_ERROR |
Unexpected bank response or internal error |
The two authentication codes are the reverse of what their names suggest: an invalid or expired
token gets 403 with UNAUTHORIZED, while 401 with INVALID_TOKEN means a valid token whose
claims do not identify your application.
Two responses have a different body:
- A
403from an account endpoint can carryconsent_idandredirect_urlinstead, see Authorizing access to the bank account. - An unknown payment in Retrieve payment status returns
404with{"errors": {"detail": "Not Found"}}.
Lists the bank accounts the user has connected to Banklink. Banklink answers from its own records and does not call the bank.
curl -X POST 'https://wap-sa.payout.one/api/v1/accounts' \
-H "Authorization: Bearer $TOKEN"const res = await fetch("https://wap-sa.payout.one/api/v1/accounts", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PAYOUT_TOKEN}`,
},
});
const data = await res.json();import os, requests
res = requests.post(
"https://wap-sa.payout.one/api/v1/accounts",
headers={"Authorization": f"Bearer {os.environ['PAYOUT_TOKEN']}"},
)
data = res.json()<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://wap-sa.payout.one/api/v1/accounts");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer " . getenv("PAYOUT_TOKEN")]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);{
"accounts": [
{
"identification": {
"iban": "SK3112000000198742637541"
},
"name": "Main account",
"baseCurrency": "EUR",
"providerName": "tatrabanka"
}
]
}Response 200
Show 4 child attributesHide child attributes
Show 1 child attributeHide child attributes
IBAN of the account
Account name
Account currency (ISO 4217)
Name of the bank servicing the account
Other responses
Missing, invalid or expired access token, or missing scope (UNAUTHORIZED)
Example
{
"tppMessages": [
{
"category": "ERROR",
"code": "UNAUTHORIZED",
"text": "Missing or insuficient authorization"
}
]
}Retrieves the details of a connected account from the bank, without balances.
curl -X POST 'https://wap-sa.payout.one/api/v1/accounts/details' \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"iban": "SK3112000000198742637541"
}'const res = await fetch("https://wap-sa.payout.one/api/v1/accounts/details", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PAYOUT_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"iban": "SK3112000000198742637541"
}),
});
const data = await res.json();import os, requests
res = requests.post(
"https://wap-sa.payout.one/api/v1/accounts/details",
headers={"Authorization": f"Bearer {os.environ['PAYOUT_TOKEN']}"},
json={
"iban": "SK3112000000198742637541",
},
)
data = res.json()<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://wap-sa.payout.one/api/v1/accounts/details");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
"iban" => "SK3112000000198742637541"
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer " . getenv("PAYOUT_TOKEN"), "Content-Type: application/json"]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);{
"identification": {
"iban": "SK3112000000198742637541"
},
"name": "Main account",
"productName": "superaccount",
"type": "CACC",
"baseCurrency": "EUR",
"authorizationExpiration": "2026-12-31T08:37:51+00:00"
}Parameters
IP address the user is connected from
Whether the user triggered the request
trueThe request is a direct result of a user actionfalseNot a direct result of a user action
User agent of the user's browser
Request body
IBAN of the account
Integration name from List integrations, for IBANs whose bank cannot be recognised from the IBAN alone
Response 200
Show 1 child attributeHide child attributes
IBAN of the account
Account name
The bank's product name for the account
Account type, a code from the ISO 20022 ExternalCashAccountType1Code list (external code sets), for example CACC (current account) or SVGS (savings account). OTHR means another type
Account currency (ISO 4217)
When the user's authorization of the account expires, in RFC 3339. Set to 90 days after the authorization was created
Other responses
Missing or invalid header or body (INVALID_REQUEST), or the bank could not be recognised (UNSUPPORTED_BANK)
Example
{
"tppMessages": [
{
"category": "ERROR",
"code": "INVALID_REQUEST",
"text": "Missing or invalid header or body"
}
]
}Returned for two different reasons, told apart by the body:
- Bank authorization needed – the account is not connected yet, or its authorization
at the bank has expired. The body has
consent_idandredirect_url; redirect the user, see Authorizing access to the bank account. - Access token rejected – the token is missing, invalid or expired, or lacks the
scope. The body is an error with code
UNAUTHORIZED.
Example
{
"consent_id": 123,
"redirect_url": "https://wap-sa.payout.one/providers/forward/Xk7pQ2"
}Unexpected bank response (INTERNAL_SERVER_ERROR)
Example
{
"tppMessages": [
{
"category": "ERROR",
"code": "INTERNAL_SERVER_ERROR",
"text": "Unexpected bank response"
}
]
}Retrieves a connected account's details and balances from the bank in one call. account
is the same object Retrieve account details returns; the balances are
those of Retrieve account balances without their type.
curl -X POST 'https://wap-sa.payout.one/api/v1/accounts/information' \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"iban": "SK3112000000198742637541"
}'const res = await fetch("https://wap-sa.payout.one/api/v1/accounts/information", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PAYOUT_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"iban": "SK3112000000198742637541"
}),
});
const data = await res.json();import os, requests
res = requests.post(
"https://wap-sa.payout.one/api/v1/accounts/information",
headers={"Authorization": f"Bearer {os.environ['PAYOUT_TOKEN']}"},
json={
"iban": "SK3112000000198742637541",
},
)
data = res.json()<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://wap-sa.payout.one/api/v1/accounts/information");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
"iban" => "SK3112000000198742637541"
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer " . getenv("PAYOUT_TOKEN"), "Content-Type: application/json"]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);{
"account": {
"identification": {
"iban": "SK3112000000198742637541"
},
"name": "Main account",
"productName": "superaccount",
"type": "CACC",
"baseCurrency": "EUR",
"authorizationExpiration": "2026-12-31T08:37:51+00:00"
},
"balances": [
{
"amount": {
"value": 1520.35,
"currency": "EUR"
},
"creditDebitIndicator": "CRDT",
"dateTime": "2026-10-06T08:00:00+00:00"
}
]
}Parameters
IP address the user is connected from
Whether the user triggered the request
trueThe request is a direct result of a user actionfalseNot a direct result of a user action
User agent of the user's browser
Request body
IBAN of the account
Integration name from List integrations, for IBANs whose bank cannot be recognised from the IBAN alone
Response 200
Show 6 child attributesHide child attributes
Show 1 child attributeHide child attributes
IBAN of the account
Account name
The bank's product name for the account
Account type, a code from the ISO 20022 ExternalCashAccountType1Code list (external code sets), for example CACC (current account) or SVGS (savings account). OTHR means another type
Account currency (ISO 4217)
When the user's authorization of the account expires, in RFC 3339. Set to 90 days after the authorization was created
Show 3 child attributesHide child attributes
Show 2 child attributesHide child attributes
Balance as an absolute value, creditDebitIndicator gives the sign
Currency of the balance (ISO 4217)
Sign of the balance
CRDTZero or positive balanceDBITNegative balance
When the balance was checked, in RFC 3339
Other responses
Missing or invalid header or body (INVALID_REQUEST), or the bank could not be recognised (UNSUPPORTED_BANK)
Example
{
"tppMessages": [
{
"category": "ERROR",
"code": "INVALID_REQUEST",
"text": "Missing or invalid header or body"
}
]
}Returned for two different reasons, told apart by the body:
- Bank authorization needed – the account is not connected yet, or its authorization
at the bank has expired. The body has
consent_idandredirect_url; redirect the user, see Authorizing access to the bank account. - Access token rejected – the token is missing, invalid or expired, or lacks the
scope. The body is an error with code
UNAUTHORIZED.
Example
{
"consent_id": 123,
"redirect_url": "https://wap-sa.payout.one/providers/forward/Xk7pQ2"
}Unexpected bank response (INTERNAL_SERVER_ERROR)
Example
{
"tppMessages": [
{
"category": "ERROR",
"code": "INTERNAL_SERVER_ERROR",
"text": "Unexpected bank response"
}
]
}Retrieves the balances of a connected account from the bank.
curl -X POST 'https://wap-sa.payout.one/api/v1/accounts/balance' \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"iban": "SK3112000000198742637541"
}'const res = await fetch("https://wap-sa.payout.one/api/v1/accounts/balance", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PAYOUT_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"iban": "SK3112000000198742637541"
}),
});
const data = await res.json();import os, requests
res = requests.post(
"https://wap-sa.payout.one/api/v1/accounts/balance",
headers={"Authorization": f"Bearer {os.environ['PAYOUT_TOKEN']}"},
json={
"iban": "SK3112000000198742637541",
},
)
data = res.json()<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://wap-sa.payout.one/api/v1/accounts/balance");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
"iban" => "SK3112000000198742637541"
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer " . getenv("PAYOUT_TOKEN"), "Content-Type: application/json"]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);{
"balances": [
{
"amount": {
"value": 1520.35,
"currency": "EUR"
},
"creditDebitIndicator": "CRDT",
"dateTime": "2026-10-06T08:00:00+00:00",
"type": "ITAV"
}
]
}Parameters
IP address the user is connected from
Whether the user triggered the request
trueThe request is a direct result of a user actionfalseNot a direct result of a user action
User agent of the user's browser
Request body
IBAN of the account
Integration name from List integrations, for IBANs whose bank cannot be recognised from the IBAN alone
Response 200
Show 4 child attributesHide child attributes
Show 2 child attributesHide child attributes
Balance as an absolute value, creditDebitIndicator gives the sign
Currency of the balance (ISO 4217)
Sign of the balance
CRDTZero or positive balanceDBITNegative balance
When the balance was checked, in RFC 3339
Balance type, a code from the ISO 20022 ExternalBalanceType1Code list (external code sets), for example ITAV (interim available) or CLBD (closing booked). Some banks add their own codes ACCR, DSCR, OWRS and OWFU
Other responses
Missing or invalid header or body (INVALID_REQUEST), or the bank could not be recognised (UNSUPPORTED_BANK)
Example
{
"tppMessages": [
{
"category": "ERROR",
"code": "INVALID_REQUEST",
"text": "Missing or invalid header or body"
}
]
}Returned for two different reasons, told apart by the body:
- Bank authorization needed – the account is not connected yet, or its authorization
at the bank has expired. The body has
consent_idandredirect_url; redirect the user, see Authorizing access to the bank account. - Access token rejected – the token is missing, invalid or expired, or lacks the
scope. The body is an error with code
UNAUTHORIZED.
Example
{
"consent_id": 123,
"redirect_url": "https://wap-sa.payout.one/providers/forward/Xk7pQ2"
}Unexpected bank response (INTERNAL_SERVER_ERROR)
Example
{
"tppMessages": [
{
"category": "ERROR",
"code": "INTERNAL_SERVER_ERROR",
"text": "Unexpected bank response"
}
]
}Lists the transactions of a connected account, retrieved from the bank. Each page holds up to 100 transactions.
Pagination
To get the next page, repeat the request with page_index set to pagination.next_page
from the previous response. next_page is null on the last page.
curl -X POST 'https://wap-sa.payout.one/api/v1/transactions' \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"iban": "SK3112000000198742637541",
"date_from": "2026-09-01",
"date_to": "2026-09-30"
}'const res = await fetch("https://wap-sa.payout.one/api/v1/transactions", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PAYOUT_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"iban": "SK3112000000198742637541",
"date_from": "2026-09-01",
"date_to": "2026-09-30"
}),
});
const data = await res.json();import os, requests
res = requests.post(
"https://wap-sa.payout.one/api/v1/transactions",
headers={"Authorization": f"Bearer {os.environ['PAYOUT_TOKEN']}"},
json={
"iban": "SK3112000000198742637541",
"date_from": "2026-09-01",
"date_to": "2026-09-30",
},
)
data = res.json()<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://wap-sa.payout.one/api/v1/transactions");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
"iban" => "SK3112000000198742637541",
"date_from" => "2026-09-01",
"date_to" => "2026-09-30"
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer " . getenv("PAYOUT_TOKEN"), "Content-Type: application/json"]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);{
"pagination": {
"next_page": "zxQewRtveXy",
"previous_page": null
},
"transactions": [
{
"amount": {
"value": "12.50",
"currency": "EUR"
},
"creditDebitIndicator": "CRDT",
"valueDate": "2026-09-14",
"bookingDate": "2026-09-14",
"transactionDetails": {
"reversalIndicator": false,
"references": {
"accountServiceReference": "7Q2K9X41",
"endToEndIdentification": "/VS20260914/SS/KS"
},
"relatedParties": {
"debtor": {
"name": "Jan Novák"
},
"debtorAccount": {
"identification": "CZ6508000000192000145399"
},
"creditor": {
"name": "Example Shop, s.r.o."
},
"creditorAccount": {
"identification": "SK3112000000198742637541"
}
},
"remittanceInformation": "Invoice 2026-104"
}
}
]
}Parameters
IP address the user is connected from
Whether the user triggered the request
trueThe request is a direct result of a user actionfalseNot a direct result of a user action
User agent of the user's browser
Request body
IBAN of the account
Integration name from List integrations, for IBANs whose bank cannot be recognised from the IBAN alone
Page to return, from pagination.next_page or pagination.previous_page of a previous response. Omit for the first page
Return no transactions older than this date. Defaults to 90 days ago
Return no transactions newer than this date. Defaults to the end of today
Response 200
Show 2 child attributesHide child attributes
page_index of the next page, null on the last page
page_index of the previous page
Show 6 child attributesHide child attributes
Show 2 child attributesHide child attributes
Amount as an absolute decimal string, creditDebitIndicator gives the direction
Currency of the transaction (ISO 4217)
Date when the funds become available to the account owner, for credits
Date when the transaction was posted to the account in the bank's books
Direction of the transaction
CRDTCredit, money added to the accountDBITDebit, money taken from the account
ISO 20022 bank transaction code
Show 8 child attributesHide child attributes
Whether the transaction reverses a previous one
Show 3 child attributesHide child attributes
Unique transaction id assigned by the bank
End-to-end identification of the transaction, as reported by the bank
Masked card number of a card transaction, for example ** 1111
Show 1 child attributeHide child attributes
Show 2 child attributesHide child attributes
Counter-value amount as a decimal string
Currency of the counter-value amount (ISO 4217)
Show 1 child attributeHide child attributes
Exchange rate applied to the transaction
Show 4 child attributesHide child attributes
Show 1 child attributeHide child attributes
Name of the debtor
Show 1 child attributeHide child attributes
Debtor's account, usually an IBAN
Show 1 child attributeHide child attributes
Name of the creditor
Show 1 child attributeHide child attributes
Creditor's account, usually an IBAN
Show 1 child attributeHide child attributes
Name of the third party. For card transactions, the merchant
Show 2 child attributesHide child attributes
Show 1 child attributeHide child attributes
Debtor's bank, usually a BIC
Show 1 child attributeHide child attributes
Creditor's bank, usually a BIC
Payment message for the receiver
Other responses
Missing or invalid header or body (INVALID_REQUEST), or the bank could not be recognised (UNSUPPORTED_BANK)
Example
{
"tppMessages": [
{
"category": "ERROR",
"code": "INVALID_REQUEST",
"text": "Missing or invalid header or body"
}
]
}Returned for two different reasons, told apart by the body:
- Bank authorization needed – the account is not connected yet, or its authorization
at the bank has expired. The body has
consent_idandredirect_url; redirect the user, see Authorizing access to the bank account. - Access token rejected – the token is missing, invalid or expired, or lacks the
scope. The body is an error with code
UNAUTHORIZED.
Example
{
"consent_id": 123,
"redirect_url": "https://wap-sa.payout.one/providers/forward/Xk7pQ2"
}Unexpected bank response (INTERNAL_SERVER_ERROR)
Example
{
"tppMessages": [
{
"category": "ERROR",
"code": "INTERNAL_SERVER_ERROR",
"text": "Unexpected bank response"
}
]
}Lists the accounts the user authorized under a consent, with their details from the bank.
Call it with the consent_id from a 403 response once the user has authorized access, see
Authorizing access to the bank account.
curl -X POST 'https://wap-sa.payout.one/api/v1/provider/accounts' \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"consent_id": 123
}'const res = await fetch("https://wap-sa.payout.one/api/v1/provider/accounts", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PAYOUT_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"consent_id": 123
}),
});
const data = await res.json();import os, requests
res = requests.post(
"https://wap-sa.payout.one/api/v1/provider/accounts",
headers={"Authorization": f"Bearer {os.environ['PAYOUT_TOKEN']}"},
json={
"consent_id": 123,
},
)
data = res.json()<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://wap-sa.payout.one/api/v1/provider/accounts");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
"consent_id" => 123
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer " . getenv("PAYOUT_TOKEN"), "Content-Type: application/json"]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);{
"accounts": [
{
"identification": {
"iban": "SK3112000000198742637541"
},
"name": "Main account",
"productName": "superaccount",
"type": "CACC",
"baseCurrency": "EUR",
"authorizationExpiration": "2026-12-31T08:37:51+00:00"
}
]
}Parameters
IP address the user is connected from
Whether the user triggered the request
trueThe request is a direct result of a user actionfalseNot a direct result of a user action
User agent of the user's browser
Request body
Consent id from the 403 response of an account endpoint
Response 200
Show 6 child attributesHide child attributes
Show 1 child attributeHide child attributes
IBAN of the account
Account name
The bank's product name for the account
Account type, a code from the ISO 20022 ExternalCashAccountType1Code list (external code sets), for example CACC (current account) or SVGS (savings account). OTHR means another type
Account currency (ISO 4217)
When the user's authorization of the account expires, in RFC 3339. Set to 90 days after the authorization was created
Other responses
Missing consent_id or unknown consent (INVALID_REQUEST)
Example
{
"tppMessages": [
{
"category": "ERROR",
"code": "INVALID_REQUEST",
"text": "Missing or invalid header or body"
}
]
}Returned for two different reasons, told apart by the body:
- Bank authorization needed – the account is not connected yet, or its authorization
at the bank has expired. The body has
consent_idandredirect_url; redirect the user, see Authorizing access to the bank account. - Access token rejected – the token is missing, invalid or expired, or lacks the
scope. The body is an error with code
UNAUTHORIZED.
Example
{
"consent_id": 123,
"redirect_url": "https://wap-sa.payout.one/providers/forward/Xk7pQ2"
}Unexpected bank response (INTERNAL_SERVER_ERROR)
Example
{
"tppMessages": [
{
"category": "ERROR",
"code": "INTERNAL_SERVER_ERROR",
"text": "Unexpected bank response"
}
]
}Verifies that the user has access to the bank account with the given IBAN. Banklink checks the account with the bank.
curl -X POST 'https://wap-sa.payout.one/api/v1/accounts/verify-iban' \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"iban": "SK3112000000198742637541"
}'const res = await fetch("https://wap-sa.payout.one/api/v1/accounts/verify-iban", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PAYOUT_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"iban": "SK3112000000198742637541"
}),
});
const data = await res.json();import os, requests
res = requests.post(
"https://wap-sa.payout.one/api/v1/accounts/verify-iban",
headers={"Authorization": f"Bearer {os.environ['PAYOUT_TOKEN']}"},
json={
"iban": "SK3112000000198742637541",
},
)
data = res.json()<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://wap-sa.payout.one/api/v1/accounts/verify-iban");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
"iban" => "SK3112000000198742637541"
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer " . getenv("PAYOUT_TOKEN"), "Content-Type: application/json"]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);{
"iban": "SK3112000000198742637541",
"verified": true
}Parameters
IP address the user is connected from
Whether the user triggered the request
trueThe request is a direct result of a user actionfalseNot a direct result of a user action
User agent of the user's browser
Request body
IBAN of the account
Integration name from List integrations, for IBANs whose bank cannot be recognised from the IBAN alone
Response 200
IBAN of the verified account
Always true. Without access, the response is 403 instead
Other responses
Missing or invalid header or body (INVALID_REQUEST), or the bank could not be recognised (UNSUPPORTED_BANK)
Example
{
"tppMessages": [
{
"category": "ERROR",
"code": "INVALID_REQUEST",
"text": "Missing or invalid header or body"
}
]
}Returned for two different reasons, told apart by the body:
- Bank authorization needed – the account is not connected yet, or its authorization
at the bank has expired. The body has
consent_idandredirect_url; redirect the user, see Authorizing access to the bank account. - Access token rejected – the token is missing, invalid or expired, or lacks the
scope. The body is an error with code
UNAUTHORIZED.
Example
{
"consent_id": 123,
"redirect_url": "https://wap-sa.payout.one/providers/forward/Xk7pQ2"
}Unexpected bank response (INTERNAL_SERVER_ERROR)
Example
{
"tppMessages": [
{
"category": "ERROR",
"code": "INTERNAL_SERVER_ERROR",
"text": "Unexpected bank response"
}
]
}Creates a payment for the user to authorize at their bank. Redirect the user to
_links.sca.href, see Authorizing access to the bank account,
then track the payment with Retrieve payment status.
curl -X POST 'https://wap-sa.payout.one/api/v1/payments/tatrabanka/sepa-credit-transfers' \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"endToEndIndentification": "/VS1/SS2/KS3",
"creditorAgent": "COBADEFFXXX",
"creditorName": "John Doe",
"debtorName": "Test Testovic",
"remittanceInformationUnstructured": "Testing",
"debtorAccount": {
"iban": "SK3112000000198742637541"
},
"creditorAccount": {
"iban": "DE89370400440532013000"
},
"instructedAmount": {
"amount": "1.00",
"currency": "EUR"
}
}'const res = await fetch("https://wap-sa.payout.one/api/v1/payments/tatrabanka/sepa-credit-transfers", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PAYOUT_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"endToEndIndentification": "/VS1/SS2/KS3",
"creditorAgent": "COBADEFFXXX",
"creditorName": "John Doe",
"debtorName": "Test Testovic",
"remittanceInformationUnstructured": "Testing",
"debtorAccount": {
"iban": "SK3112000000198742637541"
},
"creditorAccount": {
"iban": "DE89370400440532013000"
},
"instructedAmount": {
"amount": "1.00",
"currency": "EUR"
}
}),
});
const data = await res.json();import os, requests
res = requests.post(
"https://wap-sa.payout.one/api/v1/payments/tatrabanka/sepa-credit-transfers",
headers={"Authorization": f"Bearer {os.environ['PAYOUT_TOKEN']}"},
json={
"endToEndIndentification": "/VS1/SS2/KS3",
"creditorAgent": "COBADEFFXXX",
"creditorName": "John Doe",
"debtorName": "Test Testovic",
"remittanceInformationUnstructured": "Testing",
"debtorAccount": {
"iban": "SK3112000000198742637541",
},
"creditorAccount": {
"iban": "DE89370400440532013000",
},
"instructedAmount": {
"amount": "1.00",
"currency": "EUR",
},
},
)
data = res.json()<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://wap-sa.payout.one/api/v1/payments/tatrabanka/sepa-credit-transfers");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
"endToEndIndentification" => "/VS1/SS2/KS3",
"creditorAgent" => "COBADEFFXXX",
"creditorName" => "John Doe",
"debtorName" => "Test Testovic",
"remittanceInformationUnstructured" => "Testing",
"debtorAccount" => [
"iban" => "SK3112000000198742637541"
],
"creditorAccount" => [
"iban" => "DE89370400440532013000"
],
"instructedAmount" => [
"amount" => "1.00",
"currency" => "EUR"
]
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer " . getenv("PAYOUT_TOKEN"), "Content-Type: application/json"]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);{
"paymentId": 123,
"_links": {
"sca": {
"href": "https://wap-sa.payout.one/providers/forward/Xk7pQ2"
}
}
}Parameters
name of an integration from List integrations that supports payment initiation (pisp is true)
Payment method. Integrations support different methods, see supported_payment_methods in List integrations
sepa-credit-transfersSEPA credit transfer, listed assepainstant-sepa-credit-transfersInstant SEPA credit transfer, listed assepa_ipay
Request body
Your end-to-end identification of the payment. The key is spelled endToEndIndentification.
In the form /VS{variable symbol}/SS{specific symbol}/KS{constant symbol}, Banklink reads
the variable, specific and constant symbol from it.
BIC of the creditor's bank
Name of the creditor
E-mail of the creditor, a non-standard field used by the payout integration
Name of the debtor
Payment message for the creditor
Non-standard field, required by csob-cz for business customers
Show 1 child attributeHide child attributes
IBAN of the debtor account. Supported countries:
SK– SlovakiaCZ– Czech RepublicDE– GermanyLT– Lithuania
Show 1 child attributeHide child attributes
IBAN of the creditor account, from the same countries as debtorAccount.iban
Show 2 child attributesHide child attributes
Amount as a decimal string
Response 201
Payment id, used by Retrieve payment status
Show 1 child attributeHide child attributes
Show 1 child attributeHide child attributes
URL to redirect the user to for authorizing the payment
Other responses
Invalid request body (INVALID_INPUT with xpath) or unknown payment_product (INVALID_PAYMENT_PRODUCT)
Example
{
"tppMessages": [
{
"category": "ERROR",
"code": "INVALID_INPUT",
"text": "Unsupported IBAN country",
"xpath": "/debtorAccount/iban"
}
]
}Missing, invalid or expired access token, or missing scope (UNAUTHORIZED)
Example
{
"tppMessages": [
{
"category": "ERROR",
"code": "UNAUTHORIZED",
"text": "Missing or insuficient authorization"
}
]
}Retrieves the current status of a payment. Unless the payment is pending or completed,
Banklink first asks the bank for its latest status.
curl -X GET 'https://wap-sa.payout.one/api/v1/payments/123/status' \
-H "Authorization: Bearer $TOKEN"const res = await fetch("https://wap-sa.payout.one/api/v1/payments/123/status", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.PAYOUT_TOKEN}`,
},
});
const data = await res.json();import os, requests
res = requests.get(
"https://wap-sa.payout.one/api/v1/payments/123/status",
headers={"Authorization": f"Bearer {os.environ['PAYOUT_TOKEN']}"},
)
data = res.json()<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://wap-sa.payout.one/api/v1/payments/123/status");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer " . getenv("PAYOUT_TOKEN")]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);{
"paymentId": 123,
"transactionStatus": "pending"
}Parameters
Payment id returned by Initiate payment
Response 200
Payment id
Status of the payment
pendingCreated in Banklink, not yet posted to the bankinitializedPosted to the bank, not yet validatedreceivedValidated by the bank as technically correctacceptedAccepted by the bank as valid and signed by the user, waiting to be processedunknownSigned, but Banklink could not check its status afterwardscompletedProcessed successfullyrejectedInvalid or declined by the user
Other responses
Missing, invalid or expired access token, or missing scope (UNAUTHORIZED)
Example
{
"tppMessages": [
{
"category": "ERROR",
"code": "UNAUTHORIZED",
"text": "Missing or insuficient authorization"
}
]
}Unknown payment
Example
{
"errors": {
"detail": "Not Found"
}
}Banklink could not get the latest status from the bank (INTERNAL_SERVER_ERROR)
Example
{
"tppMessages": [
{
"category": "ERROR",
"code": "INTERNAL_SERVER_ERROR",
"text": "Something is wrong on our side"
}
]
}Starts verifying the user's identity through their bank account. Redirect the user to the
returned redirect_url, see Authorizing access to the bank account.
Once the user is back, get the result with Retrieve verification status.
The Verification guide describes the whole flow.
curl -X POST 'https://wap-sa.payout.one/api/v1/verifications' \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"iban": "CZ6508000000192000145399",
"first_name": "Jan",
"last_name": "Novák"
}'const res = await fetch("https://wap-sa.payout.one/api/v1/verifications", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PAYOUT_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"iban": "CZ6508000000192000145399",
"first_name": "Jan",
"last_name": "Novák"
}),
});
const data = await res.json();import os, requests
res = requests.post(
"https://wap-sa.payout.one/api/v1/verifications",
headers={"Authorization": f"Bearer {os.environ['PAYOUT_TOKEN']}"},
json={
"iban": "CZ6508000000192000145399",
"first_name": "Jan",
"last_name": "Novák",
},
)
data = res.json()<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://wap-sa.payout.one/api/v1/verifications");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
"iban" => "CZ6508000000192000145399",
"first_name" => "Jan",
"last_name" => "Nov\u00e1k"
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer " . getenv("PAYOUT_TOKEN"), "Content-Type: application/json"]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);{
"id": "3f1c9a52-7d4e-4b8a-9c21-5e6f7a8b9c0d",
"redirect_url": "https://wap-sa.payout.one/providers/forward/Xk7pQ2",
"status": "initialized"
}Request body
IBAN of the account to verify the user with
User's first name, compared with the names of the account owners
User's last name, compared with the names of the account owners
Integration name from List integrations, for IBANs whose bank cannot be recognised from the IBAN alone
Response 200
Verification id
URL to send the user to. There they log in to their bank and grant access to the account, which is what the verification checks
Result of the verification
initializedCreated, the user has not finished authorizing access at the bank yetverified_accessThe user accessed the account, but the bank does not provide owner namesverified_ownershipThe user accessed the account and an owner's name matchesfirst_nameandlast_nameunverified_accessThe user failed to provide credentials to access the accountunverified_ownershipThe user accessed the account, but no owner's name matchesfirst_nameandlast_nameerrorCommunication with the bank failed
Other responses
Invalid request body (INVALID_INPUT with xpath)
Example
{
"tppMessages": [
{
"category": "ERROR",
"code": "INVALID_INPUT",
"text": "Invalid IBAN format",
"xpath": "/provider/iban"
}
]
}Missing, invalid or expired access token, or missing scope (UNAUTHORIZED)
Example
{
"tppMessages": [
{
"category": "ERROR",
"code": "UNAUTHORIZED",
"text": "Missing or insuficient authorization"
}
]
}Retrieves the result of a verification created by your application.
curl -X GET 'https://wap-sa.payout.one/api/v1/verifications/3f1c9a52-7d4e-4b8a-9c21-5e6f7a8b9c0d' \
-H "Authorization: Bearer $TOKEN"const res = await fetch("https://wap-sa.payout.one/api/v1/verifications/3f1c9a52-7d4e-4b8a-9c21-5e6f7a8b9c0d", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.PAYOUT_TOKEN}`,
},
});
const data = await res.json();import os, requests
res = requests.get(
"https://wap-sa.payout.one/api/v1/verifications/3f1c9a52-7d4e-4b8a-9c21-5e6f7a8b9c0d",
headers={"Authorization": f"Bearer {os.environ['PAYOUT_TOKEN']}"},
)
data = res.json()<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://wap-sa.payout.one/api/v1/verifications/3f1c9a52-7d4e-4b8a-9c21-5e6f7a8b9c0d");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer " . getenv("PAYOUT_TOKEN")]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);{
"status": "initialized"
}Parameters
Verification id returned by Create verification
Response 200
Result of the verification
initializedCreated, the user has not finished authorizing access at the bank yetverified_accessThe user accessed the account, but the bank does not provide owner namesverified_ownershipThe user accessed the account and an owner's name matchesfirst_nameandlast_nameunverified_accessThe user failed to provide credentials to access the accountunverified_ownershipThe user accessed the account, but no owner's name matchesfirst_nameandlast_nameerrorCommunication with the bank failed
Other responses
Unknown verification, or one created by another application (UNSUPPORTED_BANK)
Example
{
"tppMessages": [
{
"category": "ERROR",
"code": "UNSUPPORTED_BANK",
"text": "Unsupported bank"
}
]
}Missing, invalid or expired access token, or missing scope (UNAUTHORIZED)
Example
{
"tppMessages": [
{
"category": "ERROR",
"code": "UNAUTHORIZED",
"text": "Missing or insuficient authorization"
}
]
}Lists the banks Banklink integrates with and what each of them supports.
curl -X GET 'https://wap-sa.payout.one/api/v1/integrations' \
-H "Authorization: Bearer $TOKEN"const res = await fetch("https://wap-sa.payout.one/api/v1/integrations", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.PAYOUT_TOKEN}`,
},
});
const data = await res.json();import os, requests
res = requests.get(
"https://wap-sa.payout.one/api/v1/integrations",
headers={"Authorization": f"Bearer {os.environ['PAYOUT_TOKEN']}"},
)
data = res.json()<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://wap-sa.payout.one/api/v1/integrations");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer " . getenv("PAYOUT_TOKEN")]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);[
{
"name": "payout",
"aisp": true,
"pisp": true,
"supported_payment_methods": [
"sepa"
]
},
{
"name": "tatrabanka",
"aisp": true,
"pisp": true,
"supported_payment_methods": [
"sepa",
"sepa_ipay"
]
}
]Response 200 · array
Integration name. Use it as bank in account requests and as integration in Initiate payment
Whether the integration supports account information
Whether the integration supports payment initiation
Payment methods for Initiate payment. Present only when pisp is true
sepaSEPA credit transfer, payment productsepa-credit-transferssepa_ipayInstant SEPA credit transfer, payment productinstant-sepa-credit-transfers
Other responses
Missing, invalid or expired access token, or missing scope (UNAUTHORIZED)
Example
{
"tppMessages": [
{
"category": "ERROR",
"code": "UNAUTHORIZED",
"text": "Missing or insuficient authorization"
}
]
}- Need help? Contact support.
- Questions? Contact sales.
- Service status? status.payout.one.
- LLM? Read llms.txt.