bankapi
io.token.proto.bankapi /external/src/main/proto/bankapi/bankapi.proto
syntax = "proto3";
package io.token.proto.bankapi;
import "google/api/annotations.proto";
import "account.proto";
import "transfer.proto";
import "consent.proto";
import "money.proto";
import "transaction.proto";
import "transferinstructions.proto";
import "notification.proto";
import "subscriber.proto";
import "banklink.proto";
import "providerspecific.proto";
import "token.proto";
import "extensions/field.proto";
import "extensions/method.proto";
////////////////////////////////////////////////////////////////////////////////////////////////////
// Shared objects
//
enum StatusCode {
INVALID_STATUS = 0; // invalid status, reserved
PROCESSING = 1; // transaction is being processed
SUCCESS = 2; // transaction succeeded
FAILURE_CANCELED = 3; // transaction has been canceled, rolled back
FAILURE_INSUFFICIENT_FUNDS = 4; // the transaction failed due to insufficient funds
FAILURE_INVALID_CURRENCY = 5; // the transaction failed due to currency mismatch
FAILURE_PERMISSION_DENIED = 6; // the transaction failed due to access violation
FAILURE_QUOTE_EXPIRED = 7; // the transaction failed because the quote has expired
FAILURE_INVALID_AMOUNT = 8; // the transaction failed due to invalid amount
FAILURE_INVALID_QUOTE = 9; // the transaction failed due to invalid quote (wrong fx rate)
FAILURE_EXPIRED = 10; // the transaction failed to complete within alotted time
FAILURE_GENERIC = 11; // the transaction has failed due to other reasons
FAILURE_ACCOUNT_NOT_FOUND = 12; // the account is not found
FAILURE_TRANSACTION_NOT_FOUND = 13; // the transaction has failed due to other reasons
FAILURE_UNSUPPORTED_DESTINATION = 14; // the transaction failed because bank does not support requested destination
FAILURE_UNSUPPORTED_FREQUENCY = 17; // the standing order failed because bank does not support requested frequency
FAILURE_DECLINED = 18; // the transaction failed because bank has declined
SENT = 15; // legacy transfers only: the transaction has been sent but has not been acknowledged by the bank
INITIATED = 16; // not recommended: the transaction has been initiated but the result is unknown, this may be the final status and may not get updated later
}
// Simplified transaction object used in bulk transfer lookup.
message BulkTransaction {
string ref_id = 1;
string transaction_id = 2;
io.token.proto.common.transaction.TransactionStatus status = 3;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Account API types
//
message GetTransactionRequest {
string transaction_id = 1;
io.token.proto.common.account.BankAccount account = 2;
string consent_id = 3;
}
message GetTransactionResponse {
io.token.proto.common.transaction.Transaction transaction = 1;
}
message GetTransactionsRequest {
io.token.proto.common.account.BankAccount account = 1;
int32 integer_offset = 2 [deprecated=true]; // use offset instead
int32 limit = 3;
string offset = 4;
// Optional lower bound for a transaction's booking date as returned by the bank, in the format 'YYYY-MM-DD' (e.g. '2016-01-01').
// If specified, then only transactions whose bank booking date is equal to or later than the given date will be regarded.
string start_date = 5;
// Optional upper bound for a transaction's booking date as returned by the bank (= original booking date), in the format 'YYYY-MM-DD' (e.g. '2016-01-01').
// If specified, then only transactions whose bank booking date is equal to or earlier than the given date will be regarded.
string end_date = 6;
string consent_id = 7;
}
message GetTransactionsResponse {
repeated io.token.proto.common.transaction.Transaction transactions = 1;
string offset = 2;
}
message GetStandingOrderRequest {
io.token.proto.common.account.BankAccount account = 1;
string standing_order_id = 2;
string consent_id = 3;
}
message GetStandingOrderResponse {
io.token.proto.common.transaction.StandingOrder standing_order = 1;
}
message GetStandingOrdersRequest {
io.token.proto.common.account.BankAccount account = 1;
int32 limit = 2;
string offset = 3;
string consent_id = 4;
}
message GetStandingOrdersResponse {
repeated io.token.proto.common.transaction.StandingOrder standing_orders = 1;
string offset = 2;
}
message GetBalanceRequest {
io.token.proto.common.account.BankAccount account = 1;
string consent_id = 2;
}
message GetBalanceResponse {
io.token.proto.common.money.Money current = 1;
io.token.proto.common.money.Money available = 2;
int64 updated_at_ms = 3;
repeated io.token.proto.common.transaction.Balance.TypedBalance other_balances = 4; // optional
}
message GetCustomerDataRequest {
io.token.proto.common.account.BankAccount account = 1;
string consent_id = 2;
}
message GetCustomerDataResponse {
io.token.proto.common.transferinstructions.CustomerData customer_data = 1;
StatusCode status = 2;
string status_description = 3;
}
message ResolveTransferDestinationRequest {
option deprecated = true;
io.token.proto.common.account.BankAccount account = 1;
}
message ResolveTransferDestinationResponse {
option deprecated = true;
repeated io.token.proto.common.account.BankAccount destinations = 1 [deprecated=true];
repeated io.token.proto.common.transferinstructions.TransferEndpoint endpoints = 2 [deprecated=true];
repeated io.token.proto.common.transferinstructions.TransferDestination transfer_destinations = 3;
}
message ResolveTransferDestinationsRequest {
option deprecated = true;
io.token.proto.common.account.BankAccount account = 1;
string consent_id = 2;
}
message ResolveTransferDestinationsResponse {
option deprecated = true;
repeated io.token.proto.common.transferinstructions.TransferDestination destinations = 3;
}
message GetAccountDetailsRequest {
option deprecated = true;
io.token.proto.common.account.BankAccount account = 1;
}
message GetAccountDetailsResponse {
option deprecated = true;
io.token.proto.common.account.AccountDetails account_details = 1;
}
message GetAccountRequest {
io.token.proto.common.account.BankAccount account = 1;
string consent_id = 2;
}
message GetAccountResponse {
Account account = 1;
message Account {
string name = 1 [(io.token.proto.extensions.field.redact) = true]; // human-friendly name. E.g., "Checking account with number ...1234"
io.token.proto.common.account.AccountFeatures account_features = 2; // features account supports
io.token.proto.common.account.AccountDetails account_details = 3; // optional additional account details
}
}
message ConfirmFundsRequest {
io.token.proto.common.account.BankAccount account = 1;
io.token.proto.common.money.Money money = 2;
string consent_id = 3;
}
message ConfirmFundsResponse {
bool funds_available = 1;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Account linking API types
//
message GetBankAuthorizationRequest {
string access_token = 1;
}
message GetBankAuthorizationResponse {
io.token.proto.banklink.BankAuthorization bank_authorization = 1;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Notification API types
//
message NotifyRequest {
io.token.proto.common.notification.Notification notification = 1;
io.token.proto.common.subscriber.Subscriber subscriber = 2;
}
message NotifyResponse {}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Storage API types
//
message SetValueRequest {
enum ContentCategory {
INVALID = 0;
ACCOUNT_INFO = 1;
TOKEN_INFO = 2;
}
string key = 1;
bytes value = 2 [(io.token.proto.extensions.field.redact) = true];
ContentCategory category = 3;
}
message SetValueResponse {
bytes previous = 1 [(io.token.proto.extensions.field.redact) = true];
}
message GetValueRequest {
string key = 1;
}
message GetValueResponse {
bytes value = 1 [(io.token.proto.extensions.field.redact) = true];
}
message RemoveValueRequest {
string key = 1;
}
message RemoveValueResponse {
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Transfer API types
//
message TransferRequest {
string transfer_id = 1;
io.token.proto.common.money.Money requested_amount = 2 [deprecated = true];
io.token.proto.common.money.Money transaction_amount = 3;
io.token.proto.common.account.BankAccount source = 4 [deprecated=true];
repeated io.token.proto.common.transferinstructions.TransferEndpoint destinations = 5 [deprecated=true];
string description = 9; // optional transfer description
string token_ref_id = 10; // reference ID of the token, set by the initiator
string transfer_ref_id = 11;
io.token.proto.common.transferinstructions.TransferInstructions.Metadata metadata = 12 [deprecated=true];
string token_initiator_id = 13; // ID of member who requested token creation
repeated io.token.proto.common.transferinstructions.TransferDestination transfer_destinations = 14 [deprecated=true];
string execution_date = 15; // execution date of the transfer
bool confirm_funds = 16;
io.token.proto.common.transferinstructions.TransferInstructions transfer_instructions = 17;
string consent_id = 18;
string remittance_reference = 19 [(io.token.proto.extensions.field.hash) = true];
bool return_refund_account = 20; // Returns a refundable account.
}
message TransferResponse {
string transaction_id = 1;
StatusCode status = 2;
string status_description = 3;
io.token.proto.common.transferinstructions.TransferEndpoint source = 4;
io.token.proto.common.providerspecific.ProviderTransferDetails provider_details = 5; // optional if there are provider details
io.token.proto.common.account.Refund refund = 7; // Optional: a refund object will be returned
bool continue_polling = 8; // force status polling despite the status.
io.token.proto.common.transfer.Transfer.ScaStatus sca_status = 9; // Optional: SCA Status object will be returned
}
message CreateStandingOrderRequest {
string token_submission_id = 1; // Token reference for the standing order submission
string ref_id = 2; // reference ID of the standing order, set by the initiator
string token_initiator_id = 3; // ID of member who requested token creation
io.token.proto.common.token.StandingOrderBody payload = 4;
io.token.proto.common.account.BankAccount source = 5 [deprecated=true];
repeated io.token.proto.common.transferinstructions.TransferDestination transfer_destinations = 6 [deprecated=true];
string description = 7; // optional transfer description
io.token.proto.common.transferinstructions.TransferInstructions.Metadata metadata = 8 [deprecated=true];
io.token.proto.common.transferinstructions.TransferInstructions transfer_instructions = 9;
string consent_id = 10;
bool return_refund_account = 11; // Returns a refundable account.
}
message CreateStandingOrderResponse {
string standing_order_id = 1;
StatusCode status = 2;
string status_description = 3;
io.token.proto.common.providerspecific.ProviderStandingOrderSubmissionDetails provider_details = 4; // optional if there are provider details
io.token.proto.common.account.Refund refund = 6; // Optional: a refund object will be returned
}
message CreateBulkTransferRequest {
string token_bulk_transfer_id = 1; // Token reference for the bulk transfer
string ref_id = 2;
string token_initiator_id = 3; // ID of member who requested token creation
io.token.proto.common.token.BulkTransferBody payload = 4;
io.token.proto.common.account.BankAccount source = 5 [deprecated=true]; // resolved source
string description = 6; // optional transfer description
io.token.proto.common.transferinstructions.TransferEndpoint source_account = 7;
string consent_id = 8;
}
message CreateBulkTransferResponse {
string bulk_transfer_id = 1;
StatusCode status = 2;
repeated BulkTransaction transactions = 3;
}
message BatchTransferRequest {
repeated TransferRequest transfers = 1;
}
message BatchTransferResponse {
TransferResponse transfer_response = 1;
}
message GetTransferStatusRequest {
string transfer_id = 1;
string consent_id = 2;
io.token.proto.common.transfer.Transfer.ScaStatus sca_status = 3;
}
message GetTransferStatusResponse {
io.token.proto.common.transaction.TransactionStatus status = 1;
string raw_status = 2; // optional if there is a raw status
string status_reason_information = 3; // Optional: provides detailed information on the status reason
bool continue_polling = 4; // force status polling despite the status.
io.token.proto.common.transfer.Transfer.ScaStatus sca_status = 5;
}
message GetBulkTransferRequest {
string bulk_transfer_id = 1;
}
message GetBulkTransferResponse {
repeated BulkTransaction transactions = 1;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Account Management API types
//
message OnAccountLinkedRequest {
io.token.proto.common.account.BankAccount account = 1;
string account_id = 2;
}
message OnAccountLinkedResponse {}
message OnAccountUnlinkedRequest {
io.token.proto.common.account.BankAccount account = 1;
string account_id = 2;
}
message OnAccountUnlinkedResponse {}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Consent Management API types
//
message OnConsentCreatedRequest {
io.token.proto.common.consent.Consent consent = 1;
}
message OnConsentCreatedResponse {}
message OnConsentRevokedRequest {
string token_id = 1;
}
message OnConsentRevokedResponse {}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Health Check API types
//
message HealthCheckRequest {
string bank_id = 1;
}
message HealthCheckResponse {
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Account API
//
service AccountService {
rpc GetBalance (GetBalanceRequest) returns (GetBalanceResponse) {
option (google.api.http) = {
get: "/accounts/balance?account.swift.bic={account.swift.bic}&account.swift.account={account.swift.account}&account.sepa.iban={account.sepa.iban}&account.sepa.bic={account.sepa.bic}&account.ach.routing={account.ach.routing}&account.ach.account={account.ach.account}&account.faster_payments.sort_code={account.faster_payments.sort_code}&account.faster_payments.account_number={account.faster_payments.account_number}&account.custom.bank_id={account.custom.bank_id}&account.custom.payload={account.custom.payload}"
};
}
rpc GetTransaction (GetTransactionRequest) returns (GetTransactionResponse) {
option (google.api.http) = {
get: "/accounts/transactions?transaction_id={transaction_id}&account.swift.bic={account.swift.bic}&account.swift.account={account.swift.account}&account.sepa.iban={account.sepa.iban}&account.sepa.bic={account.sepa.bic}&account.ach.routing={account.ach.routing}&account.ach.account={account.ach.account}&account.faster_payments.sort_code={account.faster_payments.sort_code}&account.faster_payments.account_number={account.faster_payments.account_number}&account.custom.bank_id={account.custom.bank_id}&account.custom.payload={account.custom.payload}"
};
}
rpc GetTransactions (GetTransactionsRequest) returns (GetTransactionsResponse) {
option (google.api.http) = {
get: "/accounts/transactions?offset={offset}&limit={limit}&account.swift.bic={account.swift.bic}&account.swift.account={account.swift.account}&account.sepa.iban={account.sepa.iban}&account.sepa.bic={account.sepa.bic}&account.ach.routing={account.ach.routing}&account.ach.account={account.ach.account}&account.faster_payments.sort_code={account.faster_payments.sort_code}&account.faster_payments.account_number={account.faster_payments.account_number}&account.custom.bank_id={account.custom.bank_id}&account.custom.payload={account.custom.payload}"
};
}
rpc GetStandingOrder (GetStandingOrderRequest) returns (GetStandingOrderResponse) {
option (google.api.http) = {
get: "/account/standing-orders/{standing_order_id}"
};
}
rpc GetStandingOrders (GetStandingOrdersRequest) returns (GetStandingOrdersResponse) {
option (google.api.http) = {
get: "/account/standing-orders"
};
}
rpc GetCustomerData(GetCustomerDataRequest) returns (GetCustomerDataResponse) {
option deprecated = true;
option (google.api.http) = {
get: "/accounts/{account.custom.bank_id}/{account.custom.payload}/customer-data"
};
}
rpc ResolveTransferDestination(ResolveTransferDestinationRequest) returns (ResolveTransferDestinationResponse) {
option deprecated = true; // Use ResolveTransferDestinations instead
option (google.api.http) = {
get: "/accounts/transfer-destination?account.swift.bic={account.swift.bic}&account.swift.account={account.swift.account}&account.sepa.iban={account.sepa.iban}&account.sepa.bic={account.sepa.bic}&account.ach.routing={account.ach.routing}&account.ach.account={account.ach.account}&account.faster_payments.sort_code={account.faster_payments.sort_code}&account.faster_payments.account_number={account.faster_payments.account_number}&account.custom.bank_id={account.custom.bank_id}&account.custom.payload={account.custom.payload}"
};
}
rpc ResolveTransferDestinations(ResolveTransferDestinationsRequest) returns (ResolveTransferDestinationsResponse) {
// AccountIdentifier is now populated in Account.AccountDetails - no need to resolve it anymore;
// linked accounts are no longer used as transfer destinations (were used in p2p flow before)
option deprecated = true;
option (google.api.http) = {
get: "/accounts/transfer-destinations?account.swift.bic={account.swift.bic}&account.swift.account={account.swift.account}&account.sepa.iban={account.sepa.iban}&account.sepa.bic={account.sepa.bic}&account.ach.routing={account.ach.routing}&account.ach.account={account.ach.account}&account.faster_payments.sort_code={account.faster_payments.sort_code}&account.faster_payments.account_number={account.faster_payments.account_number}&account.custom.bank_id={account.custom.bank_id}&account.custom.payload={account.custom.payload}"
};
}
rpc GetAccountDetails(GetAccountDetailsRequest) returns (GetAccountDetailsResponse) {
option deprecated = true; // Use GetAccount instead
option (google.api.http) = {
get: "/accounts/account-details?account.swift.bic={account.swift.bic}&account.swift.account={account.swift.account}&account.sepa.iban={account.sepa.iban}&account.sepa.bic={account.sepa.bic}&account.ach.routing={account.ach.routing}&account.ach.account={account.ach.account}&account.faster_payments.sort_code={account.faster_payments.sort_code}&account.faster_payments.account_number={account.faster_payments.account_number}&account.custom.bank_id={account.custom.bank_id}&account.custom.payload={account.custom.payload}"
};
}
rpc GetAccount(GetAccountRequest) returns (GetAccountResponse) {
option (google.api.http) = {
get: "/accounts?account.swift.bic={account.swift.bic}&account.swift.account={account.swift.account}&account.sepa.iban={account.sepa.iban}&account.sepa.bic={account.sepa.bic}&account.ach.routing={account.ach.routing}&account.ach.account={account.ach.account}&account.faster_payments.sort_code={account.faster_payments.sort_code}&account.faster_payments.account_number={account.faster_payments.account_number}&account.custom.bank_id={account.custom.bank_id}&account.custom.payload={account.custom.payload}"
};
}
rpc ConfirmFunds(ConfirmFundsRequest) returns (ConfirmFundsResponse) {
option (google.api.http) = {
get: "/accounts/funds-confirmation?money.currency={money.currency}&money.value={money.value}&account.swift.bic={account.swift.bic}&account.swift.account={account.swift.account}&account.sepa.iban={account.sepa.iban}&account.sepa.bic={account.sepa.bic}&account.ach.routing={account.ach.routing}&account.ach.account={account.ach.account}&account.faster_payments.sort_code={account.faster_payments.sort_code}&account.faster_payments.account_number={account.faster_payments.account_number}&account.custom.bank_id={account.custom.bank_id}&account.custom.payload={account.custom.payload}"
};
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Account Linking API
//
service AccountLinkingService {
rpc GetBankAuthorization (GetBankAuthorizationRequest) returns (GetBankAuthorizationResponse) {
option (google.api.http) = {
get: "/bank-authorization?access_token={access_token}"
};
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Notification API
//
service NotificationService {
rpc Notify (NotifyRequest) returns (NotifyResponse) {
option (google.api.http) = {
post: "/notifications"
body: "*"
};
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Storage API
//
service StorageService {
rpc SetValue (SetValueRequest) returns (SetValueResponse) {
option (google.api.http) = {
put: "/storage/{key}"
};
}
rpc GetValue (GetValueRequest) returns (GetValueResponse) {
option (google.api.http) = {
get: "/storage/{key}"
};
}
rpc RemoveValue (RemoveValueRequest) returns (RemoveValueResponse) {
option (google.api.http) = {
delete: "/storage/{key}"
};
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Transfer API
//
service TransferService {
rpc Transfer (TransferRequest) returns (TransferResponse) {
option (google.api.http) = {
post: "/transfers"
body: "*"
};
}
rpc CreateStandingOrder (CreateStandingOrderRequest) returns (CreateStandingOrderResponse) {
option (google.api.http) = {
post: "/standing-orders"
body: "*"
};
}
rpc CreateBulkTransfer (CreateBulkTransferRequest) returns (CreateBulkTransferResponse) {
option (google.api.http) = {
post: "/bulk-transfers"
body: "*"
};
}
rpc GetBulkTransfer (GetBulkTransferRequest) returns (GetBulkTransferResponse) {
option (google.api.http) = {
get: "/bulk-transfers/{bulk_transfer_id}"
};
}
rpc BatchTransfer (BatchTransferRequest) returns (BatchTransferResponse) {
option (google.api.http) = {
post: "/batch/transfers"
body: "*"
};
}
rpc GetTransferStatus (GetTransferStatusRequest) returns (GetTransferStatusResponse) {
option (google.api.http) = {
get: "/transfers/{transfer_id}/status"
};
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Account Management API
//
service AccountManagementService {
rpc OnAccountLinked (OnAccountLinkedRequest) returns (OnAccountLinkedResponse) {
option (google.api.http) = {
put: "/accounts/linked"
};
}
rpc OnAccountUnlinked (OnAccountUnlinkedRequest) returns (OnAccountUnlinkedResponse) {
option (google.api.http) = {
put: "/accounts/unlinked"
};
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Consent Management API
//
service ConsentManagementService {
rpc OnConsentCreated (OnConsentCreatedRequest) returns (OnConsentCreatedResponse) {
option (google.api.http) = {
put: "/consent/created"
};
}
rpc OnConsentRevoked (OnConsentRevokedRequest) returns (OnConsentRevokedResponse) {
option (google.api.http) = {
put: "/consent/revoked"
};
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Health Check API
//
service HealthCheckService {
rpc HealthCheck (HealthCheckRequest) returns (HealthCheckResponse) {
option (google.api.http) = {
get: "/health-check?bank_id={bank_id}"
};
}
}