Learn how to programmatically send payouts via Payout API through the following sections.
Before you start
Create an API Key in your Xendit Dashboard. You will need the API Key to make API calls.
Set up your webhook URL. Configure this to receive real-time notifications on payout status changes.
Check Payout Coverage for channel-specific information. You need to know what information needs to be collected to start sending payouts.
Create a Quote (Optional)
Call Create Quote API with the your selected currencies to create a quote and lock rates. This step is recommended if you want to lock in and use a pre-defined rate for your payout. If you want to use live rates instead, you can directly move to Create a Payout.
Example Request
curl https://api.xendit.co/quotes -X POST \
-u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
--header 'Idempotency-key: some-unique-ref-for-request'
--data-raw '{
"reference_id": "quote-payout-245",
"type": "PAYOUT",
"source_currency": "USD",
"destination_currency": "SGD",
"source_amount": 200000
}Example Response
{
"quote_id": "qo-51c36b82-57d7-4643-90ce-27498e531085",
"reference_id": "quote-payout-245",
"source_amount": 200000,
"source_currency": "USD",
"destination_amount": 253077,
"destination_currency": "SGD",
"fx_rate": 1.26539,
"created": "2026-07-08T15:59:06.920336Z",
"updated": "2026-07-08T15:59:06.920336Z",
"expires": "2026-07-08T15:59:36.892559Z",
"type": "PAYOUT"
}Create a Payout
Call Create Payout API with the required recipient and transaction information to create a payout.
Example Request
curl https://api.xendit.co/v3/payouts -X POST \
-u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
--header 'Idempotency-key: some-unique-ref-for-request'
--header 'Api-version: 2025-09-01'
--data-raw '{
"reference_id": "8f88868a-aeaa-4e3d-8e79-ccd8c27afd76",
"recipient": {
"type": "BUSINESS",
"business_name": "Kalaw Manufacturing Inc.",
"relationship": "SUPPLIER",
"details": {
"date_of_incorporation": "2010-08-20",
"registration_number": "SEC-2010-456789",
"business_phone_number": "+6328765432",
"nature_of_business": "Metal Fabrication and Manufacturing"
},
"account_details": {
"currency": "PHP",
"account_country": "PH",
"account_holder_name": "Juanito Dimaguiba",
"account_number": "12345678",
"routing_type_1": "SWIFT",
"routing_value_1": "BNORPHMM"
},
"address": {
"country": "PH",
"province_state": "Metro Manila",
"city": "Makati City",
"street_line_1": "8th Floor Greenbelt Tower",
"street_line_2": "Ayala Avenue",
"postal_code": "1200"
}
},
"payout_details": {
"source_currency": "USD",
"destination_currency": "PHP",
"destination_amount": 12300000
},
"source_of_fund": "INVESTMENT",
"purpose_code": "SELF",
"description": "Payout to Kalaw",
"metadata": {
"invoice_number": "9285901"
}
}Example Response
If successfully created, a payout object with ACCEPTED status will always be returned.
{
"payout_id": "po-39c77bd0-6de6-426d-b1ba-80fe6066b190",
"status": "ACCEPTED",
"reference_id": "8f88868a-aeaa-4e3d-8e79-ccd8c27afd76",
"type": "B2B",
"source_currency": "USD",
"source_amount": 208214,
"destination_currency": "PHP",
"destination_amount": 12300000,
"recipient": {
"type": "BUSINESS",
"business_name": "Kalaw Manufacturing Inc.",
"details": {
"date_of_incorporation": "2010-08-20",
"registration_number": "SEC-2010-456789",
"business_phone_number": "+6328765432",
"nature_of_business": "Metal Fabrication and Manufacturing"
},
"address": {
"country": "PH",
"province_state": "Metro Manila",
"city": "Makati City",
"street_line_1": "8th Floor Greenbelt Tower",
"street_line_2": "Ayala Avenue",
"postal_code": "1200"
},
"account_details": {
"currency": "PHP",
"account_holder_name": "Juanito Dimaguiba",
"account_number": "12345678",
"routing_type_1": "SWIFT",
"routing_value_1": "BNORPHMM",
"account_country": "PH"
},
"relationship": "SUPPLIER"
},
"underlying_documents": null,
"source_of_fund": "INVESTMENT",
"purpose_code": "SELF",
"description": "Payout to Kalaw",
"created": "2026-07-08T16:09:40.994748827Z",
"updated": "2026-07-08T16:09:40.994748827Z",
"estimated_arrival_time": "2026-07-08T16:24:40Z",
"business_id": "675fb9aae4321c4cfc175c1b",
"metadata": {
"invoice_number": "9285901"
}
}Avoiding creating duplicate Payouts
We use idempotency-key to achieve idempotency and avoid creating duplicate payout transactions. If your first request fails due to error or timeout, you can retry safely by using the same idempotency-key value in the request header of your next retry. This will help us identify subsequent retry requests as retry attempts and will not create a duplicate payout transaction.
Ensure your recipient identify your payouts
We payout funds on your behalf from our bank accounts. To help your recipient identify funds from you, include your business name or any identifier in the description parameter - if the recipient's channel supports this field, the recipient will see this in their statement. In most cases, only a limited number of character is supported, so keep your identifier short and concise.
Read Payout Coverage for more channel-specific details.
Field requirements for your intended transfer scenario
Refer to the Dynamic Schema Sheet for precise field requirements specific to the intended transfer scenario. If you specify a parameter that is either not required or not on the full schema, it will be ignored and removed from the response. Please find below further considerations on some of the required parameters:
Minor Units
Starting in v3, we are utilizing minor units to accept amount format from you. This ensures the accuracy of decimal calculations that happens during the payout.
Utilize FX rate guarantee through Quote
Specify the quote_id returned from a previously created quote to fix the conversion rate of the transfer. You must also ensure that the source_currency and transfer_currency in your transfer request match the sell_currency and buy_currency from the quote. Quotes cannot be applied for creating and submitting a transfer for approval.
If not specified, the system will automatically book the underlying currency conversion based on transfer_date and lock_rate_on_create parameters. See Transactional FX to learn more about the options you have in performing conversions and how you can leverage the corresponding API endpoints.
Pay On Behalf Of (POBO)
Specify the sender information other than the Xendit account owner with POBO (Pay On Behalf Of) enabled on a case-by-case approval basis — usually with the provision of a remittance license. The sender information need to be provided directly within the sender object. By default, Xendit identifies the sender as the Xendit account owner creating the payout, and it is not necessary to specify the sender information.
Retrieve a Payout by its ID
Call Get Payout by ID API to retrieve payouts by its ID. Always return a single payout.
Example Request
curl https://api.xendit.co/v3/payouts/po-39c77bd0-6de6-426d-b1ba-80fe6066b190 -X GET \
-u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:Example Response
{
"payout_id": "po-39c77bd0-6de6-426d-b1ba-80fe6066b190",
"status": "SUCCEEDED",
"reference_id": "8f88868a-aeaa-4e3d-8e79-ccd8c27afd76",
"type": "B2B",
"source_currency": "USD",
"source_amount": 208214,
"destination_currency": "PHP",
"destination_amount": 12300000,
"sender": {
"type": "BUSINESS",
"business_name": "Your Business Name",
"details": {
"date_of_incorporation": "2000-01-01",
"registration_number": "REG12345",
"business_phone_number": "+651234567890",
"nature_of_business": "Your nature of business"
},
"address": {
"country": "SG",
"province_state": "Singapore",
"city": "Singapore",
"street_line_1": "Your street address 1",
"street_line_2": "Your street address 2",
"postal_code": "123456"
}
},
"recipient": {
"type": "BUSINESS",
"business_name": "Kalaw Manufacturing Inc.",
"details": {
"date_of_incorporation": "2010-08-20",
"registration_number": "SEC-2010-456789",
"business_phone_number": "+6328765432",
"nature_of_business": "Metal Fabrication and Manufacturing"
},
"address": {
"country": "PH",
"province_state": "Metro Manila",
"city": "Makati City",
"street_line_1": "8th Floor Greenbelt Tower",
"street_line_2": "Ayala Avenue",
"postal_code": "1200"
},
"account_details": {
"currency": "PHP",
"account_holder_name": "Juanito Dimaguiba",
"account_number": "12345678",
"routing_type_1": "SWIFT",
"routing_value_1": "BNORPHMM",
"account_country": "PH"
},
"relationship": "SUPPLIER"
},
"underlying_documents": null,
"source_of_fund": "INVESTMENT",
"purpose_code": "SELF",
"description": "Payout to Kalaw",
"created": "2026-07-08T16:09:40.994749Z",
"updated": "2026-07-08T16:09:42.122288Z",
"estimated_arrival_time": "2026-07-08T16:24:40Z",
"business_id": "675fb9aae4321c4cfc175c1b",
"metadata": {
"invoice_number": "9285901"
}
}Error Handling
Common Errors in Payouts
Below is a list of common errors you may encounter while using Payouts API. For simple understanding, we’ve split them into 2 categories:
Errors in creating the payout
Errors in executing the payout
Errors In Creating the Payout
All the possible errors while creating payouts via our API endpoints are listed in this page.
For errors generally, the response you receive will contain:
error_code: A semantic code specifying the error encountered;message: A brief statement that explains the code.
Example:
{
"error_code": "DUPLICATE_ERROR",
"message": "A payout with this idempotency key already exists. If you meant to execute a different request, please use another idempotency key."
}If you receive an error in our API response, this means that there were issues creating the payout due to invalid inputs or issues with the server. For detailed handling instructions of each error, please see the table below:
Error Code | Explanation |
|---|---|
| Certain inputs do not meet our API validation requirements. |
| Idempotency key has been used before. Use a unique idempotency key and try again. |
| Every channel has a minimum and maximum transaction amount. We will return an error response if the transfer amount requested does not conform to the prescribed limits. See Payout Coverage. |
| Every channel has a different increment support. We will return an error response if the transfer amount requested does not conform to the prescribed increment support. |
Errors In Executing the Payout
After a payout status is REQUESTED, it may fail our payout partner’s processing or be rejected by the recipient bank, at which point its status will transition to FAILED. Subscribe to payout.failed webhook events to receive real-time notifications of each transfer's failure and its reason.
It is important that you understand each failure code in detail in order to decide on the appropriate action to take. Below is a comprehensive list of the possible failure codes that you may receive, what they mean and what our corresponding suggested action is:
Error Message | Description | Should you retry? |
|---|---|---|
| Client has insufficient balance for the payout amount | Yes, retry the payout after ensuring that you have sufficient balance in your account |
| The recipient account does not exist/is invalid | You are unlikely to succeed if you retry the payout request. Please confirm with the recipient whether their account is correct |
| The recipient is unable to receive the funds due to the payout amount exceeding the recipient’s ability to receive | You are unlikely to succeed if you retry the payout request. Please confirm with the recipient whether their account can receive the payout |
| Payout failed due to an error from the destination channel. This is usually because of network issues associated with the destination bank or issues crediting funds into the destination bank account | Yes, retry the payout after validating that the destination bank account number is active and can receive funds in your chosen currency |
| The channel networks are experiencing a temporary error | Yes, retry the payout in 1-3 hours |
| We’ve encountered a fatal error while processing this payout. Normally, this means that certain API fields in your request are invalid | It is unlikely that the same disbursement request will succeed if you retry |
Note: We could add new failure codes to the list above and your system should be able to handle the events even if the failure code is not recognized.
Payout Events
Learn more below for the different webhook events that you can subscribe to. For more information of different payout statuses, see Payout Status Lifecycle.
Webhook Event | Payout Status |
|---|---|
|
|
|
|
|
|
|
|
|
|