gateway

io.token.proto.gateway external/src/main/proto/gateway/auth.proto


syntax = "proto3";
package io.token.proto.gateway;
option csharp_namespace = "Tokenio.Proto.Gateway";

import "extensions/field.proto";

// The payload is signed by the client for every request.

// For HTTP communication, the payload consists of some of the HTTP request fields.
// We convert the proto into canonical JSON and sign it.
// https://github.com/tokenio/sdk-js/blob/master/src/http/AuthHeader.js
message HttpAuthPayload {
  string method = 1;       // HTTP method, e.g., "POST"
  string uri_host = 2;     // host, e.g., "api.sandbox.token.io"
  string uri_path = 3;     // path part of URL, e.g., "/aliases"
  string query_string = 4 [(io.token.proto.extensions.field.redact) = true]; // query part of URL, e.g., "tokenId=tt:AMg...bXg5ny:5zKcENpV&offset=null&limit=100"
  string request_body = 5 [(io.token.proto.extensions.field.redact) = true]; // request body, e.g., "{\"memberId\":\"m:Y9GkD...LdEn:5zKtXEAq\"}"
  int64 created_at_ms = 6; // creation time, e.g., "1515710877090"
}

// For gRPC communication, the payload is a serialized protbuf and creation time.
// https://github.com/tokenio/sdk-java/blob/master/lib/src/main/java/io/token/rpc/ClientAuthenticator.java
message GrpcAuthPayload {
  bytes request = 1 [(io.token.proto.extensions.field.redact) = true];
  int64 created_at_ms = 6;
}

io.token.proto.gateway external/src/main/proto/gateway/gateway.proto


syntax = "proto3";
package io.token.proto.gateway;
option csharp_namespace = "Tokenio.Proto.Gateway";

import "google/api/annotations.proto";
import "grpcbridge/swagger/openapi_v2.proto";

import "account.proto";
import "address.proto";
import "bankinfo.proto";
import "banklink.proto";
import "blob.proto";
import "consent.proto";
import "eidas.proto";
import "alias.proto";
import "member.proto";
import "money.proto";
import "notification.proto";
import "providerspecific.proto";
import "security.proto";
import "submission.proto";
import "subscriber.proto";
import "token.proto";
import "transaction.proto";
import "transfer.proto";
import "transferinstructions.proto";
import "webhook.proto";
import "tsp/bankconfig.proto";
import "restriction.proto";
import "v2/common.proto";
import "v2/bank.proto";
import "v2/paging.proto";
import "v2/payout.proto";
import "v2/openbanking/payment.proto";
import "v2/openbanking/vrp.proto";
import "extensions/field.proto";
import "extensions/service.proto";
import "extensions/method.proto";
import "extensions/message.proto";
import "virtualaccount.proto";

message EmptyResponse {
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Paging details.
//
message Page {
  string offset = 1;      // Opaque base-64 encoded offset for the client to roundtrip.
  int32 limit = 2;        // Max number of records to return.
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Member registration, key and alias management.
//

message CreateMemberRequest {
  string nonce = 1; // random string; used only to de-duplicate requests.
  io.token.proto.common.member.CreateMemberType member_type = 2;
  string token_request_id = 3; // Optional token request ID, if set the member will be claimed by the TPP initiating the token request.
  string partner_id = 4;
  string realm_id = 5;
}

message CreateMemberResponse {
  string member_id = 1; // newly-created member ID.
}

message RegisterWithEidasRequest {
  io.token.proto.common.eidas.RegisterWithEidasPayload payload = 1; // payload with a certificate
  string signature = 2; // signature of payload signed with the private key of the certificate
}

message RegisterWithEidasResponse {
  string member_id = 1; // ID of a newly-created or already registered with this bank member
  string key_id = 2; // ID of the key that has been added
  string verification_id = 3; // ID of the verification for this certificate
}

message UpdateMemberRequest {
  io.token.proto.common.member.MemberUpdate update = 1;                       // changes
  io.token.proto.common.security.Signature update_signature = 2;              // signature of update field
  repeated io.token.proto.common.member.MemberOperationMetadata metadata = 3; // extra (unsigned) data for aliases
}

message UpdateMemberResponse {
  io.token.proto.common.member.Member member = 1; // updated member structure
}

message GetMemberRequest {
  string member_id = 1; // ID of member to get
}

message GetMemberResponse {
  io.token.proto.common.member.Member member = 1; // member structure
}

message ResolveAliasRequest {
  io.token.proto.common.alias.Alias alias = 1; // alias to resolve

  // for backwards compatibility with older JS clients TODO(RD-2738) remove
  io.token.proto.common.alias.Alias.Type type = 2 [deprecated = true];                    // For example, EMAIL.
  string value = 3 [(io.token.proto.extensions.field.redact) = true, deprecated = true]; // For example, "sandy@example.com"
  string realm  = 4 [deprecated = true];                              // For example, "token"
}

message ResolveAliasResponse {
  io.token.proto.common.token.TokenMember member = 1; // member that owns alias, if any
}

message GetAliasesRequest {}

message GetAliasesResponse {
  repeated io.token.proto.common.alias.Alias aliases = 1;            // verified aliases
  repeated io.token.proto.common.alias.Alias unverified_aliases = 2; // unverified aliases
}

message CompleteVerificationRequest {
  string verification_id = 1; // verification ID
  string code = 2;            // verification code
}

message CompleteVerificationResponse {
  io.token.proto.common.alias.VerificationStatus status = 1;
}

message RetryVerificationRequest {
  string member_id = 1;                        // member ID
  io.token.proto.common.alias.Alias alias = 2; // alias
}

message RetryVerificationResponse {
  string verification_id = 1; // verification ID
}

message GetPairedDevicesRequest {
  option deprecated = true;
}

message GetPairedDevicesResponse {
  option deprecated = true;
  repeated io.token.proto.common.member.Device devices = 1; // linked device info
}

message DeleteMemberRequest {}

message DeleteMemberResponse {}

message NormalizeAliasRequest {
  io.token.proto.common.alias.Alias alias = 1;
}

message NormalizeAliasResponse {
  io.token.proto.common.alias.Alias alias = 1;
}

message SetAppCallbackUrlRequest {
  string app_callback_url = 1; // the custom app call back url
}

message SetAppCallbackUrlResponse {}

message GetRedirectUrlsRequest {}

message GetRedirectUrlsResponse {
  repeated string redirect_urls = 1;
}

message AddRedirectUrlsRequest {
  repeated string redirect_urls = 1;
}

message AddRedirectUrlsResponse {}

message RemoveRedirectUrlsRequest {
  repeated string redirect_urls = 1;
}

message RemoveRedirectUrlsResponse {}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Member account recovery.
//

message BeginRecoveryRequest {
  io.token.proto.common.alias.Alias alias = 1; // alias of member to recover
}

message BeginRecoveryResponse {
  string verification_id = 1; // id to use in later recovery steps
}

message CompleteRecoveryRequest {
  string verification_id = 1;                 // verification id
  string code = 2;                            // verification code (perhaps sent to alias email)
  io.token.proto.common.security.Key key = 3; // new privileged key to use
}

message CompleteRecoveryResponse {
  io.token.proto.common.member.MemberRecoveryOperation recovery_entry = 1;
  io.token.proto.common.alias.VerificationStatus status = 2;
}

message VerifyAliasRequest {
  string verification_id = 1; // verification id
  string code = 2;            // verification code (perhaps sent to alias email)
}

message VerifyAliasResponse {}

message VerifyEidasRequest {
  io.token.proto.common.eidas.VerifyEidasPayload payload = 1; // payload with certificate
  string signature = 2; // signature of payload signed with the private key of the certificate
}

message VerifyEidasResponse {
  io.token.proto.common.eidas.KonsentusVerificationStatus status = 1 [deprecated = true];
  string status_details = 2;
  string verification_id = 3;
  io.token.proto.common.eidas.EidasVerificationStatus eidas_status = 4;
}

message GetEidasVerificationStatusRequest {
  string verification_id = 1;
}

message GetEidasVerificationStatusResponse {
  string alias_value = 1;
  string certificate = 2;
  io.token.proto.common.eidas.KonsentusVerificationStatus status = 3 [deprecated = true];
  string status_details = 4;
  io.token.proto.common.eidas.EidasVerificationStatus eidas_status = 5;
}

message GetEidasCertificateStatusRequest {}

message GetEidasCertificateStatusResponse {
  io.token.proto.common.eidas.EidasCertificateStatus status = 1;
  string certificate = 2;
}

message RecoverEidasRequest {
  io.token.proto.common.eidas.EidasRecoveryPayload payload = 1; // payload with certificate
  string signature = 2; // signature of payload signed with the private key of the certificate
}

message RecoverEidasResponse {
  io.token.proto.common.member.MemberRecoveryOperation recovery_entry = 1;
}

message GetDefaultAgentRequest {}

message GetDefaultAgentResponse {
  string member_id = 1; // ID of the "normal consumer mode" recovery agent
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Member PII/addresses/preferences management.
//

message AddAddressRequest {
  string name = 1;                                                // display name, such as "Office"
  io.token.proto.common.address.Address address = 2;              // shipping address
  io.token.proto.common.security.Signature address_signature = 3; // signature
}

message AddAddressResponse {
  io.token.proto.common.member.AddressRecord address = 1; // new address
}

message GetAddressRequest {
  string address_id = 1; // address ID
}

message GetAddressResponse {
  io.token.proto.common.member.AddressRecord address = 1; // address
}

message GetAddressesRequest {}

message GetAddressesResponse {
  repeated io.token.proto.common.member.AddressRecord addresses = 1; // list of addresses
}

message DeleteAddressRequest {
  string address_id = 1; // address ID
}

message DeleteAddressResponse {}

message SetProfileRequest {
  option deprecated = true; // DEPRECATED; use SetProfileName
  io.token.proto.common.member.Profile profile = 1; // new profile, picture fields ignored
}

message SetProfileResponse {
  option deprecated = true;
  io.token.proto.common.member.Profile profile = 1; // updated profile
}

message GetProfileRequest {
  option deprecated = true; //DEPRECATED; use GetProfileName endpoint.
  string member_id = 1; // member ID
}

message GetProfileResponse {
  option deprecated = true;
  io.token.proto.common.member.Profile profile = 1; // display information
}

message SetProfileNameRequest {
  string profile_name = 1;
}

message SetProfileNameResponse {}

message GetProfileNameRequest {
  string member_id = 1; // member ID
}

message GetProfileNameResponse {
  string profile_name = 1;
}

message SetProfilePictureRequest {
  io.token.proto.common.blob.Blob.Payload payload = 1; // image "file"
}

message SetProfilePictureResponse {
}

message GetProfilePictureRequest {
  string member_id = 1;                                     // member ID
  io.token.proto.common.member.ProfilePictureSize size = 2; // ORIGINAL/SMALL/MEDIUM/LARGE
}

message GetProfilePictureResponse {
  io.token.proto.common.blob.Blob blob = 1; // blob with image "file"
}

message SetReceiptContactRequest {
  string member_id = 1;
  io.token.proto.common.member.ReceiptContact contact = 2;
}

message SetReceiptContactResponse {
}

message GetReceiptContactRequest {
  string member_id = 1;
}

message GetReceiptContactResponse {
  io.token.proto.common.member.ReceiptContact contact = 1;
}

message CreateCustomizationRequest {
  io.token.proto.common.blob.Blob.Payload logo = 1;
  map<string, string> colors = 2;
  string consent_text = 3;
  string name = 4;
  string app_name = 5;
}

message CreateCustomizationResponse {
  string customization_id = 1;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Notification service
//

message SubscribeToNotificationsRequest {
  string handler = 1;                           // Who is sending the notification
  map<string, string> handler_instructions = 2; // Available to handler when sending notifications
}

message SubscribeToNotificationsResponse {
  io.token.proto.common.subscriber.Subscriber subscriber = 1; // Represents one subscription
}

message GetSubscribersRequest {}

message GetSubscribersResponse {
  repeated io.token.proto.common.subscriber.Subscriber subscribers = 1; // notification subscriber info
}

message GetSubscriberRequest {
  string subscriber_id = 1; // ID of notification subscriber to get
}

message GetSubscriberResponse {
  io.token.proto.common.subscriber.Subscriber subscriber = 1; // notification subscriber info
}

message UnsubscribeFromNotificationsRequest {
  string subscriber_id = 1; // ID of notification subscriber to unsubscribe
}

message UnsubscribeFromNotificationsResponse {}

message NotifyRequest {
  io.token.proto.common.alias.Alias alias = 1; // alias of member to notify
  io.token.proto.common.notification.NotifyBody body = 2; // notification details
  string realm = 3; // Deprecated
}

message NotifyResponse {
  io.token.proto.common.notification.NotifyStatus status = 1; // was notification accepted?
}

message GetNotificationsRequest {
  Page page = 1; // offset and limit

  // for backwards compatibility with older JS clients TODO(RD-2738) remove
  string offset = 2 [deprecated = true];
  int32 limit = 3 [deprecated = true];
}

message GetNotificationsResponse {
  repeated io.token.proto.common.notification.Notification notifications = 1; // notification details
  string offset = 2; // offset string to get "next page"
}

message GetNotificationRequest {
  string notification_id = 1; // ID of notification to get
}

message GetNotificationResponse {
  io.token.proto.common.notification.Notification notification = 1; // notification details
}

message RequestTransferRequest {
  io.token.proto.common.token.TokenPayload token_payload = 2; // transfer token payload with some values filled in
}

message RequestTransferResponse {
  io.token.proto.common.notification.NotifyStatus status = 1; // was notification accepted?
}

message TriggerStepUpNotificationRequest {
  oneof step_up_type {
    io.token.proto.common.notification.StepUp token_step_up = 1;                  // ask user to endorse token
    io.token.proto.common.notification.BalanceStepUp balance_step_up = 2;         // ask user to approve get-balance
    io.token.proto.common.notification.TransactionStepUp transaction_step_up = 3; // ask user to approve get-transactions
  }
}

message TriggerStepUpNotificationResponse {
  io.token.proto.common.notification.NotifyStatus status = 1; // was notification accepted?
}

message TriggerCreateAndEndorseTokenNotificationRequest {
  string token_request_id = 1;
  io.token.proto.common.notification.AddKey add_key = 2;      // Optional key to add
  io.token.proto.common.member.ReceiptContact contact = 3;    // Optional receipt contact
}

message TriggerCreateAndEndorseTokenNotificationResponse {
  io.token.proto.common.notification.NotifyStatus status = 1; // was notification accepted?
  string notification_id = 2;
}

message TriggerEndorseAndAddKeyNotificationRequest {
  option deprecated = true;         // Use CreateAndEndorseToken instead
  io.token.proto.common.notification.EndorseAndAddKey endorse_and_add_key = 1;
}

message TriggerEndorseAndAddKeyNotificationResponse {
  option deprecated = true;         // Use CreateAndEndorseToken instead
  io.token.proto.common.notification.NotifyStatus status = 1; // was notification accepted?
  string notification_id = 2;
}

message InvalidateNotificationRequest {
  string notification_id = 1;
}

message InvalidateNotificationResponse {
  io.token.proto.common.notification.NotifyStatus status = 1; // was notification accepted?
}

message UpdateNotificationStatusRequest {
  string notification_id = 1;
  io.token.proto.common.notification.Notification.Status status = 2;
}

message UpdateNotificationStatusResponse {}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Bank account management and information access.
//

message LinkAccountsRequest {
  // authorization, normally from bank web site
  io.token.proto.banklink.BankAuthorization bankAuthorization = 1;
}

message LinkAccountsResponse {
  // basic info about newly-linked accounts
  repeated io.token.proto.common.account.Account accounts = 1;
}

message LinkAccountsOauthRequest {
  // OAuth access token, normally from a bank website
  io.token.proto.banklink.OauthBankAuthorization authorization = 1;
}

message LinkAccountsOauthResponse {
  // basic info about newly-linked accounts
  repeated io.token.proto.common.account.Account accounts = 1;
  io.token.proto.banklink.AccountLinkingStatus status = 2;
}

message UnlinkAccountsRequest {
  repeated string account_ids = 1; // IDs of accounts to unlink
}

message UnlinkAccountsResponse {
}

message GetAccountRequest {
  string account_id = 1; // ID of account to get information about
}

message GetAccountResponse {
  io.token.proto.common.account.Account account = 1; // basic account information
}

message GetAccountsRequest {
}

message GetAccountsResponse {
  repeated io.token.proto.common.account.Account accounts = 1; // basic account information
}

message GetBalanceRequest {
  string account_id = 1;
}

message GetBalanceResponse {
  io.token.proto.common.transaction.Balance balance = 1;
  io.token.proto.common.transaction.RequestStatus status = 2;
}

message GetBalancesRequest {
  repeated string account_id = 1;
}

message GetBalancesResponse {
  repeated GetBalanceResponse response = 1;
}

message GetTransactionRequest {
  string account_id = 1;
  string transaction_id = 2;
}

message GetTransactionResponse {
  io.token.proto.common.transaction.Transaction transaction = 1;
  io.token.proto.common.transaction.RequestStatus status = 2;
}

message GetTransactionsRequest {
  string account_id = 1;
  Page page = 2; // Optional paging settings.

  // for backwards compatibility with older JS clients TODO(RD-2738) remove
  string offset = 3 [deprecated = true];
  int32 limit = 4 [deprecated = true];
  // 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;
}

message GetTransactionsResponse {
  repeated io.token.proto.common.transaction.Transaction transactions = 1; // transaction details
  string offset = 2; // Optional offset state for the client to roundtrip.
  io.token.proto.common.transaction.RequestStatus status = 3;
}

message GetStandingOrderRequest {
  string account_id = 1;
  string standing_order_id = 2;
}

message GetStandingOrderResponse {
  io.token.proto.common.transaction.StandingOrder standing_order = 1;
  io.token.proto.common.transaction.RequestStatus status = 2;
}

message GetStandingOrdersRequest {
  string account_id = 1;
  Page page = 2; // Optional paging settings.
}

message GetStandingOrdersResponse {
  repeated io.token.proto.common.transaction.StandingOrder standing_orders = 1;
  string offset = 2; // Optional offset state for the client to roundtrip.
  io.token.proto.common.transaction.RequestStatus status = 3;
}

message ApplyScaRequest {
  repeated string account_id = 1;
}

message ApplyScaResponse {}

message GetDefaultAccountRequest {
  string member_id = 1; // ID of member; must be same as auth'd member
}

message GetDefaultAccountResponse {
  io.token.proto.common.account.Account account = 1; // default account, if any
}

message SetDefaultAccountRequest {
  string member_id = 1;  // ID of member; must be same as auth'd member
  string account_id = 2; // ID of account to set as default
}

message SetDefaultAccountResponse {
}

message ResolveTransferDestinationsRequest {
  option deprecated = true; // AccountIdentifier is now populated in Account.AccountDetails - no need to resolve it anymore
  string account_id = 1;
}

message ResolveTransferDestinationsResponse {
  option deprecated = true; // AccountIdentifier is now populated in Account.AccountDetails - no need to resolve it anymore
  repeated io.token.proto.common.transferinstructions.TransferEndpoint destinations = 1 [deprecated=true];
  repeated io.token.proto.common.transferinstructions.TransferDestination transfer_destinations = 2;
}

message ConfirmFundsRequest {
  string account_id = 1;
  io.token.proto.common.money.Money amount = 2;
}

message ConfirmFundsResponse {
  bool funds_available = 1;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Blobs
//

message CreateBlobRequest {
  io.token.proto.common.blob.Blob.Payload payload = 1; // "file" information
}

message CreateBlobResponse {
  string blob_id = 1; // ID of new blob
}

message GetBlobRequest {
  string blob_id = 1; // ID of blob to fetch
}

message GetBlobResponse {
  io.token.proto.common.blob.Blob blob = 1; // "file" information
}

message GetTokenBlobRequest {
  string token_id = 1; // ID of token to use for "permission"
  string blob_id = 2;  // ID of blob to fetch
}

message GetTokenBlobResponse {
  io.token.proto.common.blob.Blob blob = 1; // "file" information
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Token Requests
//

message StoreTokenRequestRequest {
  io.token.proto.common.token.TokenRequestPayload request_payload = 5;
  io.token.proto.common.token.TokenRequestOptions request_options = 6;
}

message StoreTokenRequestResponse {
  io.token.proto.common.token.TokenRequest token_request = 1;
}

message RetrieveTokenRequestRequest {
  string request_id = 1;
}

message RetrieveTokenRequestResponse {
  io.token.proto.common.token.TokenRequest token_request = 1;
  io.token.proto.common.member.Customization customization = 2;
  bool hide_consent = 3;
}

message UpdateTokenRequestRequest {
  string request_id = 1;
  io.token.proto.common.token.TokenRequestOptions request_options = 2;
}

message UpdateTokenRequestResponse {
}

message SetTokenRequestMandatoryFieldsRequest {
  string request_id = 1;
  io.token.proto.common.token.TokenRequestPayload request_payload = 2; // token payload with populated mandatory fields
  string bank_id = 3; // bank id to set in the request options, if not yet set
}

message SetTokenRequestMandatoryFieldsResponse {
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Tokens
//

message PrepareTokenRequest {
  io.token.proto.common.token.TokenPayload payload = 1;
  string app_callback_url = 2 [deprecated = true];
}

message PrepareTokenResponse {
  io.token.proto.common.token.TokenPayload resolved_payload = 1;
  io.token.proto.common.token.Policy policy = 2;
}

message CreateTokenRequest {
  io.token.proto.common.token.TokenPayload payload = 1;
  repeated io.token.proto.common.security.Signature signatures = 2;
  string token_request_id = 3; // optional ID of the token request

  // Only useful for HTTP requests
  // specifying type=access in an HTTP request will call CreateAccessToken instead of this endpoint
  // specifying type=transfer in an HTTP request will call CreateTransferToken instead of this endpoint
  // TODO(RD-2738) remove this
  string type = 4 [deprecated = true];
}

message CreateTokenResponse {
  io.token.proto.common.token.Token token = 1;

  // deprecated: used as HTTP response for CreateTransferToken TODO(RD-2738) remove
  io.token.proto.common.token.TransferTokenStatus status = 2 [deprecated = true];
  io.token.proto.common.token.ExternalAuthorizationDetails authorization_details = 3 [deprecated = true];
}

message CreateTransferTokenRequest {
  option deprecated = true; // use CreateTokenRequest instead
  io.token.proto.common.token.TokenPayload payload = 1; // TokenPayload, should have TransferBody
  string token_request_id = 2; // ID of the token request
}

message CreateTransferTokenResponse {
  io.token.proto.common.token.Token token = 1;                                        // new Token
  io.token.proto.common.token.TransferTokenStatus status = 2;                         // success/failure
  io.token.proto.common.token.ExternalAuthorizationDetails authorization_details = 3; // Optional: used when status is FAILURE_EXTERNAL_AUTHORIZATION_REQUIRED
}

message CreateAccessTokenRequest {
  io.token.proto.common.token.TokenPayload payload = 1; // TokenPayload, should have AccessBody
  string token_request_id = 2; // ID of the token request
}

message CreateAccessTokenResponse {
  io.token.proto.common.token.Token token = 1; // new Token
}

message GetTokenRequest {
  string token_id = 1; // ID of Token to fetch
}

message GetTokenResponse {
  io.token.proto.common.token.Token token = 1; // Token
}

message GetActiveAccessTokenRequest {
  string to_member_id = 1; // Member ID of the recipient
}

message GetActiveAccessTokenResponse {
  io.token.proto.common.token.Token token = 1;
}

message GetTokensRequest {
  Type type = 1;          // ACCESS or TRANSFER
  Page page = 2;          // Optional paging settings.
  TokenFilter filter = 3; // optional filter

  enum Type {
    INVALID = 0;
    ACCESS = 1;
    TRANSFER = 2;
  }

  message TokenFilter {
    string source_account_id = 1;      // Transfer Token source account
    string destination_account_id = 2; // Transfer Token destination account
    int64 start_time_ms = 3;           // start time
    int64 end_time_ms = 4;             // end time
    Role role = 5;                     // FROM/TO
    string acting_as_ref_id = 6;       // Optional ref_id of TokenPayload.acting_as

    enum Role {
      ANY = 0;
      FROM = 1;
      TO = 2;
      ISSUER = 3;
    }
  }

  // for backwards compatibility with older JS clients TODO(RD-2738) remove
  string offset = 4 [deprecated = true];
  int32 limit = 5 [deprecated = true];
}

message GetTokensResponse {
  repeated io.token.proto.common.token.Token tokens = 1; // list of Tokens
  string offset = 2;                                     // optional offset state for the client to roundtrip.
}

message EndorseTokenRequest {
  string token_id = 1;                                    // The id of token to endorse
  io.token.proto.common.security.Signature signature = 2; // Signature
}

message EndorseTokenResponse {
  io.token.proto.common.token.TokenOperationResult result = 1; // Success/fail and new token data
}

message CancelTokenRequest {
  string token_id = 1;                                    // The id of token to cancel
  io.token.proto.common.security.Signature signature = 2 [deprecated = true]; // Signature
}

message CancelTokenResponse {
  io.token.proto.common.token.TokenOperationResult result = 1; // Success/fail and new token data
}

message ReplaceTokenRequest {
  message CancelToken {
    string token_id = 1;                                    // The id of token to replace
    io.token.proto.common.security.Signature signature = 2; // Signature canceling old token
  }

  message CreateToken {
    io.token.proto.common.token.TokenPayload payload = 1;           // New token payload
    io.token.proto.common.security.Signature payload_signature = 2; // Optional if endorsement requested.
    string token_request_id = 3;                                    // Optional token request ID
  }

  CancelToken cancel_token = 1;
  CreateToken create_token = 2;
}

message ReplaceTokenResponse {
  io.token.proto.common.token.TokenOperationResult result = 1; // Success/fail and new token data
}

message SignTokenRequestStateRequest {
  io.token.proto.common.token.TokenRequestStatePayload payload = 1;
  string token_request_id = 2;
}

message SignTokenRequestStateResponse {
  io.token.proto.common.security.Signature signature = 1;
}

message GetTokenRequestResultRequest {
  string token_request_id = 1;
}

message GetTokenRequestResultResponse {
  string token_id = 1;
  io.token.proto.common.security.Signature signature = 2;
  string transfer_id = 3;
  string standing_order_submission_id = 4;
}

message GetTokenRequestResultWithStatusRequest {
  string token_request_id = 1;
}

message GetTokenRequestResultWithStatusResponse {
  string token_id = 1;
  io.token.proto.common.security.Signature signature = 2;
  string transfer_id = 3;
  string standing_order_submission_id = 4;
  io.token.proto.common.token.TokenRequestResultStatus status = 5;
  string status_reason_information = 6;
}

message GetAuthRequestPayloadRequest {
  string auth_request_id = 1;
}

message GetAuthRequestPayloadResponse {
  io.token.proto.common.token.TokenPayload payload = 1;
  string callback_url = 2;
}

message StoreLinkingRequestRequest {
  string callback_url = 1;
  string token_request_id = 2;
}

message StoreLinkingRequestResponse {
  string linking_request_id = 1;
}

message GetLinkingRequestRequest {
  string linking_request_id = 1;
}

message GetLinkingRequestResponse {
  string member_id = 1;
  string callback_url = 2;
  io.token.proto.common.token.TokenRequest token_request = 3;
}

message SetTokenRequestTransferDestinationsRequest {
  string token_request_id = 1;
  repeated io.token.proto.common.transferinstructions.TransferDestination transfer_destinations = 2;
}

message SetTokenRequestTransferDestinationsResponse {}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Transfers.
//

message CreateTransferRequest {
  io.token.proto.common.transfer.TransferPayload payload = 1;     // Desired transfer spec
  io.token.proto.common.security.Signature payload_signature = 2; // Signature
}

message CreateTransferResponse {
  io.token.proto.common.transfer.Transfer transfer = 1; // Resulting transfer spec
  io.token.proto.common.token.ExternalAuthorizationDetails authorization_details = 2; // Optional: used when transfer status is PENDING_EXTERNAL_AUTHORIZATION
}

message CreateStandingOrderRequest {
  string token_id = 1;
}

message CreateStandingOrderResponse {
  io.token.proto.common.submission.StandingOrderSubmission submission = 1; // Resulting standing order submission
  io.token.proto.common.token.ExternalAuthorizationDetails authorization_details = 2; // Optional: used when transfer status is PENDING_EXTERNAL_AUTHORIZATION
}

message CreateBulkTransferRequest {
  string token_id = 1;
}

message CreateBulkTransferResponse {
  io.token.proto.common.transfer.BulkTransfer transfer = 1; // Resulting bulk transfer
}

message GetTransferRequest {
  string transfer_id = 1; // transfer to get
  bool skip_transfer_update = 2;
}

message GetTransferResponse {
  io.token.proto.common.transfer.Transfer transfer = 1; // Transfer spec
}

message GetStandingOrderSubmissionRequest {
  string submission_id = 1;
}

message GetStandingOrderSubmissionResponse {
  io.token.proto.common.submission.StandingOrderSubmission submission = 1;
}

message GetTransfersRequest {
  string token_id = 1;       // Deprecated, use filter.token_id instead
  Page page = 2;             // Optional paging settings
  TransferFilter filter = 3; // Filter to restrict query

  message TransferFilter {
    string token_id = 1;                                                        // Optional token ID
    int64 start_time_ms = 2;                                                    // Optional time range
    int64 end_time_ms = 3;                                                      // Optional time range
    io.token.proto.common.transaction.TransactionStatus transaction_status = 4; // Optional status
    Role role = 5;                                                              // Role. Default: ANY
    string acting_as_ref_id = 6;                                                // Optional ref_id of TokenPayload.acting_as
    string ref_id = 7;                                                          //optional refId
    TransferRefundStatus transfer_refund_status = 8;                                                   // optional refund status

    enum Role {
      ANY = 0;
      PAYER = 1;
      PAYEE = 2;
    }

    enum TransferRefundStatus {
      UNSET = 0;
      NONE = 1;
      PARTIAL = 2;
      FULL = 3;
    }
  }

  // for backwards compatibility with older JS clients TODO(RD-2738) remove
  string offset = 4 [deprecated = true];
  int32 limit = 5 [deprecated = true];
}

message GetTransfersResponse {
  repeated io.token.proto.common.transfer.Transfer transfers = 1; // List of transfers.
  string offset = 2;                                              // Optional offset state for the client to roundtrip.
}

message GetStandingOrderSubmissionsRequest {
  Page page = 1; // Optional paging settings
  StandingOrderSubmissionFilter filter = 2; // Filter to restrict query

  message StandingOrderSubmissionFilter {
    int64 start_time_ms = 1; // Optional time range
    int64 end_time_ms = 2; // Optional time range
    io.token.proto.common.submission.SubmissionStatus submission_status = 3; // Optional status
    Role role = 4; // Role. Default: ANY
    string acting_as_ref_id = 5; // Optional ref_id of TokenPayload.acting_as

    enum Role {
      ANY = 0;
      PAYER = 1;
      PAYEE = 2;
    }
  }
}

message GetStandingOrderSubmissionsResponse {
  repeated io.token.proto.common.submission.StandingOrderSubmission submissions = 1;
  string offset = 2;                                              // Optional offset state for the client to roundtrip.
}

message GetBulkTransferRequest {
  string bulk_transfer_id = 1;

}

message GetBulkTransferResponse {
  io.token.proto.common.transfer.BulkTransfer bulk_transfer = 1;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Bank Information Endpoints.
//

message GetBanksCountriesRequest {
  io.token.proto.common.bank.BankFilter filter = 1 [deprecated = true];     // DEPRECATED. Use fields below. (Optional) Filter by criteria in bank filter. Results must match all filter criteria.

  repeated string ids = 2;
  string search = 3;
  string country = 4 [deprecated = true]; // Use countries instead
  string provider = 5 [deprecated = true]; // Use providers instead
  string destination_country = 6 [deprecated = true]; // Use countries instead
  string tpp_id = 7;
  string bank_code = 9;
  repeated string countries = 10;
  repeated string providers = 11;
  io.token.proto.common.bank.BankFeatures bank_features = 12;
  string member_id = 13; // (Optional) If specified with a TSP member_id, return the countries which the member's configured banks are located in.
  repeated string supported_payment_networks = 14;
}

message GetBanksCountriesResponse {
  repeated string countries = 1;
}

message GetBanksRequest {
  io.token.proto.common.bank.BankFilter filter = 9 [deprecated = true];     // DEPRECATED. Use fields below. (Optional) Filter by criteria in bank filter. Results must match all filter criteria.

  // Paging
  int32 page = 4;                     // Result page to retrieve. Defaults to 1 if not specified
  int32 per_page = 5;                 // Maximum number of records per page. Can be at most 200. Defaults to 200 if not specified.
  string sort = 6;                    // (Optional) The key to sort the results. Could be one of: name, provider and country. Defaults to name if not specified.
  string member_id = 15;              // (Optional) If specified with a TSP member_id, return the banks which the member is configured with.

  string country = 3 [deprecated = true];              // DEPRECATED. Use countries instead. If specified, return banks whose 'country' matches the given ISO 3166-1 alpha-2 country code (case-insensitive)
  repeated string ids = 1;            // (Optional) If specified, return banks whose 'id' matches any one of the given ids (case-insensitive). Can be at most 1000.
  string search = 2;                  // (Optional) If specified, return banks whose 'name' or 'identifier' contains the given search string (case-insensitive)
  string provider = 7 [deprecated = true];             // DEPRECATED. Use providers instead. (Optional) If specified, return banks whose 'provider' matches the provider (case-insensitive)
  string tpp_id = 8;                  // (Optional) If specified, return banks which are integrated with the TPP
  string destination_country = 10 [deprecated = true]; // DEPRECATED. Use countries instead. (Optional) Filter for banks that support sending to the destination country.
  repeated string providers = 11;     // (Optional) Filter for banks whose 'provider' matches the providers (case-insensitive)
  string bank_code = 12;              // (Optional) Filter for banks whose bank code matches the given value (BLZ for German banks only)
  repeated string countries = 13;
  io.token.proto.common.bank.BankFeatures bank_features = 14;
  repeated string bics = 16;          // (Optional) Filter for banks whose 'bic' matches any one of the given BICs (case-insensitive). Can be at most 1000.
  repeated string supported_payment_networks = 17;
  string bank_group = 18;             // (Optional) Filter for banks whose 'group' contains the given string (case-insensitive)
  string bank_sub_group = 19;         // (Optional) Filter for banks whose 'sub group' matches the given string (case-insensitive)
}

message GetBanksResponse {
  repeated io.token.proto.common.bank.Bank banks = 1; // List of "link-able" banks
  io.token.proto.common.bank.Paging paging = 2;       // Paging info
}

message GetBanksV2Request {
  // Paging
  int32 page = 1;                     // Result page to retrieve. Defaults to 1 if not specified
  int32 per_page = 2;                 // Maximum number of records per page. Can be at most 200. Defaults to 200 if not specified.
  Sort sort = 3;                    // (Optional) The key to sort the results. Could be one of: name, standard and country. Defaults to name if not specified.

  // Filtering
  string member_id = 4;              // (Optional) If specified with a TSP member_id, return the banks which the member is configured with.
  string tpp_id = 5;                 // (Optional) Filter for banks which are integrated with the TPP
  repeated string ids = 6;           // (Optional) Filter for banks whose 'id' matches any one of the given ids (case-insensitive). Can be at most 1000.
  string search = 7;                 // (Optional) Filter for banks whose 'name' or 'identifier' contains the given search string (case-insensitive)
  string bank_group = 8;             // (Optional) Filter for banks whose 'group' contains the given string (case-insensitive)
  string bank_code = 9;              // (Optional) Filter for banks whose bank code matches the given value (BLZ for German banks only)
  repeated io.token.proto.common.bank.OpenBankingStandard open_banking_standards = 10;     // (Optional) Filter for banks whose 'openBankingStandard' matches the one in the provided list (case-insensitive)
  repeated string countries = 11;     // (Optional) Filter for banks whose 'country' matches the given ISO 3166-1 alpha-2 country code (case-insensitive)
  repeated string bics = 12;          // (Optional) Filter for banks whose 'bic' matches any one of the given BICs (case-insensitive). Can be at most 1000.
  repeated io.token.proto.common.v2.common.LocalInstrument supported_local_instruments = 13; // (Optional) Filter for banks whose 'localInstrument' matches the a local instrument the bank supports (case-insensitive)

  // Bank Feature Filtering
  // AIS
  string supports_account_list = 16;                 // Connection allows for retrieval of accounts
  string supports_account_details = 17;              // Connection allows for retrieval of account's details
  string supports_account_balance = 18;              // Connection allows for retrieval of account's balance
  string supports_transaction_list = 19;             // Connection allows for retrieval of account's transactions
  string supports_transaction_details = 20;          // Connection allows for retrieval of account's transaction details
  string supports_standing_order_list = 21;          // Connection allows for retrieval of account's standing order transactions
  string supports_transactions_date_filter = 22;     // Connection allows for retrieval of account's transactions by date filter
  string supports_delete_ais_consent = 34;           // Connection allows to delete ais consent
  string supports_unattended_calls_limit = 35;       // Connection allows to get unattended calls limit
  // PIS
  string requires_one_step_payment = 23;           // Connection only supports immediate redemption of payments
  string supports_single_payment = 24;             // Connection supports single payment.
  string supports_scheduled_payment = 25;          // Connection supports scheduled payments
  string supports_standing_order = 26;             // Connection supports standing orders
  string supports_return_refund_account = 27;      // Connection supports returning refund account details
  string supports_return_refund_account_holder_name = 28; // Connection supports returning account holder name of the refund account
  // CAF
  string supports_funds_confirmation = 29;         // Connections supports funds confirmation
  // VRP
  string supports_variable_recurring_payment = 30; // Connection supports variable recurring payments
  // Other
  string supports_app_to_app_on_ios = 31;          // Bank supports redirecting to the Bank's app on IOS
  string supports_app_to_app_on_android = 32;      // Bank supports redirecting to the Bank's app on Android
  string bank_sub_group = 33;                      // (Optional) Filter for banks whose 'sub group' matches the given string (case-insensitive)

  enum Sort {
    INVALID = 0;  // Invalid value, don't sort
    COUNTRY = 1;  // Sort by bank's Country
    PROVIDER = 2; // Sort by bank's Provider
    STANDARD = 3; // Sort by bank's OpenBankingStandard
    RANK = 4;     // Sort by bank's Rank
    NAME = 5;     // Sort by bank's Name
  }
}

message GetBanksV2Response {
  repeated io.token.proto.common.v2.bank.Bank banks = 1;
  io.token.proto.common.bank.Paging paging = 2;
}

message GetBankInfoRequest {
  string bank_id = 1; // Bank id
}

message GetBankInfoResponse {
  io.token.proto.common.bank.BankInfo info = 1; // Linking info
}

message GetBankAuthUrlRequest {
  string bank_id = 1;
  string token_request_id = 2;
  bool consent_accepted = 3; // if user/payer accepted the consent
}

message GetBankAuthUrlResponse {
  string url = 1;
}

message InitiateBankAuthorizationRequest {
  string token_request_id = 1;
  map<string, string> credentials = 2 [(io.token.proto.extensions.field.redact) = true]; // credential ID -> value
  bool consent_accepted = 3; // if user/payer accepted the consent
  bool use_credential_flow = 4; // to use Credential Flow explicitly with empty credentials
  bool use_webapp_credentials_flow = 5; //Use Token web app screen for credential flow.
}

message CredentialFields {
  repeated io.token.proto.common.providerspecific.CredentialField fields = 1;
}

message InitiateBankAuthorizationResponse {
  oneof result {
    string redirect_url = 1; // URL for bank authorization
    io.token.proto.common.providerspecific.ScaStatus status = 2; // if SCA process has finished, whether it succeeded or not
    CredentialFields fields = 3;
  }
  string oauth_state = 4;
}

message GetDirectBankAuthUrlRequest {
  option deprecated = true; // Backward compatibility for web-app
  string bank_id = 1;
  string token_request_id = 2;
}

message GetDirectBankAuthUrlResponse {
  option deprecated = true; // Backward compatibility for web-app
  string url = 1;
}

message GetBanksOutageStatusRequest {
  repeated string bank_id = 1; // (Optional) Filter for banks whose 'id' matches any one of the given ids
  repeated io.token.proto.common.bank.ProductType product_type = 2; // (Optional) Filter will apply on the given product types.
  repeated io.token.proto.common.bank.OutageStatus outage_status = 3; // (Optional) Filter for banks whose 'outage_status' matches any one of the given outage statuses
  repeated string country = 4; // (Optional) Filter for banks whose 'country' matches any one of the given ISO 3166-1 alpha-2 country code
}

message GetBanksOutageStatusResponse {
  repeated BankStatus banks_status = 1;

  message BankStatus {
    string bank_name = 1;
    string bank_id = 2;
    io.token.proto.common.bank.OutageStatus ais_status = 3;
    io.token.proto.common.bank.OutageStatus sip_status = 4;
    string last_updated_at = 5;
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// TSP client only requests
//

message OnBankAuthCallbackRequest {
  string bank_id = 1 [deprecated = true];// the bank id of the callback. Typically extracted from the path component of the callback url
  string query = 2;   // the query component of the callback url
}

message OnBankAuthCallbackResponse {
  string token_request_id = 1;
  CredentialFields fields = 2; // Optional credential request fields. When provided, TPP should call initiateBankAuth again to provide the credentials.
  oneof result { // v2 result - only populated in the V2 and Vrp callback responses
    io.token.proto.common.v2.openbanking.payment.Payment payment = 3;
    io.token.proto.common.v2.openbanking.vrp.VrpConsent vrp_consent = 4;
  }
  string redirect_url = 5; // Optional - URL for bank authorization
}

message GetExternalMetadataRequest {
  string token_request_id = 1;
}

message GetExternalMetadataResponse {
  io.token.proto.common.bank.OpenBankingStandard standard = 1;
  string consent = 2;
}

message StoreBankConfigRequest {
  string member_id = 1;
  string bank_id = 2;
  io.token.proto.common.tsp.bankconfig.BankConfig bank_config = 3;
}

message StoreBankConfigResponse {
}

message GetBankConfigRequest {
  string member_id = 1;
  string bank_id = 2;
}

message GetBankConfigResponse {
  io.token.proto.common.tsp.bankconfig.BankConfig bank_config = 1;
}

message GetBankConfigsRequest {
  string member_id = 1;
}

message GetBankConfigsResponse {
  map<string, io.token.proto.common.tsp.bankconfig.BankConfig> bank_configs = 1;
}

message DeleteBankConfigRequest {
  string member_id = 1;
  string bank_id = 2;
}

message DeleteBankConfigResponse {
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Bank member only requests.
//
message GetMemberInfoRequest {
  string member_id = 1;
}

message GetMemberInfoResponse {
  io.token.proto.common.member.MemberInfo member_info = 1; // Member info
}

message GetConsentRequest {
  string bank_id = 1;
  string consent_id = 2;
}

message GetConsentResponse {
  io.token.proto.common.consent.Consent consent = 1;
}

message GetConsentsRequest {
  string bank_id = 1;
  io.token.proto.common.account.BankAccount bank_account = 2;
  Page page = 3;
}

message GetConsentsResponse {
  repeated io.token.proto.common.consent.Consent consents = 1;
  string offset = 2;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Testing API calls
//

message CreateTestBankAccountRequest {
  io.token.proto.common.money.Money balance = 1; // starting balance
}

message CreateTestBankAccountResponse {
  io.token.proto.banklink.OauthBankAuthorization authorization = 2; // authorization usable with linkAccounts
}

message GetTestBankNotificationRequest {
  string subscriber_id = 1;   // subscriber ID
  string notification_id = 2; // notification ID
}

message GetTestBankNotificationResponse {
  io.token.proto.common.notification.Notification notification = 1; // notification
}

message GetTestBankNotificationsRequest {
  string subscriber_id = 1; // subscriber ID
}

message GetTestBankNotificationsResponse {
  repeated io.token.proto.common.notification.Notification notifications = 1; // list of notifications
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Report
//

message GetTppPerformanceReportRequest {
  string bank_id = 1;
  int32 days_back = 2;
}

message GetTppPerformanceReportResponse {
  repeated PerformanceSummary summaries = 1;

  message PerformanceSummary {
    string date = 1;
    TppType tpp_type = 2;
    double p50_latency = 3 [deprecated = true];
    double p75_latency = 4 [deprecated = true];
    double p90_latency = 5 [deprecated = true];
    double p95_latency = 6 [deprecated = true];
    double p99_latency = 7 [deprecated = true];
    double p999_latency = 8 [deprecated = true];
    double error_rate = 9;
    int64 error_count = 10;
    int64 request_count = 11;
    string tpp_id = 12;
    double average_latency = 13;

    enum TppType {
      AISP = 0;
      PISP = 1;
      CBPII = 2;
    }
  }
}

message GetAvailabilityReportRequest {
  string bank_id = 1;
  int32 days_back = 2;
}

message GetAvailabilityReportResponse {
  repeated AvailabilitySummary summaries = 1;

  message AvailabilitySummary {
    string date = 1;
    double token_uptime_pct = 2;
    double bank_uptime_pct = 3;
  }
}

message GetTppAccessReportRequest {
  string bank_id = 1;
  int32 days_back = 2;
}

message GetTppAccessReportResponse {
  repeated TppAccessSummary summaries = 1;

  message TppAccessSummary {
    string date = 1;
    TppType tppType = 2;
    int64 total = 3;

    enum TppType {
      AISP = 0;
      PISP = 1;
      CBPII = 2;
    }
  }
}

message GetTppRequestsReportRequest {
  string tpp_member_id = 1;
  int64 from_date_ms = 2;         // UTC time in millis.
  int64 to_date_ms = 3;           // UTC time in millis.
}

message GetTppRequestsReportResponse {
  repeated TppRequestsSummary summaries = 1;

  message TppRequestsSummary {
    int64 ais_count = 1;
    int64 pis_count = 2;
    string date = 3;
  }
}

message GetBankDowntimeReportRequest {
  string bank_id = 1;
  int32 days_back = 2;
}

message GetBankDowntimeReportResponse {
  repeated BankDowntimeSummary summaries = 1;

  message BankDowntimeSummary {
    string bank_name = 1;
    RequestType request_type = 2;
    string start_time = 3;
    string end_time = 4;
    enum RequestType {
      INVALID = 0;
      AIS = 1;
      PIS = 2;
    }
  }
}

message GetBankStatusRequest {
  string bank_id = 1;
}

message GetBankStatusResponse {
  BankStatus bank_status = 1;

  message BankStatus {
    string bank_name = 1;
    string ais_status = 2;
    string pis_status = 3;
    string last_updated_at = 4;
    string server_status = 5 [deprecated = true];
  }
}

message GetBanksStatusRequest {}

message GetBanksStatusResponse {
  repeated BankStatus banks_status = 1;

  message BankStatus {
    string bank_id = 1;
    string ais_status = 2;
    string pis_status = 3;
    string last_updated_at = 4;
    string server_status = 5 [deprecated = true];
  }
}

message GetServiceHealthRequest {}

message GetServiceHealthResponse {}

////////////////////////////////////////////////////////////////////////////////////////////////////
// RESTful Bank API
//
message CreateBankUserRequest {
  string bank_id = 1;
}

message CreateBankUserResponse {
  string user_id = 1;
}

message DeleteBankUserRequest {
  string bank_id = 1;
  string user_id = 2;
}

message DeleteBankUserResponse {}

message RetrieveConsentRequestRequest {
  string bank_id = 1;
  string request_id = 2;
}

message RetrieveConsentRequestResponse {
  io.token.proto.common.consent.ConsentRequest consent_request = 1;
}

message CreateConsentRequest {
  string bank_id = 1;
  io.token.proto.common.consent.CreateConsent params = 2;
}

message CreateConsentResponse {
  io.token.proto.common.consent.Consent consent = 1;
}

message CancelConsentRequest {
  string bank_id = 1;
  string consent_id = 2;
}

message CancelConsentResponse {}

message GetActiveAccessConsentsRequest {
  string bank_id = 1;
  string user_id = 2;
  Page page = 3;
}

message GetActiveAccessConsentsResponse {
  repeated io.token.proto.common.consent.Consent consents = 1;
  string offset = 2;
}

message GetAccessConsentsRequest {
  string bank_id = 1;
  string user_id = 2;
  Page page = 3;
  io.token.proto.common.consent.StatusFilter status = 4;
}

message GetAccessConsentsResponse {
  repeated io.token.proto.common.consent.Consent consents = 1;
  string offset = 2;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Partner endpoints
//
message EnableMemberRequest {
  string member_id = 1;
}

message EnableMemberResponse {}

message DisableMemberRequest {
  string member_id = 1;
}

message DisableMemberResponse {}

message GetMembersUnderPartnerRequest {
  Page page = 1;
}

message GetMembersUnderPartnerResponse {
  repeated io.token.proto.common.member.MemberInfo members = 1;
  string offset = 2; // Optional offset state for the client to roundtrip
}

message SetDefaultCustomizationRequest {
  string customization_id = 1;
}

message SetDefaultCustomizationResponse {}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Webhook endpoints
//

message SetWebhookConfigRequest {
  io.token.proto.common.webhook.Webhook.Config config = 1;
}

message SetWebhookConfigResponse {}

message GetWebhookConfigRequest {}

message GetWebhookConfigResponse {
  io.token.proto.common.webhook.Webhook.Config config = 1;
}

message DeleteWebhookConfigRequest {}

message DeleteWebhookConfigResponse {}

////////////////////////////////////////////////////////////////////////////////////////////////////
//Validation endpoints
//

message ValidateIbanRequest {
  string iban = 1 [(io.token.proto.extensions.field.redact) = true];
}

message ValidateIbanResponse {
  string bank_name = 1;
  string bic = 2;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
//Sub Tpp endpoints
//

message CreateSubTppRequest {
  string name = 1;
  string domain = 2;
  string domicile_country = 3;
  bytes logo = 4;
  string mcc_code = 5; // optional mcccode
  string parent_sub_tpp_id = 6; //optional parent subTpp id
  io.token.proto.common.member.Merchant merchant = 7;
}

message CreateSubTppResponse {
  string sub_tpp_id = 1;
}

message DeleteSubTppRequest {
  string sub_tpp_id = 1;
}

message DeleteSubTppResponse {}

message RetrieveSubTppRequest {
  string sub_tpp_id = 1;
}

message RetrieveSubTppResponse {
  io.token.proto.common.member.SubTpp sub_tpp = 1;
}

message RetrieveSubTppsRequest {
  Page page = 1;
  Filter filter = 2; //Optional

  message Filter {
    repeated string by_company_names = 1;  // Optional list of company names by which the result will be filtered.
    repeated string by_registration_dates = 2; // Optional list of registration dates by which the result will be filtered.
  }
}

message RetrieveSubTppsResponse {
  repeated io.token.proto.common.member.SubTpp sub_tpps = 1;
  string offset = 2;  // offset for client to roundtrip
}

message RetrieveSubTppChildrenRequest {
  string sub_tpp_id = 1;
}

message RetrieveSubTppChildrenResponse {
  repeated io.token.proto.common.member.SubTpp sub_tpps = 1;
}

message UpdateSubTppRequest {
  string sub_tpp_id = 1;
  io.token.proto.common.member.SubTpp sub_tpp = 2;
}

message UpdateSubTppResponse {}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Provider registration endpoints

message RegisterProviderRequest {
  oneof registration_payload {
    io.token.proto.common.virtualaccount.BnppRegistrationPayload bnpp = 1;
    io.token.proto.common.virtualaccount.HsbcRegistrationPayload hsbc = 2;
    io.token.proto.common.virtualaccount.FankRegistrationPayload fank = 3; // This will not be shown in swagger since this is a fake provider for testings only.
    io.token.proto.common.virtualaccount.CorporateApiRegistrationPayload corporate_api = 4;
  }
  io.token.proto.common.virtualaccount.Product product = 5;
}

message ProviderRegistrationResponse { // deprecated PLT-4728
  io.token.proto.common.virtualaccount.Registration registration = 1;
}

message GetProviderRegistrationsRequest {
  int32 limit = 1;
  string offset = 2;
  io.token.proto.common.virtualaccount.Product product = 3; // filter
}

message GetProviderRegistrationsResponse {
  repeated io.token.proto.common.virtualaccount.Registration registrations = 1;
  io.token.proto.common.v2.paging.PageInfo page_info = 2;
}

message GetProviderRegistrationRequest {
  string registration_id = 1;
}

message DeleteProviderRegistrationRequest {
  string registration_id = 1;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Refund endpoints
//

// TODO START: deprecated PLT-4728
message PayoutRegisterRequest {
  oneof registration_payload {
    io.token.proto.common.v2.payout.BnppRegistrationPayload bnpp = 1;
    io.token.proto.common.v2.payout.HsbcRegistrationPayload hsbc = 2;
    io.token.proto.common.v2.payout.FankRegistrationPayload fank = 3; // This will not be shown in swagger since this is a fake provider for testings only.
    io.token.proto.common.v2.payout.CorporateApiRegistrationPayload corporate_api = 4;
  }
}

message PayoutRegisterResponse {
  io.token.proto.common.v2.payout.Registration registration = 1;
}

message GetPayoutRegistrationRequest {
  string registration_id = 1;
}

message GetPayoutRegistrationResponse {
  io.token.proto.common.v2.payout.Registration registration = 2;
}

message DeletePayoutRegistrationRequest {
  string registration_id = 1;
}
// TODO END: deprecated PLT-4728

message InitiateRefundRequest {
  io.token.proto.common.v2.payout.RefundInitiation initiation = 1;
}

message InitiateRefundResponse {
  io.token.proto.common.v2.payout.Refund refund = 1;
}

message GetRefundRequest {
  string refund_id = 1;
}

message GetRefundResponse {
  io.token.proto.common.v2.payout.Refund refund = 1;
}

message GetRefundsRequest {
  int32 limit = 1;        // Max number of records to return
  string offset = 2;      // The offset from the previous page
  string start_date = 3;  // Lower bound for a refund creation date in the format 'YYYY-MM-DD'. If specified, only refunds created at or after the given date will be returned.
  string end_date = 4;    // Upper bound for a refund creation date in the format 'YYYY-MM-DD'. If specified, only refunds created at or before the given date will be returned.
  repeated string ids = 5; // return payments with these ids
  bool invert_ids = 6;     // inverts the ids query: return payments with ids not listed in the ids parameter
  repeated io.token.proto.common.v2.payout.Status statuses = 7; // return payments with these statuses
  bool invert_statuses = 8; // inverts the statuses query: return payments with statuses not listed in the statuses parameter
  repeated string ref_ids = 9;
  bool partial = 10;       // if true, return partial payments - with only id and status fields
  repeated string on_behalf_of_ids = 11; // return payments with these on behalf of ids (optional)
}

message GetRefundsResponse {
  repeated io.token.proto.common.v2.payout.Refund refunds = 1;
  io.token.proto.common.v2.paging.Page paging = 2;
}

message GetRefundsByPaymentIdRequest {
  int32 limit = 1;        // Max number of records to return
  string offset = 2;      // The offset from the previous page
  string payment_id = 3;
}

message GetRefundsByPaymentIdResponse {
  repeated io.token.proto.common.v2.payout.Refund refunds = 1;
  io.token.proto.common.v2.paging.Page paging = 2;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Payout endpoints
//

message CreatePayoutRequest {
  io.token.proto.common.v2.payout.Initiation initiation = 1;
}

message CreatePayoutResponse {
  io.token.proto.common.v2.payout.Payout payout = 1;
}

message GetPayoutByPayoutIdRequest {
  string id = 1;
}

message GetPayoutByPayoutIdResponse {
  io.token.proto.common.v2.payout.Payout payout = 1;
}

message GetPayoutsRequest {
  // string account_id = 1; // (Mandatory) We will not ask for account id because GetPayouts will only query our own db
  int32 limit = 2;
  int32 offset = 3;
  string start_date = 4; // 'YYYY-MM-DD' UTC timezone (Mandatory)
  string end_date = 5; // 'YYYY-MM-DD' UTC timezone
  repeated string ids = 7;
  bool invert_ids = 8;
  repeated string statuses = 9;
  bool invert_statuses = 10;
  repeated string ref_ids = 11;
  string on_behalf_of_id = 12;
}

message GetPayoutsResponse {
  repeated io.token.proto.common.v2.payout.Payout payouts = 1;
  io.token.proto.common.v2.paging.PageInfo page_info = 2;
}

message DeleteVirtualAccountSettlementRuleRequest {
  string account_id = 1;
  string settlement_rule_id = 2;
}

message DeleteVirtualAccountSettlementRuleResponse {}

message CreateVirtualAccountSettlementRuleRequest {
  string account_id = 1; // Mandatory - payer virtual account id
  io.token.proto.common.v2.payout.Creditor payee_account_details = 2; // Mandatory
  io.token.proto.common.v2.payout.AmountType amount_type = 3; // Mandatory
  string amount_value = 4; // Mandatory
  string effective_from = 5; // Optional 'YYYY-MM-DD' UTC timezone (If not set, default to today’s date.)
  string effective_to = 6; // Optional 'YYYY-MM-DD' UTC timezone (If not set, the instruction will not end.)
  io.token.proto.common.v2.payout.TimeInterval time_interval = 7; // Mandatory If Intraday, need to specify the time interval in terms of hours.
  int32 intraday_interval_hours = 8; // Mandatory if the TimeInterval is Intraday, the time interval in hours
  int32 intraday_interval_minutes = 9; // Optional if the TimeInterval is Intraday, the time interval in minutes
}

message CreateVirtualAccountSettlementRuleResponse {
  string settlement_rule_id = 1; // UUID
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// VRP endpoints
//

message CreateVrpConsentRequest {
  io.token.proto.common.v2.openbanking.vrp.VrpConsent.Initiation initiation = 1;
  bool pisp_consent_accepted = 2;
}

message GetVrpConsentRequest {
  string vrp_consent_id = 1;
}

message RevokeVrpConsentRequest {
  string vrp_consent_id = 1;
}

message VrpConsentResponse {
  io.token.proto.common.v2.openbanking.vrp.VrpConsent vrp_consent = 1;
}

message GetVrpConsentsRequest {
  int32 limit = 1;        // Max number of records to return
  string offset = 2;      // The offset from the previous page
}

message GetVrpConsentsResponse {
  repeated io.token.proto.common.v2.openbanking.vrp.VrpConsent vrp_consents = 1;
  io.token.proto.common.v2.paging.PageInfo page_info = 2;
}

message GetVrpConsentPaymentsRequest {
  string vrp_consent_id = 1;
  int32 limit = 2;        // Max number of records to return
  string offset = 3;      // The offset from the previous page
}

message GetVrpConsentPaymentsResponse {
  repeated io.token.proto.common.v2.openbanking.vrp.Vrp vrps = 1;
  io.token.proto.common.v2.paging.PageInfo page_info = 2;
}

message CreateVrpRequest {
  io.token.proto.common.v2.openbanking.vrp.Vrp.Initiation initiation = 1;
}

message GetVrpRequest {
  string vrp_id = 1;
}

message VrpResponse {
  io.token.proto.common.v2.openbanking.vrp.Vrp vrp = 1;
}

message GetVrpsRequest {
  int32 limit = 1;        // Max number of records to return
  string offset = 2;      // The offset from the previous page
  repeated string ids = 3; // return payments with these ids
  bool invert_ids = 4;     // inverts the ids query: return payments with ids not listed in the ids parameter
  repeated io.token.proto.common.v2.openbanking.vrp.Vrp.Status statuses = 5; // return payments with these statuses
  bool invert_statuses = 6; // inverts the statuses query: return payments with statuses not listed in the statuses parameter
  string created_after = 7; // ISO 8601 format, e.g. 2023-04-05
  string created_before = 8;// ISO 8601 format, e.g. 2023-04-05
  repeated string ref_ids = 9;
  string vrp_consent_id = 10;
}

message GetVrpsResponse {
  repeated io.token.proto.common.v2.openbanking.vrp.Vrp vrps = 1;
  io.token.proto.common.v2.paging.PageInfo page_info = 2;
}

message ConfirmFundsAvailabilityRequest {
  string vrp_consent_id = 1;
  string amount = 2;
}

message ConfirmFundsAvailabilityResponse {
  bool funds_available = 1;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Open Banking V2.
//

message CreatePaymentV2Request {
  io.token.proto.common.v2.openbanking.payment.Initiation initiation = 1;
  bool pisp_consent_accepted = 2;
  map<string, string> initial_embedded_auth = 3;
}

message GetPaymentV2Request {
  string payment_id = 1;
  bool skip_payment_update = 2; // if true, we will skip the payment update and it is only for internal use and won't be shown in API spec.
}

message ProvidePaymentEmbeddedAuthV2Request {
  string payment_id = 1;
  map<string, string> embedded_auth = 2 [(io.token.proto.extensions.field.redact) = true]; // field ID -> value
}

message RedeemPaymentV2Request {
  string payment_id = 1;
}

message PaymentV2Response {
  io.token.proto.common.v2.openbanking.payment.Payment payment = 1;
}

message GetPaymentsV2Request {
  repeated string ids = 1; // return payments with these ids
  bool invert_ids = 2;     // inverts the ids query: return payments with ids not listed in the ids parameter
  repeated io.token.proto.common.v2.openbanking.payment.Status statuses = 3; // return payments with these statuses
  bool invert_statuses = 4; // inverts the statuses query: return payments with statuses not listed in the statuses parameter
  string created_after = 5; // ISO 8601 format, e.g. 2023-04-05T17:02:11.954Z
  string created_before = 6;// ISO 8601 format, e.g. 2023-04-05T17:02:11.954Z
  repeated string ref_ids = 7;
  string on_behalf_of_id = 8;
  repeated io.token.proto.common.v2.common.PaymentRefundStatus refund_statuses = 9;
  bool partial = 10;       // if true, return partial payments - with only id and status fields
  int32 limit = 11;        // Max number of records to return
  string offset = 12;      // The offset from the previous page, if any
}

message GetPaymentsV2Response {
  repeated io.token.proto.common.v2.openbanking.payment.Payment payments = 1;
  io.token.proto.common.v2.paging.PageInfo page_info = 2;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Payment Restrictions
//

message CreateRestrictionRequest {
  string target_member_id = 1; // SubTpp Id in case of Type 1 reseller and memberId in all other cases
  io.token.proto.common.restriction.RestrictionPayload restriction_payload = 3;
}

message CreateRestrictionResponse {
  string restriction_id = 1;
}

message GetRestrictionsRequest {
  Filter filter = 2;
  message Filter {
    string by_restriction_id = 1; // [Optional]
    string by_target_member_id = 2; // [Optional]
  }
}

message GetRestrictionsResponse {
  repeated io.token.proto.common.restriction.Restriction restrictions = 1;
}

message DeleteRestrictionRequest{
  string restriction_id = 1;
}

message DeleteRestrictionResponse {
  io.token.proto.common.restriction.Restriction deleted_restriction = 1;
}

message UpdateRestrictionRequest {
  string restriction_id = 1;
  io.token.proto.common.restriction.Restriction updated_restriction = 2;
}

message UpdateRestrictionResponse {}

message CreateRuleRequest {
  string restriction_id = 1;
  io.token.proto.common.restriction.RulePayload rule = 3;
}

message CreateRuleResponse {
  string rule_id = 1;
}

message UpdateRuleRequest {
  string rule_id = 1;
  string restriction_id = 2;
  io.token.proto.common.restriction.Rule updated_rule = 3;
}

message UpdateRuleResponse {}

message DeleteRuleRequest {
  string rule_id = 1;
  string restriction_id = 2;
}

message DeleteRuleResponse {
  io.token.proto.common.restriction.Rule deleted_rule = 2;
}

message GetCountriesRequest {}

message GetCountriesResponse {
  repeated io.token.proto.common.restriction.Country countries = 1;
}

message GetRegionsRequest {
  string country_code = 1;
}

message GetRegionsResponse {
  repeated io.token.proto.common.restriction.Region regions = 1;
}

message GetBankOutageStatusRequest {
  string bank_id = 1;
  io.token.proto.common.bank.ProductType product_type = 2;
}

message GetBankOutageStatusResponse {
  io.token.proto.common.bank.OutageStatus status = 1;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Secret Service
//

message UploadKeyAndCertificateRequest {
  oneof upload {
    UploadKeyAndCertificate key_and_certificate = 1; // Upload certificate and private key
    UploadKeys keys = 2; // Upload private and public key for HSBC refund registration
  }
}

message UploadKeyAndCertificate {
  string private_key = 1; // Encrypted private_key
  string certificate = 2; // Encrypted certificate
  string certificate_name = 3;
}

message UploadKeys {
  string private_key = 1; // Encrypted private_key
  string public_key = 2; // Encrypted public_key
}

message UploadKeyAndCertificateResponse {
  string key_id = 1;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Virtual Account API
//
message CreateVirtualAccountRequest {
  reserved 2, 6;
  string currency = 1; //Mandatory field
  string on_behalf_of_id = 4; //Optional - this is provided when account to be created for the merchant(sub-Tpp).
  string account_nick_name = 5;
  string country = 7; // mandatory 2-letter ISO 3166-1 alpha-2 country code
}

message CreateVirtualAccountResponse {
  io.token.proto.common.virtualaccount.VirtualAccount virtual_account = 1;
}

message GetVirtualAccountByIdRequest {
  string account_id = 1; // Token account Id - mandatory.
}

// Getting all accounts for member by mapping memberId to modulr customerId.
message GetVirtualAccountsRequest {
  reserved 1, 2;
  string offset = 3; // The page offset, encoded
  int32 limit = 4;
  string currency = 5;
  string country = 6;
  string nickname = 7;
  string on_behalf_of_id = 8;
}

message GetVirtualAccountByIdResponse {
  io.token.proto.common.virtualaccount.VirtualAccount virtual_account = 1;
}

message GetVirtualAccountsResponse {
  repeated io.token.proto.common.virtualaccount.VirtualAccount virtual_account = 1;
  io.token.proto.common.v2.paging.PageInfo page_info = 2;
}

message CreditVirtualAccountRequest {
  string account_id = 1;
  string amount = 2; // double amount in string format
  string description = 3;
  Type type = 4;
  Payer payer = 5;

  enum Type {
    UNKNOWN = 0;
    FASTER_PAYMENTS = 1;
    SEPA_CREDIT_TRANSFERS = 2;
    SEPA_INSTANT_CREDIT_TRANSFERS = 3;
  }
}

message CreditVirtualAccountResponse {}

message GetVirtualAccountTransactionsRequest {
  string account_id = 1;
  string ref_id = 2;
  string start_date = 3; // 'YYYY-MM-DD' UTC timezone
  string end_date = 4; // 'YYYY-MM-DD' UTC timezone
  LocalInstrument local_instrument = 5;
  string offset = 6;
  int32 limit = 7;
  string amount = 8;
  string provider_payment_id = 9;
  Transaction.TransactionType transaction_type = 10; // DEBIT, CREDIT
}

enum LocalInstrument {
  INVALID_LOCAL_INSTRUMENT = 0;
  SEPA = 1;
  SEPA_INSTANT = 2;
  FASTER_PAYMENTS = 3;
  BACS = 4;
}

message GetVirtualAccountTransactionRequest {
  string account_id = 1;
  string provider_payment_id = 2;
}

message Transaction {
  string provider_payment_id = 1;
  io.token.proto.common.money.Money amount = 2;
  string description = 3;
  string created_date_time = 4;
  string local_instrument = 5; // SEPA,FASTER_PAYMENTS
  TransactionType transaction_type = 6; // DEBIT, CREDIT
  io.token.proto.common.v2.common.DebtorInformation debtor = 7;
  io.token.proto.common.v2.common.CreditorInformation creditor = 8;
  string ref_id = 9;
  string transfer_id = 10;
  string payment_id = 11;
  string refund_id = 12;
  string payout_id = 13;

  enum TransactionType {
    INVALID_TRANSACTION_TYPE = 0;
    DEBIT = 1;
    CREDIT = 2;
  }
}

message Identifier {
  string type = 1;
  oneof identifier {
    AccountDetails account_details = 6;
    Iban iban = 7;
  }
}

message AccountDetails {
  option (io.token.proto.extensions.message.redact) = true;
  string account_number = 1;
  string sort_code = 2;
}

message Iban {
  option (io.token.proto.extensions.message.redact) = true;
  string iban = 1;
  string bic = 2;
}

message Payer {
  string name = 1;
  Identifier identifier = 2;
}

message AdditionalInfo {
  Payer payer = 1;
}

message Account {
  string id = 1;
  string name = 2;
  string balance = 3;
  string currency = 4;
  string status = 5;
  repeated Identifier identifiers = 6;
  string created_date = 7;
  bool direct_debit = 8;
  string secured_funding_limit = 9;
  string external_reference = 10;
}

message GetVirtualAccountTransactionsResponse {
  repeated Transaction transactions = 1;
  io.token.proto.common.v2.paging.PageInfo page_info = 2;
}

message GetVirtualAccountTransactionResponse {
  Transaction transaction = 1;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Virtual Accounts - Settlement Rules API
//
message GetVirtualAccountSettlementPayoutsRequest {
  string account_id = 1;
  int32 limit = 2;
  string offset = 3;
  string settlement_rule_id = 4;
  string start_date = 5; // startDate 'YYYY-MM-DD' UTC timezone (Optional)
  string end_date = 6; // endDate 'YYYY-MM-DD' UTC timezone (Optional)
  repeated string ids = 7; // payout ids for search (Optional)
  bool invert_ids = 8; // bool should we revert ids, default false (Optional)
  repeated string statuses = 9; // statuses of payout (Optional)
  bool invert_statuses = 10; // revert status, default false (Optional)
  repeated string ref_ids = 11; // refIds (Optional)
}

message GetVirtualAccountSettlementPayoutsResponse {
  repeated io.token.proto.common.v2.payout.SettlementRulePayout payouts = 1;
  io.token.proto.common.v2.paging.PageInfo page_info = 2;
}

message GetVirtualAccountSettlementRuleRequest {
  string settlement_rule_id = 1; // UUID
  string account_id = 2; //virtual account id
}

message GetVirtualAccountSettlementRuleResponse {
  io.token.proto.common.v2.payout.SettlementRule settlement_rule = 1;
}

message GetVirtualAccountSettlementRulesRequest {
  string account_id = 1; // virtual account id
  io.token.proto.common.v2.payout.SettlementRule.SettlementRuleStatus status = 2;
}

message GetVirtualAccountSettlementRulesResponse {
  repeated io.token.proto.common.v2.payout.SettlementRule settlement_rules = 1;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Gateway Service.
//
service GatewayService {
  option (grpcbridge.swagger.root) = {
      info: {
          title: "Token API"
          description: "Token REST API."
          version: "1.0.0"
      };
      host: "api.token.io"
      basePath: "/v1"
  };

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Member registration, key and alias management.
  //

  // Create a member. Mints a member ID; newly-created member does not yet
  // have keys, alias, or anything other than an ID.
  // Used by createMember, https://developer.token.io/sdk/#create-a-member
  // (SDK's createMember also uses UpdateMember rpc).
  rpc CreateMember (CreateMemberRequest) returns (CreateMemberResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        post: "/members"
        body: "*"
    };
  }

  // Creates a business member under realm of a bank with an EIDAS alias (with value equal to the
  // authNumber from the certificate) and a public key taken from the certificate.
  // Then onboards it with the provided certificate.
  // A successful onboarding includes verifying the member and the alias and adding permissions
  // based on the certificate.
  // The call is idempotent, so if a member under this realm and with the same verified alias
  // already exists, it returns an ID of the existing member, an ID of the registered eidas key and
  // an ID of the verification for this certificate. If you wish to submit another certificate
  // for an existing member, please use VerifyEidas call instead.
  // Note, that the call is asynchronous and the newly created member might not be onboarded at the
  // time the call returns. You can check the verification status using GetEidasVerificationStatus
  // call with the verification_id returned by this call.
  rpc RegisterWithEidas (RegisterWithEidasRequest) returns (RegisterWithEidasResponse) {
    option (grpcbridge.swagger.operation) = {
      tags: "eidas"
      summary: "Create and register a business member with an eIDAS certificate."
      description: "Create and asynchronously [onboard](https://developer.token.io/token_rest_api_doc/content/k-eidas/member_onboarding.htm?tocpath=eIDAS-related%20REST%20API%20Calls%20for%20Certificate%20Registration%20and%20Verification%7CMember%20Onboarding) "
                   "a business member under realm of a bank.<br>"
                   "**See also:** <br>"
                   "[RegisterWithEidas](https://developer.token.io/token_rest_api_doc/content/k-eidas/register_with_eidas.htm)<br>"
                   "[Certificate and payload signature format](https://developer.token.io/token_rest_api_doc/content/k-eidas/member_onboarding.htm?tocpath=eIDAS-related%20REST%20API%20Calls%20for%20Certificate%20Registration%20and%20Verification%7CMember%20Onboarding#Certific)"
    };
    option (google.api.http) = {
      put: "/eidas/register"
      body: "*"
    };
  }

  // Apply member updates. Used when adding/removing keys, aliases to/from member.
  // These updates require a signature.
  // See how Java SDK's Client.updateMember uses it:
  //   https://developer.token.io/sdk/javadoc/io/token/rpc/Client.html#updateMember-io.token.proto.common.member.MemberProtos.Member-java.util.List-
  // See how JS SDK's AuthHttpClient._memberUpdate uses it:
  //   https://developer.token.io/sdk/esdoc/class/src/http/AuthHttpClient.js~AuthHttpClient.html#instance-method-_memberUpdate
  rpc UpdateMember (UpdateMemberRequest) returns (UpdateMemberResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        post: "/members/{update.member_id}/updates"
        body: "*"
    };
    option (io.token.proto.extensions.service.rate_limit) = {
      selector: [
        {key: "resolve-alias-remote-address", path: "{REMOTE_ADDRESS}"},
        {key: "resolve-alias-source-developer", path: "{DEVELOPER_ID}"}
      ]
    };
  }

  // Get information about a member
  rpc GetMember (GetMemberRequest) returns (GetMemberResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        get: "/members/{member_id}"
    };
  }

  // set profile information (display name)
  // Ignores picture fields; use SetProfilePicture for those.
  // https://developer.token.io/sdk/#profile
  rpc SetProfile (SetProfileRequest) returns (SetProfileResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option deprecated = true;
    option (google.api.http) = {
        put: "/profile"
        body: "*"
    };
  }

  // get a member's profile (display information)
  // https://developer.token.io/sdk/#profile
  rpc GetProfile (GetProfileRequest) returns (GetProfileResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option deprecated = true;
    option (google.api.http) = {
        get: "/members/{member_id}/profile"
    };
  }

  // set member's profile name
  // https://developer.token.io/sdk/#profile
  rpc SetProfileName (SetProfileNameRequest) returns (SetProfileNameResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      put: "/members/profile-name"
      body: "*"
      additional_bindings {
        put: "/members/{member_id}/profile-name"
        body: "*"
      }
    };
  }

  // get a member's profile name
  // https://developer.token.io/sdk/#profile
  rpc GetProfileName (GetProfileNameRequest) returns (GetProfileNameResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      get: "/members/{member_id}/profile-name"
    };
  }

  // upload an image to use as auth'd member's profile picture
  // Automatically creates smaller sizes; this works best with square images.
  // https://developer.token.io/sdk/#profile
  rpc SetProfilePicture (SetProfilePictureRequest) returns (SetProfilePictureResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        put: "/profilepicture"
        body: "*"
    };
  }

  // Get member's profile picture (can also use GetBlob with a blob ID from profile)
  // https://developer.token.io/sdk/#profile
  rpc GetProfilePicture (GetProfilePictureRequest) returns (GetProfilePictureResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        get: "/members/{member_id}/profilepicture/{size}"
    };
  }

  // Set a member's contact (e.g. email) for receipt delivery
  rpc SetReceiptContact (SetReceiptContactRequest) returns (SetReceiptContactResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        put: "/receipt-contact"
        body: "*"
    };
  }

  // Get a member's email address for receipts
  rpc GetReceiptContact (GetReceiptContactRequest) returns (GetReceiptContactResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        get: "/receipt-contact"
    };
  }

  // Get ID of member that owns an alias, if any.
  // https://developer.token.io/sdk/#aliases
  rpc ResolveAlias (ResolveAliasRequest) returns (ResolveAliasResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      get: "/resolve-alias"
    };
    option (io.token.proto.extensions.service.rate_limit) = {
      selector: [
        {key: "resolve-alias-remote-address", path: "{REMOTE_ADDRESS}"},
        {key: "resolve-alias-source-developer", path: "{DEVELOPER_ID}"}
      ]
    };
  }

  // Get the auth'd member's aliases.
  // https://developer.token.io/sdk/#aliases
  rpc GetAliases (GetAliasesRequest) returns (GetAliasesResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      get: "/aliases"
    };
  }

  // Use a verification code
  rpc CompleteVerification (CompleteVerificationRequest) returns (CompleteVerificationResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      get: "/verifications/{verification_id}/complete/{code}"
    };
  }

  // Retries verification. For example, if verifying an email alias,
  // re-sends verification-code email to the email address.
  rpc RetryVerification (RetryVerificationRequest) returns (RetryVerificationResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      post: "/verifications"
      body: "*"
    };
    option (io.token.proto.extensions.service.rate_limit) = {
      selector: [
        {key: "resolve-alias-remote-address", path: "{REMOTE_ADDRESS}"},
        {key: "resolve-alias-source-developer", path: "{DEVELOPER_ID}"}
      ]
    };
  }

  // Get auth'd members paired devices (as created by provisionDevice)
  rpc GetPairedDevices (GetPairedDevicesRequest) returns (GetPairedDevicesResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option deprecated = true;
    option (google.api.http) = {
      get: "/members/devices"
    };
  }

  rpc DeleteMember (DeleteMemberRequest) returns (DeleteMemberResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      delete: "/members"
    };
  }

  rpc NormalizeAlias (NormalizeAliasRequest) returns (NormalizeAliasResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        get: "/aliases/normalize/{alias.type}/{alias.value}/{alias.realm}"
    };
  }

  rpc SetAppCallbackUrl (SetAppCallbackUrlRequest) returns (SetAppCallbackUrlResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        put: "/members/app-callback-url"
        body: "*"
    };
  }

  rpc GetRedirectUrls (GetRedirectUrlsRequest) returns (GetRedirectUrlsResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      get: "/redirect-urls"
    };
  }

  rpc AddRedirectUrls (AddRedirectUrlsRequest) returns (AddRedirectUrlsResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      put: "/redirect-urls"
      body: "*"
    };
  }

  rpc RemoveRedirectUrls (RemoveRedirectUrlsRequest) returns (RemoveRedirectUrlsResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      delete: "/redirect-urls"
      body: "*"
    };
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Member account recovery
  //

  // Begin member recovery. If the member has a "normal consumer" recovery rule,
  // this sends a recovery message to their email address.
  // https://developer.token.io/sdk/#recovery
  rpc BeginRecovery (BeginRecoveryRequest) returns (BeginRecoveryResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      post: "/recovery/verifications"
      body: "*"
    };
    option (io.token.proto.extensions.service.rate_limit) = {
      selector: [
        {key: "resolve-alias-remote-address", path: "{REMOTE_ADDRESS}"},
        {key: "resolve-alias-source-developer", path: "{DEVELOPER_ID}"}
      ]
    };
  }

  // Complete member recovery.
  // https://developer.token.io/sdk/#recovery
  rpc CompleteRecovery (CompleteRecoveryRequest) returns (CompleteRecoveryResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      post: "/recovery/verifications/{verification_id}/complete/{code}"
      body: "*"
    };
  }

  // Verify an alias
  rpc VerifyAlias (VerifyAliasRequest) returns (VerifyAliasResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      put: "/verifications/{verification_id}/complete/{code}"
      body: "*"
    };
  }

  // Verify an eidas
  rpc VerifyEidas (VerifyEidasRequest) returns (VerifyEidasResponse) {
    option (grpcbridge.swagger.operation) = {
      tags: "eidas"
      summary: "Submit an eIDAS certificate for verification."
      description: "Submit an eIDAS certificate for a business member registered under the realm of a bank.<br>"
                   "**See also:**<br>"
                   "[VerifyEidas](https://developer.token.io/token_rest_api_doc/content/k-eidas/verify_eidas.htm)<br>"
                   "[Certificate and payload signature format](https://developer.token.io/token_rest_api_doc/content/k-eidas/member_onboarding.htm?tocpath=eIDAS-related%20REST%20API%20Calls%20for%20Certificate%20Registration%20and%20Verification%7CMember%20Onboarding#Certific)"
    };
    option (google.api.http) = {
      post: "/eidas/verifications"
      body: "*"
      additional_bindings {
        put: "/verifications/eidas"
        body: "*"
      }
    };
  }

  rpc GetEidasVerificationStatus (GetEidasVerificationStatusRequest) returns (GetEidasVerificationStatusResponse) {
    option (grpcbridge.swagger.operation) = {
      tags: "eidas"
      summary: "Get a status of an eIDAS verification."
      description: "Given a verificationId, get a status of the eIDAS verification together with submitted certificate and alias value.<br>"
                   "**See also:**<br>"
                   "[GetEidasVerificationStatus](https://developer.token.io/token_rest_api_doc/content/k-eidas/get_eidas_verification_status.htm)<br>"
    };
    option (google.api.http) = {
      get: "/eidas/verifications/{verification_id}"
    };
  }

  rpc getEidasCertificateStatus (GetEidasCertificateStatusRequest) returns (GetEidasCertificateStatusResponse) {
    option (grpcbridge.swagger.operation) = {
      tags: "eidas"
      summary: "Get a status of the current eIDAS certificate."
      description: "Get a status of an eIDAS certificate on file together with the certificate itself."
                   "**See also:**<br>"
                   "[GetEidasCertificateStatus](https://developer.token.io/token_rest_api_doc/content/k-eidas/get_eidas_certificate.htm)<br>"
    };
    option (google.api.http) = {
      get: "/eidas/status"
    };
  }

  // Recover an eidas-verified member
  rpc RecoverEidasMember (RecoverEidasRequest) returns (RecoverEidasResponse) {
    option (grpcbridge.swagger.operation) = {
      tags: "eidas"
      summary: "Recover an eIDAS-verified member"
      description: "Recover a business member that was onboarded with an eIDAS certificate under a realm of a bank."
                   "**See also:**<br>"
                   "[RecoverEidasMember](https://developer.token.io/token_rest_api_doc/content/k-eidas/recover_eidas_member.htm)<br>"
                   "[Certificate and payload signature format](https://developer.token.io/token_rest_api_doc/content/k-eidas/member_onboarding.htm?tocpath=eIDAS-related%20REST%20API%20Calls%20for%20Certificate%20Registration%20and%20Verification%7CMember%20Onboarding#Certific)"
    };
    option (google.api.http) = {
      post: "/eidas/recovery/operations"
      body: "*"
    };
  }

  // Get member ID of "normal consumer" recovery agent.
  // https://developer.token.io/sdk/#recovery
  rpc GetDefaultAgent (GetDefaultAgentRequest) returns (GetDefaultAgentResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      get: "/recovery/defaults/agent"
    };
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Member addresses and preferences
  //

  // Add a shipping address
  // https://developer.token.io/sdk/#address
  rpc AddAddress (AddAddressRequest) returns (AddAddressResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option deprecated = true;
    option (google.api.http) = {
        post: "/addresses"
        body: "*"
    };
  }

  // Get one of the auth'd member's shipping addresses
  // https://developer.token.io/sdk/#address
  rpc GetAddress (GetAddressRequest) returns (GetAddressResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option deprecated = true;
    option (google.api.http) = {
        get: "/addresses/{address_id}"
    };
  }

  // Get all of the auth'd member's shipping addresses
  // https://developer.token.io/sdk/#address
  rpc GetAddresses (GetAddressesRequest) returns (GetAddressesResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option deprecated = true;
    option (google.api.http) = {
        get: "/addresses"
    };
  }

  // Remove one of the auth'd member's shipping addresses
  // https://developer.token.io/sdk/#address
  rpc DeleteAddress (DeleteAddressRequest) returns (DeleteAddressResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option deprecated = true;
    option (google.api.http) = {
        delete: "/addresses/{address_id}"
    };
  }

  // Set Customization
  // https://developer.token.io/sdk/#customization
  rpc CreateCustomization (CreateCustomizationRequest) returns (CreateCustomizationResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option deprecated = true;
    option (google.api.http) = {
        post: "/customization"
        body: "*"
    };
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Devices for notification service
  //

  // subscribe member to notifications
  // https://developer.token.io/sdk/#notifications
  rpc SubscribeToNotifications (SubscribeToNotificationsRequest) returns (SubscribeToNotificationsResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        post: "/subscribers"
        body: "*"
    };
  }

  // get member's notification subscriber[s]
  // https://developer.token.io/sdk/#notifications
  rpc GetSubscribers (GetSubscribersRequest) returns (GetSubscribersResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        get: "/subscribers"
    };
  }

  // get one of a member's notification subscribers
  // https://developer.token.io/sdk/#notifications
  rpc GetSubscriber (GetSubscriberRequest) returns (GetSubscriberResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        get: "/subscribers/{subscriber_id}"
    };
  }

  // unsubscribe one of a member's subscribers from notifications
  // https://developer.token.io/sdk/#notifications
  rpc UnsubscribeFromNotifications (UnsubscribeFromNotificationsRequest) returns (UnsubscribeFromNotificationsResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        delete: "/subscribers/{subscriber_id}"
    };
  }

  // send a notification
  // https://developer.token.io/sdk/#notifications
  rpc Notify (NotifyRequest) returns (NotifyResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        post: "/notify"
        body: "*"
    };
    option (io.token.proto.extensions.service.rate_limit) = {
      selector: [
        {key: "notify-source-ip", path: "{REMOTE_ADDRESS}"},
        {key: "notify-source-developer", path: "{DEVELOPER_ID}"}
      ]
    };
  }

  // get notifications
  // https://developer.token.io/sdk/#polling-for-notifications
  rpc GetNotifications (GetNotificationsRequest) returns (GetNotificationsResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        get: "/notifications"
    };
  }

  // get one particular notification
  // https://developer.token.io/sdk/#polling-for-notifications
  rpc GetNotification (GetNotificationRequest) returns (GetNotificationResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        get: "/notifications/{notification_id}"
    };
  }

  // send transfer-request notification
  // https://developer.token.io/sdk/#request-payment
  rpc RequestTransfer (RequestTransferRequest) returns (RequestTransferResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        post: "/request-transfer"
        body: "*"
    };
    option (io.token.proto.extensions.service.rate_limit) = {
      selector: [
        {key: "notify-source-ip", path: "{REMOTE_ADDRESS}"},
        {key: "notify-source-developer", path: "{DEVELOPER_ID}"}
      ]
    };
  }

  // send step-up (approve with higher-privilege key) request notification
  rpc TriggerStepUpNotification (TriggerStepUpNotificationRequest) returns (TriggerStepUpNotificationResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        post: "/notify/stepup"
        body: "*"
    };
  }

  // send endorse and add key notification (approve with higher-privilege key)
  rpc TriggerEndorseAndAddKeyNotification (TriggerEndorseAndAddKeyNotificationRequest) returns (TriggerEndorseAndAddKeyNotificationResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option deprecated = true;         // Use CreateAndEndorseToken instead
    option (google.api.http) = {
        post: "/notify/endorse-and-add-key"
        body: "*"
    };
  }

  // send create and endorse token notification
  rpc TriggerCreateAndEndorseTokenNotification (TriggerCreateAndEndorseTokenNotificationRequest) returns (TriggerCreateAndEndorseTokenNotificationResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        post: "/notify/create-and-endorse-token"
        body: "*"
    };
  }

  // send invalidate notification
  rpc InvalidateNotification (InvalidateNotificationRequest) returns (InvalidateNotificationResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        post: "/notify/invalidate-notification"
        body: "*"
    };
  }

  // update notification status
  rpc UpdateNotificationStatus (UpdateNotificationStatusRequest) returns (UpdateNotificationStatusResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        put: "/notifications/{notification_id}/status"
        body: "*"
    };
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Bank accounts.
  //

  // associate bank accounts with member
  // https://developer.token.io/sdk/#link-a-bank-account
  rpc LinkAccounts (LinkAccountsRequest) returns (LinkAccountsResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        post: "/accounts"
        body: "*"
    };
  }

  // associate bank accounts with member
  // https://developer.token.io/sdk/#link-a-bank-account
  rpc LinkAccountsOauth (LinkAccountsOauthRequest) returns (LinkAccountsOauthResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        post: "/bank-accounts"
        body: "*"
    };
  }

  // un-associate bank accounts with member
  // https://developer.token.io/sdk/#link-a-bank-account
  rpc UnlinkAccounts (UnlinkAccountsRequest) returns (UnlinkAccountsResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        delete: "/accounts"
        body: "*"
    };
  }

  // get info about one linked account
  // https://developer.token.io/sdk/#get-accounts
  rpc GetAccount (GetAccountRequest) returns (GetAccountResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "accounts"
        summary: "Retrieve account information"
        description: "Given user consent, retrieve information for a specific bank account"
    };
    option (google.api.http) = {
        get: "/accounts/{account_id}"
    };
    option (io.token.proto.extensions.method.kafka_topic) = "account";
  }

  // get info about linked accounts
  // https://developer.token.io/sdk/#get-accounts
  rpc GetAccounts (GetAccountsRequest) returns (GetAccountsResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "accounts"
        summary: "Retrieve information for all accounts"
        description: "Given user consent, retrieve information for all bank accounts"
    };
    option (google.api.http) = {
        get: "/accounts"
    };
    option (io.token.proto.extensions.method.kafka_topic) = "account";
  }

  // get current and available balance for a linked account
  // https://developer.token.io/sdk/#get-account-balance
  rpc GetBalance (GetBalanceRequest) returns (GetBalanceResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "accounts"
        summary: "Retrieve account balances"
        description: "Given user consent, retrieve balances for a specific bank account"
    };
    option (google.api.http) = {
        get: "/accounts/{account_id}/balance"
    };
    option (io.token.proto.extensions.method.kafka_topic) = "account_balance";
  }

  rpc GetBalances (GetBalancesRequest) returns (GetBalancesResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "accounts"
        summary: "Retrieve multiple account balances"
        description: "Given user consent, retrieve balances for multiple bank accounts"
    };
    option (google.api.http) = {
        get: "/account-balance"
    };
    option (io.token.proto.extensions.method.kafka_topic) = "account_balance";
  }

  // get information about a particular transaction
  // https://developer.token.io/sdk/#get-transactions
  rpc GetTransaction (GetTransactionRequest) returns (GetTransactionResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "accounts"
        summary: "Retrieve transaction information"
        description: "Given user consent, retrieve information for a specific transaction in account"
    };
    option (google.api.http) = {
        get: "/accounts/{account_id}/transaction/{transaction_id}"
    };
    option (io.token.proto.extensions.method.kafka_topic) = "account_transaction";
  }

  // get information about several transactions
  // https://developer.token.io/sdk/#get-transactions
  rpc GetTransactions (GetTransactionsRequest) returns (GetTransactionsResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "accounts"
        summary: "Retrieve all transactions for an account"
        description: "Given user consent, retrieve information for all transactions in account"
    };
    option (google.api.http) = {
        get: "/accounts/{account_id}/transactions"
    };
    option (io.token.proto.extensions.method.kafka_topic) = "account_transaction";
  }

  // get information about a particular standing order
  rpc GetStandingOrder (GetStandingOrderRequest) returns (GetStandingOrderResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "accounts"
        summary: "Retrieve standing order information"
        description: "GIven user consent, retrieve information about a specific standing order in account"
    };
    option (google.api.http) = {
        get: "/accounts/{account_id}/standing-orders/{standing_order_id}"
    };
    option (io.token.proto.extensions.method.kafka_topic) = "account_standing_order";
  }

  // get information about several standing orders
  rpc GetStandingOrders (GetStandingOrdersRequest) returns (GetStandingOrdersResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "accounts"
        summary: "Retrieve information about all standing orders"
        description: "Given user consent, retrieve information about all standing orders in account"
    };
    option (google.api.http) = {
        get: "/accounts/{account_id}/standing-orders"
    };
    option (io.token.proto.extensions.method.kafka_topic) = "account_standing_order";
  }

  rpc ApplySca (ApplyScaRequest) returns (ApplyScaResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        put: "/accounts/sca"
        body: "*"
    };
    option (io.token.proto.extensions.method.kafka_topic) = "account";
  }

  // Get information about the auth'd member's default account.
  // https://developer.token.io/sdk/#default-bank-account
  rpc GetDefaultAccount (GetDefaultAccountRequest) returns (GetDefaultAccountResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      get: "/members/{member_id}/default-account"
    };
  }

  // Set one auth'd member's accounts as its default account.
  // https://developer.token.io/sdk/#default-bank-account
  rpc SetDefaultAccount (SetDefaultAccountRequest) returns (SetDefaultAccountResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      put: "/members/{member_id}/default-account"
      body: "*"
    };
  }

  // Get the resolved transfer destinations of the given account.
  rpc ResolveTransferDestinations (ResolveTransferDestinationsRequest) returns (ResolveTransferDestinationsResponse) {
  option deprecated = true; // AccountIdentifier is now populated in Account.AccountDetails - no need to resolve it anymore
    option (grpcbridge.swagger.operation) = {
        tags: "accounts"
        summary: "Get transfer destination"
        description: "Given user consent, get details needed to use the account as a transfer destination"
        deprecated: true
    };
    option (google.api.http) = {
      get: "/accounts/{account_id}/transfer-destinations"
    };
  }

  // Confirm that the given account has sufficient funds to cover the charge.
  rpc ConfirmFunds (ConfirmFundsRequest) returns (ConfirmFundsResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "accounts"
        summary: "Confirm available funds"
        description: "Given user consent, check that sufficient funds are available in account"
    };
    option (google.api.http) = {
      put: "/accounts/{account_id}/funds-confirmation"
      body: "*"
    };
    option (io.token.proto.extensions.method.kafka_topic) = "account";
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Testing.
  //

  // Create a test account at "iron" test bank.
  // https://developer.token.io/sdk/#link-a-bank-account
  rpc CreateTestBankAccount (CreateTestBankAccountRequest) returns (CreateTestBankAccountResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        post: "/test/create-account"
        body: "*"
    };
  }

  // Get notification from "iron" test bank. Useful for Token when testing its test bank.
  // Normal way to get a notification is GetNotification.
  rpc GetTestBankNotification (GetTestBankNotificationRequest) returns (GetTestBankNotificationResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        get: "/test/subscribers/{subscriber_id}/notifications/{notification_id}"
    };
  }

  // Get notifications from "iron" test bank. Useful for Token when testing its test bank.
  // Normal way to get notifications is GetNotifications.
  rpc GetTestBankNotifications (GetTestBankNotificationsRequest) returns (GetTestBankNotificationsResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        get: "/test/subscribers/{subscriber_id}/notifications"
    };
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Blobs.
  //

  // Create a blob.
  // https://developer.token.io/sdk/#transfer-token-options
  rpc CreateBlob (CreateBlobRequest) returns (CreateBlobResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        post: "/blobs"
        body: "*"
    };
  }

  // Fetch a blob. Works if the authenticated member is the blob's
  // owner or if the blob is public-access.
  // https://developer.token.io/sdk/#transfer-token-options
  rpc GetBlob (GetBlobRequest) returns (GetBlobResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        get: "/blobs/{blob_id}"
    };
  }

  // Fetch a blob using a Token's authority. Works if Blob is attached to token
  // and authenticated member is the Token's "from" or "to".
  // https://developer.token.io/sdk/#transfer-token-options
  rpc GetTokenBlob (GetTokenBlobRequest) returns (GetTokenBlobResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option deprecated = true;
    option (google.api.http) = {
        get: "/tokens/{token_id}/blobs/{blob_id}"
    };
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Tokens Requests.
  //

  // Store a Token Request
  rpc StoreTokenRequest (StoreTokenRequestRequest) returns (StoreTokenRequestResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "requests"
        summary: "Create a token request"
        description: "Persists required information used by the Token web app to complete a transaction"
    };
    option (google.api.http) = {
        post: "/token-requests"
        body: "*"
    };
    option (io.token.proto.extensions.method.kafka_topic) = "token_request";
  }

  // Retrieve a Token Request
  rpc RetrieveTokenRequest (RetrieveTokenRequestRequest) returns (RetrieveTokenRequestResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "requests"
        summary: "Find a token request"
        description: "Retrieves a specific token request by token ID"
    };
    option (google.api.http) = {
        get: "/token-requests/{request_id}"
    };
  }

  rpc UpdateTokenRequest (UpdateTokenRequestRequest) returns (UpdateTokenRequestResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        put: "/token-requests/{request_id}"
        body: "*"
    };
    option (io.token.proto.extensions.method.kafka_topic) = "token_request";
  }

  rpc SetTokenRequestTransferDestinations(SetTokenRequestTransferDestinationsRequest) returns (SetTokenRequestTransferDestinationsResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        put: "/token-requests/{token_request_id}/transfer-destinations"
        body: "*"
    };
  }

  // populate mandatory fields values together with bankId for the given payload (if not populated yet)
  rpc SetTokenRequestMandatoryFields (SetTokenRequestMandatoryFieldsRequest) returns (SetTokenRequestMandatoryFieldsResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        put: "/token-requests/{token_request_id}/mandatory-fields"
        body: "*"
    };
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Tokens.
  //

  // Prepare a token (resolve token payload and determine policy)
  rpc PrepareToken (PrepareTokenRequest) returns (PrepareTokenResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        post: "/tokens/prepare"
        body: "*"
    };
  }

  // Create a Token.
  rpc CreateToken (CreateTokenRequest) returns (CreateTokenResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        post: "/tokens"
        body: "*"
    };
    option (io.token.proto.extensions.service.rate_limit) = {
      selector: [
        {key: "resolve-alias-remote-address", path: "{REMOTE_ADDRESS}"},
        {key: "resolve-alias-source-developer", path: "{DEVELOPER_ID}"}
      ]
    };
    option (io.token.proto.extensions.method.kafka_topic) = "transfer_token";
  }

  // Create a Transfer Token.
  // https://developer.token.io/sdk/#create-transfer-token
  rpc CreateTransferToken (CreateTransferTokenRequest) returns (CreateTransferTokenResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        // unused: use /tokens?type=transfer to reach this endpoint
        post: "/transfer-tokens"
        body: "*"
    };
    option (io.token.proto.extensions.service.rate_limit) = {
      selector: [
        {key: "resolve-alias-remote-address", path: "{REMOTE_ADDRESS}"},
        {key: "resolve-alias-source-developer", path: "{DEVELOPER_ID}"}
      ]
    };
    option deprecated = true; // use CreateToken instead
  }

  // Create an Access Token.
  // https://developer.token.io/sdk/#create-access-token
  rpc CreateAccessToken (CreateAccessTokenRequest) returns (CreateAccessTokenResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        // unused: use /tokens?type=access to reach this endpoint
        post: "/access-tokens"
        body: "*"
    };
    option (io.token.proto.extensions.service.rate_limit) = {
      selector: [
        {key: "resolve-alias-remote-address", path: "{REMOTE_ADDRESS}"},
        {key: "resolve-alias-source-developer", path: "{DEVELOPER_ID}"}
      ]
    };
  }

  // Get information about one token.
  // https://developer.token.io/sdk/#redeem-transfer-token
  rpc GetToken (GetTokenRequest) returns (GetTokenResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "tokens"
        summary: "Find a token"
        description: "Get information about a specific token for the authenticated member"
    };
    option (google.api.http) = {
        get: "/tokens/{token_id}"
    };
  }

  // Get existing Access Token where the calling member is the
  // remitter and provided member is the beneficiary.
  rpc GetActiveAccessToken (GetActiveAccessTokenRequest) returns (GetActiveAccessTokenResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        get: "/tokens/active-access-token/{to_member_id}"
    };
  }

  // Gets list of tokens the member has given/received.
  // Used by getTransferTokens, getAccessTokens.
  // https://developer.token.io/sdk/#get-tokens
  // https://developer.token.io/sdk/#replace-access-token
  rpc GetTokens (GetTokensRequest) returns (GetTokensResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "tokens"
        summary: "Retrieve a list of tokens"
        description: "Get a list of all tokens for the authenticated member"
    };
    option (google.api.http) = {
        get: "/tokens"
    };
  }

  // Endorse a token
  // https://developer.token.io/sdk/#endorse-transfer-token
  // https://developer.token.io/sdk/#endorse-access-token
  rpc EndorseToken (EndorseTokenRequest) returns (EndorseTokenResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        put: "/tokens/{token_id}/endorse"
        body: "*"
    };
  }

  // Cancel a token
  // https://developer.token.io/sdk/#cancel-transfer-token
  // https://developer.token.io/sdk/#cancel-access-token
  rpc CancelToken (CancelTokenRequest) returns (CancelTokenResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "tokens"
        summary: "Cancel a token"
        description: "Cancel a specific token by Token ID"
    };
    option (google.api.http) = {
        put: "/tokens/{token_id}/cancel"
        body: "*"
    };
  }

  // Replace an access token
  // https://developer.token.io/sdk/#replace-access-token
  //
  // See how replaceAndEndorseToken uses it:
  //   https://developer.token.io/sdk/esdoc/class/src/http/AuthHttpClient.js~AuthHttpClient.html#instance-method-replaceAndEndorseToken
  rpc ReplaceToken (ReplaceTokenRequest) returns (ReplaceTokenResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        post: "/tokens/{cancel_token.token_id}/replace"
        body: "*"
    };
  }

  // Request a Token signature on a token request state payload (tokenId | state)
  rpc SignTokenRequestState (SignTokenRequestStateRequest) returns (SignTokenRequestStateResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        put: "/sign-token-request-state"
        body: "*"
    };
  }

  // Get the token request result from the token request id
  rpc GetTokenRequestResult (GetTokenRequestResultRequest) returns (GetTokenRequestResultResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "requests"
        summary: "Obtain the result of a token request"
        description: "Checks whether a token request result is available"
    };
    option (google.api.http) = {
        get: "/token-requests/{token_request_id}/token_request_result"
    };
  }

  // Get the token request result with status from the token request id
  rpc GetTokenRequestResultWithStatus (GetTokenRequestResultWithStatusRequest) returns (GetTokenRequestResultWithStatusResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "requests"
        summary: "Obtain the result of a token request with the status."
        description: "Checks whether a token request result is available. This endpoint will return "
                     "a PENDING status while the result is not available. The status will become "
                     "PROCESSED once the result is available. If the request is rejected by the "
                     "bank, the status will become REJECTED. The status will become EXPIRED if the "
                     "request is not processed or rejected before the token request expiration."
    };
    option (google.api.http) = {
        get: "/token-requests/{token_request_id}/result"
    };
  }

  // Initiates authorization process with the bank
  rpc InitiateBankAuthorization (InitiateBankAuthorizationRequest) returns (InitiateBankAuthorizationResponse) {
    option (grpcbridge.swagger.operation) = {
      tags: "info"
      summary: "Initiate authorization with the bank"
      description: "Given a bank ID and token request ID, initiate bank authorization process"
    };
    option (google.api.http) = {
      post: "/token-requests/{token_request_id}/authorization"
      body: "*"
    };
  }

  // Gets a payload to sign
  rpc GetAuthRequestPayload (GetAuthRequestPayloadRequest) returns (GetAuthRequestPayloadResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        get: "/auth-request-payloads/{auth_request_id}"
    };
  }

  // Stores a linking request
  rpc StoreLinkingRequest (StoreLinkingRequestRequest) returns (StoreLinkingRequestResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        post: "/linking-requests"
        body: "*"
    };
  }

  // Gets a linking request
  rpc GetLinkingRequest (GetLinkingRequestRequest) returns (GetLinkingRequestResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        get: "/linking-requests/{linking_request_id}"
    };
  }

////////////////////////////////////////////////////////////////////////////////////////////////////
  // Token Transfers.
  //

  // Redeem a transfer token, creating a transfer.
  // https://developer.token.io/sdk/#redeem-transfer-token
  //
  // See how redeemToken calls it:
  //   https://developer.token.io/sdk/esdoc/class/src/http/AuthHttpClient.js~AuthHttpClient.html#instance-method-redeemToken
  rpc CreateTransfer (CreateTransferRequest) returns (CreateTransferResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "transfers"
        summary: "Initiate a bank transfer"
        description: "Creates a request to move money between accounts"
    };
    option (google.api.http) = {
        post: "/transfers"
        body: "*"
    };
    option (io.token.proto.extensions.method.kafka_topic) = "transfer";
  }

  // Redeem a standing order token, creating a standing order submission.
  rpc CreateStandingOrder (CreateStandingOrderRequest) returns (CreateStandingOrderResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "transfers"
        summary: "Create a standing order submisison"
        description: "Submit a request for a standing order creation"
    };
    option (google.api.http) = {
        post: "/standing-order-submissions"
        body: "*"
    };
    option (io.token.proto.extensions.method.kafka_topic) = "transfer_standing_order_submission";
  }

  // Redeem a bulk transfer token, creating a bulk transfer submission.
  rpc CreateBulkTransfer (CreateBulkTransferRequest) returns (CreateBulkTransferResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        post: "/bulk-transfers"
        body: "*"
    };
    option (io.token.proto.extensions.method.kafka_topic) = "transfer_bulk_transfer";
  }

  // Get information about one transfer.
  // https://developer.token.io/sdk/#get-transfers
  rpc GetTransfer (GetTransferRequest) returns (GetTransferResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "transfers"
        summary: "Retrieve a transfer"
        description: "Retrieves information about a specific transfer in account"
    };
    option (google.api.http) = {
        get: "/transfers/{transfer_id}"
    };
  }

  // Get information about one standing order submission
  rpc GetStandingOrderSubmission (GetStandingOrderSubmissionRequest) returns (GetStandingOrderSubmissionResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "transfers"
        summary: "Find a standing order submission"
        description: "Retrieve a standing order submission by its ID"
    };
    option (google.api.http) = {
        get: "/standing-order-submissions/{submission_id}"
    };
  }

  // Get information about one bulk transfer
  rpc GetBulkTransfer (GetBulkTransferRequest) returns (GetBulkTransferResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        get: "/bulk-transfers/{bulk_transfer_id}"
    };
  }

  // Get a list of the auth'd member's submissions.
  // https://developer.token.io/sdk/#get-submissions
  rpc GetTransfers (GetTransfersRequest) returns (GetTransfersResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "transfers"
        summary: "Retrieve all transfers"
        description: "Retrieves information for all transfers in account"
    };
    option (google.api.http) = {
        get: "/transfers"
    };
  }

  // Get a list of the auth'd member's recurring submissions.
  rpc GetStandingOrderSubmissions (GetStandingOrderSubmissionsRequest) returns (GetStandingOrderSubmissionsResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "transfers"
        summary: "Retrieve a list of standing order submissions"
        description: "Retrieve all standing order submissions"
    };
    option (google.api.http) = {
        get: "/standing-order-submissions"
    };
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Bank Information Endpoints.
  //

  // Get a list of "link-able" bank countries.
  rpc GetBanksCountries (GetBanksCountriesRequest) returns (GetBanksCountriesResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "info"
        summary: "Get list of bank countries"
        description: "Retrieve the list of countries with Token-integrated banks"
    };
    option (google.api.http) = {
        get: "/bank/countries"
        additional_bindings {
          get: "/banks/countries" // deprecated
        }
    };
  }

  // Get a list of "link-able" banks.
  // https://developer.token.io/sdk/#link-a-bank-account
  rpc GetBanks (GetBanksRequest) returns (GetBanksResponse) {
    option (grpcbridge.swagger.operation) = {
      tags: "info"
      summary: "Get list of banks matching criteria"
      description: "Retrieve the list of Token-integrated banks matching feature criteria for the selected country"
    };
    option (google.api.http) = {
        get: "/banks"
    };
  }

  rpc GetBanksV2 (GetBanksV2Request) returns (GetBanksV2Response) {
    option (grpcbridge.swagger.exclude) = true; // Only publish the GetBanks in swagger for now.
    option (grpcbridge.swagger.operation) = {
      tags: "info"
      summary: "Get list of banks matching criteria"
      description: "Retrieve the list of Token-integrated banks matching feature criteria for the selected country"
    };
    option (google.api.http) = {
      get: "/v2/banks"
    };
  }

  // Get information useful for linking one bank.
  // https://developer.token.io/sdk/#link-a-bank-account
  rpc GetBankInfo (GetBankInfoRequest) returns (GetBankInfoResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "info"
        summary: "Get bank information"
        description: "Retrieve information about the Token-supported bank identified"
    };
    option (google.api.http) = {
        get: "/banks/{bank_id}/info"
    };
  }

  rpc GetBankAuthUrl (GetBankAuthUrlRequest) returns (GetBankAuthUrlResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "info"
        summary: "Produce bank authorization url"
        description: "Generates a bank authorization url for the given token request id"
    };
    option (google.api.http) = {
      post: "/banks/{bank_id}/token-requests/{token_request_id}/urls"
      body: "*"
      additional_bindings {
        post: "/banks/{bank_id}/token-requests/{token_request_id}"
      }
    };
  }

  rpc GetDirectBankAuthUrl (GetDirectBankAuthUrlRequest) returns (GetDirectBankAuthUrlResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        get: "/banks/{bank_id}/token-requests/{token_request_id}/url"
        additional_bindings {
          get: "/banks/{bank_id}/token-requests/{token_request_id}/auth-url"
        }
    };
    option deprecated = true; // Backward compatibility for web-app
  }


  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // TSP only endpoints
  //
  rpc OnBankAuthCallback (OnBankAuthCallbackRequest) returns (OnBankAuthCallbackResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "tsp"
        summary: "On callback"
        description: "Process bank auth callback notification"
    };
    option (google.api.http) = {
        post: "/callback/initiation"
        body: "*"
        additional_bindings {
          post: "/banks/{bank_id}/callback"
        }
        additional_bindings {
          post: "/bank-auth-callback"
          body: "*"
        }
    };
  }

  rpc GetExternalMetadata (GetExternalMetadataRequest) returns (GetExternalMetadataResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "tsp"
        summary: "Get external metadata"
        description: "Get the external metadata from the bank"
    };
    option (google.api.http) = {
        get: "/token-requests/{token_request_id}/external-metadata"
    };
  }

  rpc StoreBankConfig (StoreBankConfigRequest) returns (StoreBankConfigResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "bankConfigs"
        summary: "Store bank config"
        description: "Store the bank config"
    };
    option (google.api.http) = {
        put: "/members/{member_id}/bank-configs/{bank_id}"
    };
  }

  rpc GetBankConfig (GetBankConfigRequest) returns (GetBankConfigResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "bankConfigs"
        summary: "Get bank config"
        description: "Get the bank config"
    };
    option (google.api.http) = {
        get: "/members/{member_id}/bank-configs/{bank_id}"
    };
  }

  rpc GetBankConfigs (GetBankConfigsRequest) returns (GetBankConfigsResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "bankConfigs"
        summary: "Get bank configs"
        description: "Get all bank configs"
    };
    option (google.api.http) = {
        get: "/members/{member_id}/bank-configs"
    };
  }

  rpc DeleteBankConfig (DeleteBankConfigRequest) returns (DeleteBankConfigResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "bankConfigs"
        summary: "Delete bank config"
        description: "Delete the bank config"
    };
    option (google.api.http) = {
        delete: "/members/{member_id}/bank-configs/{bank_id}"
    };
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Bank member only requests.
  //
  // Get member information about a member who links at least an account from this bank
  rpc GetMemberInfo (GetMemberInfoRequest) returns (GetMemberInfoResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        get: "/members/info/{member_id}"
    };
  }

  rpc GetConsent (GetConsentRequest) returns (GetConsentResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "banks"
        summary: "Gets a consent"
        description: "Gets a consent with the consent id"
    };
    option (google.api.http) = {
        get: "/banks/{bank_id}/consents/{consent_id}"
    };
  }

  rpc GetConsents (GetConsentsRequest) returns (GetConsentsResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        get: "/banks/{bank_id}/consents"
        additional_bindings {
            get: "/consents"
            body: "*"
        }
    };
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Reports (bank member only requests).
  //
  // Get TPP performance report.
  rpc GetTppPerformanceReport (GetTppPerformanceReportRequest) returns (GetTppPerformanceReportResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "banks"
        summary: "Gets the TPP performance report"
        description: "Gets the TPP performance report"
    };
    option (google.api.http) = {
        get: "/banks/{bank_id}/reports/tpp-performance"
        additional_bindings {
            get: "/reports/{bank_id}/tpp_performance_report"
        }
    };
  }

  //Get availability report.
  rpc GetAvailabilityReport (GetAvailabilityReportRequest) returns (GetAvailabilityReportResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "banks"
        summary: "Gets the availability report"
        description: "Gets the availability report"
    };
    option (google.api.http) = {
        get: "/banks/{bank_id}/reports/availability"
        additional_bindings {
            get: "/reports/{bank_id}/availability_report"
        }
    };
  }

  rpc GetTppAccessReport (GetTppAccessReportRequest) returns (GetTppAccessReportResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "banks"
        summary: "Gets the TPP access report"
        description: "Gets the TPP access report"
    };
    option (google.api.http) = {
        get: "/banks/{bank_id}/reports/tpp-access"
        additional_bindings {
            get: "/reports/{bank_id}/tpp_access_report"
        }
    };
  }


  rpc GetServiceHealth (GetServiceHealthRequest) returns (GetServiceHealthResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        get: "reports/service/health"
    };
  }

////////////////////////////////////////////////////////////////////////////////////////////////////
// Reports (portal requests).
//
// Get TPP requests report.
rpc GetTppRequestsReport (GetTppRequestsReportRequest) returns (GetTppRequestsReportResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        get: "/reports/{tpp_member_id}/tpp_requests_report/from/{from_date_ms}/to/{to_date_ms}"
    };
  }

  rpc GetBankDowntimeReport (GetBankDowntimeReportRequest) returns (GetBankDowntimeReportResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
        get: "/reports/{bank_id}/bank_downtime_report/from/{days_back}"
    };
  }

  rpc GetBankStatus (GetBankStatusRequest) returns (GetBankStatusResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "reports"
        summary: "Returns statuses for a bank"
        description: "Indicates when AIS and PIS services are up or down along with bank server"
    };
    option (google.api.http) = {
        get: "/reports/banks/{bank_id}/status"
    };
  }

  rpc GetBanksStatus (GetBanksStatusRequest) returns (GetBanksStatusResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "reports"
        summary: "Returns statuses for all banks"
        description: "Returns the current AIS and PIS service status along with server status for all banks"
    };
    option (google.api.http) = {
        get: "/reports/banks/status"
    };
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // RESTful Bank API
  //
  rpc CreateBankUser (CreateBankUserRequest) returns (CreateBankUserResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "banks"
        summary: "Creates a user"
        description: "Returns a user id in the bank's realm"
    };
    option (google.api.http) = {
        post: "/banks/{bank_id}/users"
    };
  }

  rpc DeleteBankUser (DeleteBankUserRequest) returns (DeleteBankUserResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "banks"
        summary: "Deletes a user"
        description: "Deletes a user by the user id in bank's realm"
    };
    option (google.api.http) = {
        delete: "/banks/{bank_id}/users/{user_id}"
    };
  }

  rpc RetrieveConsentRequest (RetrieveConsentRequestRequest) returns (RetrieveConsentRequestResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "banks"
        summary: "Retrieves a consent request"
        description: "Retrieves a consent request by the request id"
    };
    option (google.api.http) = {
        get: "/banks/{bank_id}/consent-requests/{request_id}"
    };
  }

  rpc CreateConsent (CreateConsentRequest) returns (CreateConsentResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "banks"
        summary: "Creates a consent"
        description: "Creates a consent with a consent request"
    };
    option (google.api.http) = {
        post: "/banks/{bank_id}/consents"
        body: "*"
    };
  }

  rpc CancelConsent (CancelConsentRequest) returns (CancelConsentResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "banks"
        summary: "Cancels a consent"
        description: "Cancels a consent with the consent id"
    };
    option (google.api.http) = {
        delete: "/banks/{bank_id}/consents/{consent_id}"
    };
  }

  rpc GetActiveAccessConsents (GetActiveAccessConsentsRequest) returns (GetActiveAccessConsentsResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "banks"
        summary: "Get active access consents"
        description: "Returns active access consents for a user id"
    };
    option (google.api.http) = {
        post: "/banks/{bank_id}/users/{user_id}/access-consents"
    };
  }

  rpc GetAccessConsents (GetAccessConsentsRequest) returns (GetAccessConsentsResponse) {
    option (grpcbridge.swagger.operation) = {
        tags: "banks"
        summary: "Get access consents"
        description: "Returns access consents for a user id"
    };
    option (google.api.http) = {
        get: "/banks/{bank_id}/users/{user_id}/access-consents"
    };
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Partner endpoints
  //
  rpc EnableMember (EnableMemberRequest) returns (EnableMemberResponse) {
    option (grpcbridge.swagger.operation) = {
      tags: "partner"
      summary: "Enables a member"
      description: "Enables a member that's under the realm of the partner"
    };
    option (google.api.http) = {
      put: "/partner/members/{member_id}/enable"
    };
  }

  rpc DisableMember (DisableMemberRequest) returns (DisableMemberResponse) {
    option (grpcbridge.swagger.operation) = {
      tags: "partner"
      summary: "Disables a member"
      description: "Disables a member that's under the realm of the partner"
    };
    option (google.api.http) = {
      put: "/partner/members/{member_id}/disable"
    };
  }

  rpc GetMembersUnderPartner (GetMembersUnderPartnerRequest) returns (GetMembersUnderPartnerResponse) {
    option (grpcbridge.swagger.operation) = {
      tags: "partner"
      summary: "Get a list of members"
      description: "Get a list of members registered under the realm of the partner"
    };
    option (google.api.http) = {
      get: "/partner/members"
    };
  }

  rpc SetDefaultCustomization (SetDefaultCustomizationRequest) returns (SetDefaultCustomizationResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (grpcbridge.swagger.operation) = {
      tags: "partner"
      summary: "Sets partner's default customization."
      description: "Sets a customization that should be used by the businesses under the realm of the partner."
    };
    option (google.api.http) = {
      put: "/partner/customization/{customization_id}"
    };
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Webhook endpoints
  //
  rpc SetWebhookConfig (SetWebhookConfigRequest) returns (SetWebhookConfigResponse) {
    option (grpcbridge.swagger.operation) = {
      tags: "webhook"
      summary: "Sets the webhook config"
      description: "Sets the webhook config"
    };
    option (google.api.http) = {
      put: "/webhook/config"
      body: "*"
    };
  }

  rpc GetWebhookConfig (GetWebhookConfigRequest) returns (GetWebhookConfigResponse) {
    option (grpcbridge.swagger.operation) = {
      tags: "webhook"
      summary: "Gets the webhook config"
      description: "Gets the webhook config"
    };
    option (google.api.http) = {
      get: "/webhook/config"
    };
  }

  rpc DeleteWebhookConfig (DeleteWebhookConfigRequest) returns (DeleteWebhookConfigResponse) {
    option (grpcbridge.swagger.operation) = {
      tags: "webhook"
      summary: "Deletes the webhook config"
      description: "Deletes the webhook config"
    };
    option (google.api.http) = {
      delete: "/webhook/config"
    };
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Validation endpoints
  //
  rpc ValidateIban (ValidateIbanRequest) returns (ValidateIbanResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      post: "/validations/iban"
      body: "*"
    };
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Sub Tpp endpoints
  //
  rpc CreateSubTpp (CreateSubTppRequest) returns (CreateSubTppResponse) {
    option (grpcbridge.swagger.operation) = {
      tags: "subTpp"
      summary: "Create a new sub tpp"
      description: "Creates a sub tpp for the reseller"
    };
    option (google.api.http) = {
      post: "/member/sub-tpps"
      body: "*"
    };
  }

  rpc DeleteSubTpp (DeleteSubTppRequest) returns (DeleteSubTppResponse) {
    option (grpcbridge.swagger.operation) = {
      tags: "subTpp"
      summary: "Delete an existing sub tpp"
      description: "Deletes the sub tpp for the reseller"
    };
    option (google.api.http) = {
      delete: "/member/sub-tpps/{sub_tpp_id}"
    };
  }

  rpc RetrieveSubTpp (RetrieveSubTppRequest) returns (RetrieveSubTppResponse) {
    option (grpcbridge.swagger.operation) = {
      tags: "subTpp"
      summary: "Retrieves the sub tpp details"
      description: "Retrieves the sub tpp for the reseller"
    };
    option (google.api.http) = {
      get: "/member/sub-tpps/{sub_tpp_id}"
    };
  }

  rpc RetrieveSubTpps (RetrieveSubTppsRequest) returns (RetrieveSubTppsResponse) {
    option (grpcbridge.swagger.operation) = {
      tags: "subTpp"
      summary: "Retrieves all the sub tpps"
      description: "Retrieves all the sub tpps for the reseller"
    };
    option (google.api.http) = {
      get: "/member/sub-tpps"
    };
  }

  rpc RetrieveSubTppChildren (RetrieveSubTppChildrenRequest) returns (RetrieveSubTppChildrenResponse) {
    option (grpcbridge.swagger.operation) = {
      tags: "subTpp"
      summary: "Retrieves the sub tpp children"
      description: "Retrieves the sub tpp children for the provided sub tpp id"
    };
    option (google.api.http) = {
      get: "/member/sub-tpps/{sub_tpp_id}/children"
    };
  }

  rpc UpdateSubTpp (UpdateSubTppRequest) returns (UpdateSubTppResponse) {
    option (grpcbridge.swagger.operation) = {
      tags: "subTpp"
      summary: "Updates the sub tpp"
      description: "Updates the sub tpp"
    };
    option (google.api.http) = {
      put: "/member/sub-tpps/{sub_tpp_id}"
      body: "*"
    };
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Refund feature endpoints
  //
  // TODO: remove START: Deprecated by PLT-4728
  rpc RegisterForRefund (PayoutRegisterRequest) returns (PayoutRegisterResponse) {
    option (google.api.http) = {
      post: "/refund/registrations"
      body: "*"
    };
  }

  rpc GetRefundRegistration (GetPayoutRegistrationRequest) returns (GetPayoutRegistrationResponse) {
    option (google.api.http) = {
      get: "/refund/registrations/{registration_id}"
    };
  }

  rpc DeleteRefundRegistration (DeletePayoutRegistrationRequest) returns (EmptyResponse) {
    option (google.api.http) = {
      delete: "/refund/registrations/{registration_id}"
    };
  }
  // TODO: remove END: Deprecated by PLT-4728

  rpc InitiateRefund (InitiateRefundRequest) returns (InitiateRefundResponse) {
    option (google.api.http) = {
      post: "/refunds"
      body: "*"
    };
    option (io.token.proto.extensions.method.kafka_topic) = "refund";
  }

  rpc GetRefund (GetRefundRequest) returns (GetRefundResponse) {
    option (google.api.http) = {
      get: "/refunds/{refund_id}"
    };
  }

  rpc GetRefunds (GetRefundsRequest) returns (GetRefundsResponse) {
    option (google.api.http) = {
      get: "/refunds"
    };
  }

  rpc GetRefundsByPaymentId (GetRefundsByPaymentIdRequest) returns (GetRefundsByPaymentIdResponse) {
    option (google.api.http) = {
      get: "/transfers/{payment_id}/refunds"
    };
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Payout feature endpoints
  //

  rpc createPayout (CreatePayoutRequest) returns (CreatePayoutResponse) {
    option (grpcbridge.swagger.exclude) = true; // We will disable autogenerated swagger
    option (google.api.http) = {
      post: "/payouts"
      body: "*"
    };
  }

  rpc GetPayoutByPayoutId (GetPayoutByPayoutIdRequest) returns (GetPayoutByPayoutIdResponse) {
    option (grpcbridge.swagger.exclude) = true; // We will disable autogenerated swagger
    option (google.api.http) = {
      get: "/payouts/{id}"
    };
  }

  rpc GetPayouts (GetPayoutsRequest) returns (GetPayoutsResponse) {
    option (grpcbridge.swagger.exclude) = true; // We will disable autogenerated swagger
    option (google.api.http) = {
      get: "/payouts"
    };
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Open Banking V2.
  //
  rpc CreatePaymentV2 (CreatePaymentV2Request) returns (PaymentV2Response) {
    option (google.api.http) = {
      post: "/v2/payments"
      body: "*"
    };
  }

  rpc GetPaymentV2 (GetPaymentV2Request) returns (PaymentV2Response) {
    option (google.api.http) = {
      get: "/v2/payments/{payment_id}"
    };
  }

  rpc ProvidePaymentEmbeddedAuthV2 (ProvidePaymentEmbeddedAuthV2Request) returns (PaymentV2Response) {
    option (google.api.http) = {
        post: "/v2/payments/{payment_id}/embedded-auth"
        body: "*"
      };
  }

  rpc RedeemPaymentV2 (RedeemPaymentV2Request) returns (PaymentV2Response) {
    option (google.api.http) = {
      post: "/v2/payments/{payment_id}/redeem"
      body: "*"
    };
  }

  rpc GetPaymentsV2 (GetPaymentsV2Request) returns (GetPaymentsV2Response) {
    option (google.api.http) = {
      get: "/v2/payments"
    };
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // VRP endpoints
  //
  rpc CreateVrpConsent (CreateVrpConsentRequest) returns (VrpConsentResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      post: "/vrp-consents"
      body: "*"
    };
  }

  rpc GetVrpConsent (GetVrpConsentRequest) returns (VrpConsentResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      get: "/vrp-consents/{vrp_consent_id}"
    };
  }

  rpc RevokeVrpConsent (RevokeVrpConsentRequest) returns (VrpConsentResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      delete: "/vrp-consents/{vrp_consent_id}"
    };
  }

  rpc GetVrpConsents (GetVrpConsentsRequest) returns (GetVrpConsentsResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      get: "/vrp-consents"
    };
  }

  rpc GetVrpConsentPayments (GetVrpConsentPaymentsRequest) returns (GetVrpConsentPaymentsResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      get: "/vrp-consents/{vrp_consent_id}/payments"
    };
  }

  rpc CreateVrp (CreateVrpRequest) returns (VrpResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      post: "/vrps"
      body: "*"
    };
  }

  rpc GetVrp (GetVrpRequest) returns (VrpResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      get: "/vrps/{vrp_id}"
    };
  }

  rpc GetVrps (GetVrpsRequest) returns (GetVrpsResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      get: "/vrps"
    };
  }

  rpc ConfirmFundsAvailability (ConfirmFundsAvailabilityRequest) returns (ConfirmFundsAvailabilityResponse) {
    option (google.api.http) = {
      get: "/vrps/{vrp_consent_id}/confirm-funds"
    };
  }

////////////////////////////////////////////////////////////////////////////////////////////////////
// Payment Restrictions endpoints
//
  rpc CreateRestriction (CreateRestrictionRequest) returns (CreateRestrictionResponse) {
    option (google.api.http) = {
      post: "/member/product/restrictions"
      body: "*"
    };
  }

  rpc GetRestrictions (GetRestrictionsRequest) returns (GetRestrictionsResponse) {
    option (google.api.http) = {
      get: "/member/product/restrictions"
    };
  }

  rpc DeleteRestriction (DeleteRestrictionRequest) returns (DeleteRestrictionResponse) {
    option (google.api.http) = {
      delete: "/member/product/restrictions/{restriction_id}"
    };
  }

  rpc UpdateRestriction (UpdateRestrictionRequest) returns (UpdateRestrictionResponse) {
    option (google.api.http) = {
      put: "/member/product/restrictions/{restriction_id}"
      body: "*"
    };
  }

  rpc CreateRule (CreateRuleRequest) returns (CreateRuleResponse) {
    option (google.api.http) = {
      post: "/member/product/restrictions/{restriction_id}/rule"
      body: "*"
    };
  }

  rpc UpdateRule (UpdateRuleRequest) returns (UpdateRuleResponse) {
    option (google.api.http) = {
      put: "/member/product/restrictions/{restriction_id}/rules/{rule_id}"
      body: "*"
    };
  }

  rpc DeleteRule (DeleteRuleRequest) returns (DeleteRuleResponse) {
    option (google.api.http) = {
      delete: "/member/product/restrictions/{restriction_id}/rules/{rule_id}"
    };
  }

  rpc GetCountries (GetCountriesRequest) returns (GetCountriesResponse) {
    option (google.api.http) = {
      get: "/member/product/restrictions/countries"
    };
  }

  rpc GetRegions (GetRegionsRequest) returns (GetRegionsResponse) {
    option (google.api.http) = {
      get: "/member/product/restrictions/countries/{country_code}/regions"
    };
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Bank information service endpoints
  //
  rpc GetBankOutageStatus (GetBankOutageStatusRequest) returns (GetBankOutageStatusResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      get: "/bank-information/banks/{bank_id}/outage-status"
    };
  }

  rpc GetBanksOutageStatus (GetBanksOutageStatusRequest) returns (GetBanksOutageStatusResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      get: "/bank-information/banks/outage-status"
    };
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Secret service endpoints
  //
  // Refunds - Publish upload certificate and private key
  rpc UploadKeyAndCertificate (UploadKeyAndCertificateRequest) returns (UploadKeyAndCertificateResponse) {
    option (google.api.http) = {
      post: "/secrets/upload/key-and-certificate"
      body: "*"
    };
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Corporate API Integration Service Endpoints
  //
  rpc CreateVirtualAccount (CreateVirtualAccountRequest) returns (CreateVirtualAccountResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      post: "/virtual-accounts"
      body: "*"
    };
  }

  rpc GetVirtualAccountById (GetVirtualAccountByIdRequest) returns (GetVirtualAccountByIdResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      get: "/virtual-accounts/{account_id}"
    };
  }

  rpc GetVirtualAccounts (GetVirtualAccountsRequest) returns (GetVirtualAccountsResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      get: "/virtual-accounts"
    };
  }

  rpc CreditVirtualAccount (CreditVirtualAccountRequest) returns (CreditVirtualAccountResponse) {
    option (google.api.http) = {
      post: "/virtual-accounts/{account_id}/credit"
      body: "*"
    };
  }

  rpc GetVirtualAccountTransactions (GetVirtualAccountTransactionsRequest) returns (GetVirtualAccountTransactionsResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      get: "/virtual-accounts/{account_id}/transactions"
    };
  }

  rpc GetVirtualAccountTransaction (GetVirtualAccountTransactionRequest) returns (GetVirtualAccountTransactionResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      get: "/virtual-accounts/{account_id}/transactions/{provider_payment_id}"
    };
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Virtual Accounts - Settlement Rules API
  //

  rpc CreateVirtualAccountSettlementRule (CreateVirtualAccountSettlementRuleRequest) returns (CreateVirtualAccountSettlementRuleResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      post: "/virtual-accounts/{account_id}/settlement-rule"
      body: "*"
    };
  }

  rpc DeleteVirtualAccountSettlementRule (DeleteVirtualAccountSettlementRuleRequest) returns (DeleteVirtualAccountSettlementRuleResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      delete: "/virtual-accounts/{account_id}/settlement-rules/{settlement_rule_id}"
    };
  }

  rpc GetVirtualAccountSettlementPayouts (GetVirtualAccountSettlementPayoutsRequest) returns (GetVirtualAccountSettlementPayoutsResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      get: "/virtual-accounts/{account_id}/settlement-rule-payouts"
    };
  }

  rpc GetVirtualAccountSettlementRule (GetVirtualAccountSettlementRuleRequest) returns (GetVirtualAccountSettlementRuleResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      get: "/virtual-accounts/{account_id}/settlement-rules/{settlement_rule_id}"
    };
  }

  rpc GetVirtualAccountSettlementRules (GetVirtualAccountSettlementRulesRequest) returns (GetVirtualAccountSettlementRulesResponse) {
    option (grpcbridge.swagger.exclude) = true;
    option (google.api.http) = {
      get: "/virtual-accounts/{account_id}/settlement-rules"
    };
  }

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Provider registration endpoints
  rpc RegisterProvider (RegisterProviderRequest) returns (ProviderRegistrationResponse) {
    option (google.api.http) = {
      post: "/provider/registrations"
      body: "*"
    };
  }
  rpc GetProviderRegistrations (GetProviderRegistrationsRequest) returns (GetProviderRegistrationsResponse) {
    option (google.api.http) = {
      get: "/provider/registrations"
    };
  }

  rpc GetProviderRegistration (GetProviderRegistrationRequest) returns (ProviderRegistrationResponse) {
    option (google.api.http) = {
      get: "/provider/registrations/{registration_id}"
    };
  }

  rpc DeleteProviderRegistration (DeleteProviderRegistrationRequest) returns (EmptyResponse) {
    option (google.api.http) = {
      delete: "/provider/registrations/{registration_id}"
    };
  }
}