Batch adding external banking account number - Payee

Batch Adding External Banking Account Number - Payee

This endpoint allows partners to register multiple external bank accounts as payees in a single batch operation. Each account in the batch is linked by routing number, account number, and account type, and the entire request is secured with a one-time verification code. This approach reduces round-trip overhead when onboarding several payee accounts at once.

Endpoint

POST /api/fundsMovement/batch/externalPayee

Authentication

Bearer token required. Obtain via:

POST https://api.banking.netevia.dev/api/auth/v2

Include in header: Authorization: Bearer {token}
Token lifetime: 10 minutes. Refresh via POST /api/auth/refresh.

When to use

Use this endpoint when a customer needs to add multiple external bank accounts as payees simultaneously — for example, during initial onboarding of a business customer who pays multiple vendors, or when migrating an existing set of payee accounts into the Netevia platform. The batch operation combines all account additions into a single secure, verified transaction, reducing the number of OTP prompts required compared to adding each payee individually.

Request Body

FieldTypeRequiredDescription
requestsarrayNoArray of external account objects to add as payees. Each item is either a base or secured external account request (see sub-fields below).
requests[].routingNumberstringYesABA routing number of the external bank.
requests[].accountNumberstringYesFull account number at the external bank.
requests[].namestringYesDisplay name for this payee account.
requests[].bankAccountTypestringYesAccount type. Allowed values: SAVINGS, CHECKING.
requests[].oneTimeCodestringNo (per-item)Per-item 6-digit OTP for item-level verification (required when using the secured variant). Must match pattern ^\d{6}$.
requests[].secureOperationTypestringNo (per-item)Verification method used for per-item OTP. Allowed values: ShortMessageCode, TimeBasedCode, LegacyTimeBasedCode.
oneTimeCodestringYesTop-level 6-digit OTP for the entire batch. Must match pattern ^\d{6}$.
secureOperationTypestringYesVerification method for the top-level OTP. Allowed values: ShortMessageCode, TimeBasedCode, LegacyTimeBasedCode.
{
  "requests": [
    {
      "routingNumber": "021000021",
      "accountNumber": "XXXXXXXXXX",
      "name": "Vendor Payroll Account",
      "bankAccountType": "CHECKING"
    },
    {
      "routingNumber": "011401533",
      "accountNumber": "XXXXXXXXXX",
      "name": "Supplier Savings Account",
      "bankAccountType": "SAVINGS"
    }
  ],
  "oneTimeCode": "847291",
  "secureOperationType": "ShortMessageCode"
}

Response

200 OK

Returns an array of result objects, one per submitted payee account request.

FieldTypeDescription
[].mainNodeobjectDetails of the newly created external bank account record.
[].mainNode.typenamestringGraphQL type name of the result node.
[].mainNode.idstringUnique identifier for the created external bank account.
[].mainNode.namestringDisplay name assigned to this payee account.
[].mainNode.externalBankAccountDetailsobjectDetailed account information.
[].mainNode.externalBankAccountDetails.last4stringLast 4 digits of the account number.
[].mainNode.externalBankAccountDetails.typestringAccount type (e.g., CHECKING, SAVINGS).
[].mainNode.externalBankAccountDetails.routingNumberstringABA routing number of the external bank.
[].mainNode.externalBankAccountDetails.accountNumberstringFull account number (may be masked).
[].mainNode.externalBankAccountDetails.createdAtstring (date-time)Timestamp when the account details were created.
[].mainNode.externalBankAccountDetails.updatedAtstring (date-time)Timestamp when the account details were last updated.
[].mainNode.accessDeniedErrorMessagestringError message if access was denied for this item; null if successful.
[].mainNode.createdAtstring (date-time)Timestamp when the payee record was created.
[].mainNode.updatedAtstring (date-time)Timestamp when the payee record was last updated.
[].mainNode.errorsarrayPer-item mutation errors, if any.
[].mainNode.errors[].patharray of stringsField path where the error occurred.
[].mainNode.errors[].codestringMachine-readable error code.
[].mainNode.errors[].descriptionstringHuman-readable error description.
[].mutationResultobjectOverall mutation result for this item.
[].mutationResult.errorsarrayTop-level errors for this item's mutation, if any (same structure as mainNode.errors).
[
  {
    "mainNode": {
      "typename": "AddNonVerifiedExternalUSFinancialBankAccount",
      "id": "extacct_01HX9KZQV3MTNR8WPBFYG2C4D",
      "name": "Vendor Payroll Account",
      "externalBankAccountDetails": {
        "last4": "7890",
        "type": "CHECKING",
        "routingNumber": "021000021",
        "accountNumber": "XXXXXXXXXX",
        "createdAt": "2026-06-08T14:22:10Z",
        "updatedAt": "2026-06-08T14:22:10Z"
      },
      "accessDeniedErrorMessage": null,
      "createdAt": "2026-06-08T14:22:10Z",
      "updatedAt": "2026-06-08T14:22:10Z",
      "errors": []
    },
    "mutationResult": {
      "errors": []
    }
  },
  {
    "mainNode": {
      "typename": "AddNonVerifiedExternalUSFinancialBankAccount",
      "id": "extacct_02JY0LARGS4NUTS9XQCGZH3E5F",
      "name": "Supplier Savings Account",
      "externalBankAccountDetails": {
        "last4": "3412",
        "type": "SAVINGS",
        "routingNumber": "011401533",
        "accountNumber": "XXXXXXXXXX",
        "createdAt": "2026-06-08T14:22:11Z",
        "updatedAt": "2026-06-08T14:22:11Z"
      },
      "accessDeniedErrorMessage": null,
      "createdAt": "2026-06-08T14:22:11Z",
      "updatedAt": "2026-06-08T14:22:11Z",
      "errors": []
    },
    "mutationResult": {
      "errors": []
    }
  }
]

Error Codes

CodeWhen it happens
400Missing required fields (oneTimeCode, secureOperationType), invalid OTP format (must be exactly 6 digits), invalid bankAccountType (must be SAVINGS or CHECKING), or malformed routing/account number.
401Token missing, expired, or invalid.
403Insufficient permissions to add external payee accounts.
404Customer or financial account context not found.
500Internal server error.

Common Mistakes

  • Providing a oneTimeCode that does not exactly match the pattern ^\d{6}$ (e.g., including spaces, letters, or fewer/more than 6 digits) will cause a 400 validation error.
  • Setting bankAccountType to a value other than SAVINGS or CHECKING (case-sensitive) will fail validation — do not use lowercase or mixed-case variants.
  • Omitting the top-level oneTimeCode or secureOperationType fields, which are required at the batch level even if individual items carry their own OTP fields.
  • Sending raw, unmasked account numbers in logs or error reports — always sanitize account numbers as XXXXXXXXXX in any diagnostic output.
  • Assuming a 200 response means all items succeeded — always inspect each item's mainNode.errors and mutationResult.errors arrays for per-item failures within a successful batch response.

Related Endpoints

  • POST /api/fundsMovement/externalPayee — Add a single external bank account as a payee.
  • GET /api/fundsMovement/externalPayees — List all external payee accounts for the current customer.
  • DELETE /api/fundsMovement/externalPayee/{id} — Remove a specific external payee account.
  • POST /api/fundsMovement/transfer — Initiate a funds transfer to a registered external payee.

Example

curl -X POST https://api.banking.netevia.dev/api/fundsMovement/batch/externalPayee \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "requests": [
      {
        "routingNumber": "021000021",
        "accountNumber": "XXXXXXXXXX",
        "name": "Vendor Payroll Account",
        "bankAccountType": "CHECKING"
      },
      {
        "routingNumber": "011401533",
        "accountNumber": "XXXXXXXXXX",
        "name": "Supplier Savings Account",
        "bankAccountType": "SAVINGS"
      }
    ],
    "oneTimeCode": "847291",
    "secureOperationType": "ShortMessageCode"
  }'
Body Params
requests
array | null
requests
string
required
length ≥ 1
^\d{6}$

Code for passing verification

string
enum
required
Allowed:
Headers
string
enum
Defaults to application/json

Generated from available response content types

Allowed:
string
enum
Defaults to application/json

Generated from available request content types

Allowed:
Response

Language
Credentials
Bearer
JWT
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
text/plain
application/json
text/json