Skip to main content

Prerequisites

Before creating a payout you need:
  1. A pre-funded account — created via POST /api/v2/customers/pre-fund/create
  2. Sufficient balance — check via GET /api/v2/customers/balances
  3. 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

1

Check Available Balance

Verify you have enough funds before submitting the payout.
GET /api/v2/customers/balances
Response
[
  {
    "id": "balance-id",
    "currency": "COP",
    "amount": "10000000.00",
    "accountId": "prefund-account-id"
  }
]
2

Create the Payout

Submit the payout request with your pre-fund account, amount, and beneficiary.
POST /api/v2/payouts
3

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

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.

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-reference>
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