A Developer’s Guide to Batch Payouts Using Request Network

I'm Vedant! I'm a software developer who loves to create awesome web3 and blockchain projects. When I'm not coding, you can find me writing technical articles or exploring new technologies. I'm always up for a chat about the latest tech trends, so feel free to drop me a message!
Batch payouts are a common requirement in payroll systems, treasury tools, creator payouts, and automated on-chain settlement pipelines. Instead of sending multiple independent ERC-20 transfers which is slow, expensive, Request Network provides a single API call that returns:
ERC-20 approval transactions (if needed)
a batch payment transaction containing pre-encoded calldata
all the metadata required to execute the batch atomically on-chain
Prerequisites
Before writing code, make sure you have:
Node.js (>= 18 recommended)
A funded Sepolia wallet holding FAU tokens (Token Address:
0x370DE27fdb7D1Ff1e1BaA7D11c5820a324Cf623C)Environment Variables:
PRIVATE_KEY: Payer’s Private KeyAPI_KEY: Request API Key
Getting Your Request Network API Key
Request Network exposes its batch payout API behind an authenticated HTTP interface. To get your API key:
Create an account / log in
Create a new “API Key”
Copy the generated API Key
Store it securely (e.g.,
.envfile)
API_KEY=your-request-network-api-key
PRIVATE_KEY=your-sepolia-private-key
Your API key is required for the x-api-key header in all API calls.
Creating a Batch Payout
Setup Provider + Wallet
To interact with Sepolia and later broadcast the approval and batch payment transactions, we first initilize a provider and wallet. The JsonRpcProvider connects your code to an Ethereum Sepolia RPC endpoint. Using your PRIVATE_KEY, we instantiate an Ethers.js Wallet that will sign and pay for all on-chain operations. The derived payerAddress is the account that Request Network will treat as the payer for the batch.
const provider = new providers.JsonRpcProvider(
"https://ethereum-sepolia-rpc.publicnode.com"
);
const payerWallet = new Wallet(process.env.PRIVATE_KEY as string, provider);
const payerAddress = payerWallet.address;
Prepare the Batch Requests
Next we define a simple list of payout entries, each containing a recipient address and an amount. These entries represent the individual payments you want to include in the batch.
Later, each item is converted into the format the Request Network API expects, where both the invoice currency and the payment currency are set to FAU-sepolia. This means the payout will be settled entirely in FAU tokens on the Sepolia network.
const requests = [
{ address: "0x00A2895816e64F152FF81c8A931DC1bd9F5c3ce3", amount: "10" },
{ address: "0xc0d86456F6f2930b892f3DAD007CDBE32c081FE6", amount: "10" },
{ address: "0xe269688F24e1C7487f649fC3dCD99A4Bf15bDaA1", amount: "10" },
];
Create the Batch Payout Request
Next we sends a POST request to https://api.request.network/v2/payouts/batch. Along with your API key in the header, the body includes the list of payout entries and the Ethereum address of the payer.
Request Network validates the batch, calculates total spending, and prepares all the on-chain steps required to settle this batch. This single API call returns everything you need to perform the payout on-chain without writing your own smart contract logic.
const response = await fetch("https://api.request.network/v2/payouts/batch", {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": process.env.API_KEY as string,
},
body: JSON.stringify({
requests: requests.map((r) => ({
payee: r.address,
amount: r.amount,
invoiceCurrency: "FAU-sepolia",
paymentCurrency: "FAU-sepolia",
})),
payer: payerAddress,
}),
});
Understanding the API Response
The response contains two important elements:
ERC20ApprovalTransactionsbatchPaymentTransaction
The approval transactions are optional and are only returned when your wallet does not have enough ERC-20 allowance set for Request Network’s batch contract. Each approval transaction is already encoded and ready to be broadcast.
The batchPaymentTransaction contains the calldata and contract address needed to process all payouts in one atomic on-chain operation. Essentially, the API produces all transaction objects for you, so your code only needs to sign and send them.
const { batchPaymentTransaction, ERC20ApprovalTransactions } =
await response.json();
Sending Required ERC-20 Approvals
If approvals are required, the script loops through each approval transaction and broadcasts it directly through the payer’s wallet. These approval transactions use the standard ERC-20 approve() function to authorize Request Network’s batch contract to move FAU tokens on your behalf. Once an approval is confirmed, the allowance is updated on-chain, enabling the final batch payment to succeed.
if (ERC20ApprovalTransactions.length > 0) {
for (const tx of ERC20ApprovalTransactions) {
const res = await payerWallet.sendTransaction(tx);
await res.wait();
console.log(res.hash);
}
}
Executing the Batch Payment Transaction
After any necessary approvals are completed, the script sends the main batch payment transaction. This transaction performs all payouts in one go, distributing FAU to each recipient based on the request list.
Once the transaction confirms, all recipients receive their payouts, and you get a single transaction hash representing the complete batch settlement.
const res = await payerWallet.sendTransaction(batchPaymentTransaction);
await res.wait();
console.log(res.hash);

Full Code
import type { TransactionRequest } from "@ethersproject/abstract-provider";
import { providers, Wallet } from "ethers";
const provider = new providers.JsonRpcProvider(
"https://ethereum-sepolia-rpc.publicnode.com",
);
const payerWallet = new Wallet(process.env.PRIVATE_KEY as string, provider);
const payerAddress = payerWallet.address;
const requests: { address: string; amount: string }[] = [
{
address: "0x00A2895816e64F152FF81c8A931DC1bd9F5c3ce3",
amount: "10",
},
{
address: "0xc0d86456F6f2930b892f3DAD007CDBE32c081FE6",
amount: "10",
},
{
address: "0xe269688F24e1C7487f649fC3dCD99A4Bf15bDaA1",
amount: "10",
},
];
const response = await fetch("https://api.request.network/v2/payouts/batch", {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": process.env.API_KEY as string,
},
body: JSON.stringify({
requests: [
...requests.map((r) => ({
payee: r.address,
amount: r.amount,
invoiceCurrency: "FAU-sepolia",
paymentCurrency: "FAU-sepolia",
})),
],
payer: payerAddress,
}),
});
const { batchPaymentTransaction, ERC20ApprovalTransactions } =
(await response.json()) as {
batchPaymentTransaction: TransactionRequest;
ERC20ApprovalTransactions: TransactionRequest[];
};
if (ERC20ApprovalTransactions.length > 0) {
console.log(
"Sending ERC20 approval transactions...",
ERC20ApprovalTransactions.length,
);
for (const tx of ERC20ApprovalTransactions) {
const res = await payerWallet.sendTransaction(tx);
await res.wait();
console.log(res.hash);
}
}
const res = await payerWallet.sendTransaction(batchPaymentTransaction);
await res.wait();
console.log(res.hash);
Conclusion
Batch payouts don’t need custom smart contracts or complicated encoding logic. By relying on Request Network’s batch payout API, you can automate multi-recipient payments with a single API call and one final on-chain transaction.
The API handles request creation, calldata generation, allowance validation, and transaction preparation, your code simply forwards the returned transaction objects.
With the code above, you now have a fully working end-to-end implementation. From fetching payout instructions to executing the final settlement on-chain, your system can now perform seamless mass payouts with minimal moving parts.
Happy shipping!





