Prerequisites
Before creating a payout you need:
A pre-funded account — created via POST /api/v2/customers/pre-fund/create
Sufficient balance — check via GET /api/v2/customers/balances
Beneficiary details — bank account, wallet address, or payment alias of the recipient
Set Up Pre-Funded Accounts Don’t have a pre-funded account yet? Start here.
Complete Payout Flow
Check Available Balance
Verify you have enough funds before submitting the payout. GET /api/v2/customers/balances
[
{
"id" : "balance-id" ,
"currency" : "COP" ,
"amount" : "10000000.00" ,
"accountId" : "prefund-account-id"
}
]
Create the Payout
Submit the payout request with your pre-fund account, amount, and beneficiary.
Track Status
Poll the payout or listen to webhooks until it reaches a terminal status (COMPLETED, ERROR, FAILED, REJECTED, or REFUNDED).
Implementation Example
curl -X POST https://sandbox.killb.app/api/v2/payouts \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: payout-2024-001" \
-d '{
"preFundAccountId": "prefund-account-id",
"amount": 500000,
"externalId": "payout-2024-001",
"beneficiary": {
"type": "PSE",
"account": {
"firstName": "Maria",
"lastName": "Garcia",
"email": "[email protected] ",
"phone": "3001234567",
"document": { "type": "CC", "number": "12345678" },
"accountNumber": "123456789",
"bankCode": "001",
"type": "savings",
"countryCode": "CO"
}
}
}'
Response:
{
"id" : "payout-abc123" ,
"amount" : 500000 ,
"currency" : "COP" ,
"status" : "PENDING" ,
"externalId" : "payout-2024-001" ,
"beneficiary" : {
"type" : "PSE" ,
"account" : { ... }
},
"createdAt" : "2024-01-15T10:30:00.000Z" ,
"updatedAt" : "2024-01-15T10:30:00.000Z"
}
Beneficiary Types
PSE (Colombia)
BREB (Colombia)
Standard Colombian bank account transfer via PSE rails. {
"type" : "PSE" ,
"account" : {
"firstName" : "Maria" ,
"lastName" : "Garcia" ,
"email" : "[email protected] " ,
"phone" : "3001234567" ,
"document" : {
"type" : "CC" ,
"number" : "12345678"
},
"accountNumber" : "123456789" ,
"bankCode" : "001" ,
"type" : "savings" ,
"countryCode" : "CO"
}
}
Required fields: firstName or companyName, lastName, email, phone, document, accountNumber, bankCode, type, countryCodeUse GET /api/v2/banks to look up valid bankCode values. Disbursement via a registered alias (phone, email, ID, or BREB alias). {
"type" : "BREB" ,
"account" : {
"firstName" : "Carlos" ,
"lastName" : "Lopez" ,
"email" : "[email protected] " ,
"phone" : "3109876543" ,
"document" : {
"type" : "CC" ,
"number" : "87654321"
},
"aliasType" : "PHONE" ,
"alias" : "3109876543" ,
"countryCode" : "CO"
}
}
Alias types: NATIONAL_ID, PHONE, EMAIL, ALPHANUMERIC, BUSINESS_ID
Checking Balance Before Payout
Always verify available balance before submitting large payouts:
const checkBalance = async ( preFundAccountId , requiredAmount ) => {
const balances = await fetch ( '/api/v2/customers/balances' , {
headers: { 'Authorization' : `Bearer ${ token } ` }
}). then ( r => r . json ());
const account = balances . find ( b => b . accountId === preFundAccountId );
if ( ! account || parseFloat ( account . amount ) < requiredAmount ) {
throw new Error (
`Insufficient balance. Available: ${ account ?. amount ?? 0 } , Required: ${ requiredAmount } `
);
}
return account ;
};
Idempotency
To prevent duplicate disbursements on network retries, pass a unique Idempotency-Key header with every payout creation request. If the same key is submitted twice, KillB returns the original payout instead of creating a new one.
Idempotency-Key: < your-unique-payout-referenc e >
Use a stable, unique identifier as the key — your internal payment ID or a UUID tied to the business transaction works well.
Listing Payouts
Retrieve all payouts with optional filters:
const listPayouts = async ({ status , externalId , page = 1 , limit = 20 } = {}) => {
const params = new URLSearchParams ({ page , limit });
if ( status ) params . set ( 'status' , status );
if ( externalId ) params . set ( 'externalId' , externalId );
const response = await fetch (
`https://sandbox.killb.app/api/v2/payouts? ${ params } ` ,
{ headers: { 'Authorization' : `Bearer ${ token } ` } }
);
return response . json (); // { payouts: [...], totalPage: N }
};
// Get all pending payouts
const pending = await listPayouts ({ status: 'PENDING' });
Next Steps
Status Tracking Monitor payouts with polling and webhooks
Webhooks Setup Configure PAYOUT webhook notifications