How to Send an ACH/RTP Optimal Payout
The ACH/RTP optimal payout flow allows you to send domestic US payouts at the fastest available speed. Before creating a transfer, this flow checks whether the beneficiary's bank supports Real-Time Payments (RTP). If RTP is available, the transfer is sent as Realtime ACH for near-instant delivery. If not, it falls back to Same-day ACH or Regular ACH.
This approach ensures your beneficiaries receive funds as quickly as their bank allows, without requiring you to know the payment rail in advance.
The usual workflow for integrating with the non-hosted solution involves the following steps:
Step 1: Authenticate: Obtain an API token by validating your credentials.
Step 2: Create Beneficiary: Create and manage beneficiary's accounts using API calls.
Step 3: Create a Sender: Register the originating party for the payout.
Step 4: Create Transfer Method: Add and manage transfer methods for your beneficiaries.
Step 5: Check RTP Availability: Look up the beneficiary's routing number to determine if RTP is supported.
Step 6: Create Transfer: Execute the transfer using the optimal payment rail.
API Endpoints Used
This guide will demonstrate step-by-step instructions using the API integration method. In this guide, you will use the following API endpoints:
Below, you will go through the necessary API calls to achieve the steps above within the i-payout system.
Step 1: Authenticate
To start using i-payout solutions, you will need to authenticate with your API Token. Refer to the Get a Token guide to learn how to:
Step 2: Create Beneficiary
A beneficiary is an individual or company designated to receive funds through the i-payout system. To create a beneficiary, you will need to provide detailed information about the individual, such as their name, address, and payment details. Leave companyName empty if the beneficiary is an individual.
Use the Create Beneficiary endpoint to create a new beneficiary. The request should include all necessary details about the beneficiary in the request body and, as shown in Step 1, include the authentication to access the i-payout API. Below, you will find an example request to create a new beneficiary:
curl --request POST \
--url "https://merchantapi.testewallet.com/api/v1/beneficiaries" \
--header 'Authorization: Bearer <YOUR_API_TOKEN>' \
--header 'X-MerchantId: <YOUR_MERCHANT_ID>' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '{
"username": "john_doe",
"firstName": "John",
"lastName": "Doe",
"emailAddress": "[email protected]"
}'{
"data": {
"beneficiaryToken": "e0e4764b-9619-4deb-95c4-108ce9f0fe04"
},
"isSuccess": true,
"message": "Customer created successfully",
"statusCode": "NO_ERROR",
"logIdentifier": "497b73624c0d47bfb0abf58df5dd99ca"
}Step 3: Create a Sender
A sender identifies the originating party of the payout. You must create a sender before initiating a transfer. Use the Create Sender endpoint to register a new sender in the system.
The senderID and emailAddress fields are required. Only company senders are supported at this time, so you must provide the companyName field. All other fields are optional but recommended for compliance and record-keeping purposes. Below, you will find an example request to create a new sender:
curl --request POST \
--url "https://merchantapi.testewallet.com/api/v1/beneficiaries/sender" \
--header 'Authorization: Bearer <YOUR_API_TOKEN>' \
--header 'X-MerchantId: <YOUR_MERCHANT_ID>' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '{
"senderID": "SENDER_001",
"companyName": "Acme Corp",
"emailAddress": "[email protected]",
"address1": "123 Main Street",
"country": "US"
}'{
"isSuccess": true,
"message": "Sender created successfully",
"statusCode": "NO_ERROR",
"logIdentifier": "abc123def456",
"data": {
"senderToken": "f1e2d3c4-b5a6-7890-abcd-ef1234567890"
}
}Step 4: Create Transfer Method
To manage how funds are transferred to beneficiaries, you need to create a transfer method. To add a bank account for your beneficiary, use the Add Bank Account endpoint. Make sure accountType1 matches the beneficiary type: "personal" for individuals or "business" for companies. This method requires a US bank account and the relevant ACH details:
curl --request POST \
--url "https://merchantapi.testewallet.com/api/v1/transfer-methods/beneficiaries/<BENEFICIARY_TOKEN_FROM_STEP_2>/bank-accounts" \
--header 'Authorization: Bearer <YOUR_API_TOKEN>' \
--header 'X-MerchantId: <YOUR_MERCHANT_ID>' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '{
"accountNickName": "John Personal Account",
"accountCurrency": "USD",
"accountNumber": "123456789",
"accountType1": "personal",
"accountType2": "checking",
"bankName": "Bank of America",
"bankCountry": "US",
"routingNumber": "987654321",
"branchAddress": "1234 Bank Street, Suite 567",
"beneficiaryFirstName": "John",
"beneficiaryLastName": "Doe",
"beneficiaryCountry": "US",
"beneficiaryAddress1": "1234 Elm St",
"beneficiaryState": "CA",
"beneficiaryCity": "Los Angeles",
"beneficiaryZipCode": "90001"
}'{
"isSuccess": true,
"message": "Bank account added successfully",
"statusCode": "NO_ERROR",
"logIdentifier": "def456ghi789",
"data": {
"token": "bankAcc123Token",
"isDocumentVerificationRequired": false
}
}Step 5: Check RTP Availability
Before creating the transfer, you need to determine the fastest available payment rail. Use the USA Routing Number Lookup endpoint with includeRtp=true to check whether the beneficiary's bank supports Real-Time Payments. Below, you will find an example request to look up a routing number:
curl --request GET \
--url "https://merchantapi.testewallet.com/api/v1/lookups/usa-routing-numbers/987654321?includeRtp=true" \
--header 'Authorization: Bearer <YOUR_API_TOKEN>' \
--header 'X-MerchantId: <YOUR_MERCHANT_ID>' \
--header 'accept: application/json'{
"isSuccess": true,
"message": "Success",
"statusCode": "NO_ERROR",
"logIdentifier": "rtp123lookup456",
"data": {
"routingNumber": "987654321",
"bankName": "Bank of America",
"bankAddress": "1234 Bank Street",
"bankCity": "Los Angeles",
"bankState": "CA",
"bankZipCode": "90001",
"rtpSupported": true,
"rtpDetails": {
"fedNow": true,
"rtp": true
}
}
}Use the rtpSupported field to determine the destinationType for the transfer in the next step:
- If
rtpSupportedistrue— setdestinationTypeto"RealtimeACH"for near-instant delivery. - If
rtpSupportedisfalse— setdestinationTypeto"SameDayACH"or"RegularACH".
Step 6: Create Transfer
With the beneficiary, sender, transfer method, and RTP availability confirmed, you can now create the transfer. The Create Transfer endpoint will be used to make the transfer from you to your beneficiary by linking the transfer with the beneficiaryToken created on Step 2 and the senderToken created on Step 3. Set the destinationType based on the result from Step 5. Below, you will find an example request to create a new transfer using Realtime ACH:
curl --request POST \
--url "https://merchantapi.testewallet.com/api/v1/transfers" \
--header 'Authorization: Bearer <YOUR_API_TOKEN>' \
--header 'X-MerchantId: <YOUR_MERCHANT_ID>' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '{
"merchantTransactionId": "TX123456",
"beneficiaryToken": "<BENEFICIARY_TOKEN_FROM_STEP_2>",
"senderToken": "<SENDER_TOKEN_FROM_STEP_3>",
"autoApprove": true,
"comments": "Payment for services",
"dateExpire": "2025-12-31",
"sourceAmount": 100.00,
"sourceCurrency": "USD",
"destinationCurrency": "USD",
"destinationType": "RealtimeACH",
"bankAccount": {
"accountNickName": "John Personal Account",
"accountCurrency": "USD",
"accountNumber": "123456789",
"accountType1": "personal",
"accountType2": "checking",
"bankName": "Bank of America",
"bankCountry": "US",
"routingNumber": "987654321",
"branchAddress": "1234 Bank Street, Suite 567",
"beneficiaryCountry": "US",
"beneficiaryAddress1": "1234 Elm St",
"beneficiaryState": "CA",
"beneficiaryCity": "Los Angeles",
"beneficiaryZipCode": "90001"
}
}'{
"isSuccess": true,
"message": "Transfer created successfully",
"statusCode": "NO_ERROR",
"logIdentifier": "abc123def456",
"data": {
"token": "trans789token",
"dateCreated": "2025-07-22T16:17:00.548Z",
"dateUpdated": "2025-07-22T16:17:00.548Z",
"statusId": 1,
"status": "CREATED",
"fxRate": 1.00,
"beneficiaryFee": 0.00,
"merchantFee": 1.00,
"senderToken": "f1e2d3c4-b5a6-7890-abcd-ef1234567890"
}
}If
rtpSupportedwasfalsein Step 5, replace"RealtimeACH"with"SameDayACH"or"RegularACH"in thedestinationTypefield.
Monitor Transfer Status
After creating a transfer, there are two ways to track its progress:
Option A: Transfer Reports (Recommended)
Use the Get Transfers Report endpoint to retrieve the status and details of your transfers on demand. This is the primary way to check on transfers, especially when processing multiple payments and you need to review statuses in bulk. You can filter results by beneficiary, status, date range, currency, and more. The maximum pageSize is 100 records per request.
Option B: Webhook Notifications
For real-time updates without polling the API, subscribe to webhook events. We recommend the following events:
TRANSFER.CREATED: triggers when a transfer is created, confirming the payout was initiated.TRANSFER.STATUS.UPDATED: triggers when the transfer status changes (e.g.,PROCESSING,APPROVED,DECLINED,CANCELLED,ON_HOLD,SETTLED).
Transfers placed on ON_HOLD may include sub-statuses with additional detail.
To start receiving webhook notifications, follow the How to Set Up Webhooks guide. For a full list of available events and example payloads, see Webhook Events.
Other Available Payout Methods
Follow the links below to learn more about other available payout methods:
Updated 19 days ago