Skip to content

Releasing funds with split payouts ​

When a milestone is approved, finance releases it to one to five payout instructions. Each instruction is a bank destination that RekberPay has verified and signed, so money cannot be sent to an account someone typed in at the last moment. In this run Rp30.000.000 is split between the supplier's main account and its freight account.

1. See the verified instructions ​

bash
curl "https://api.rekberpay.com/v1/enterprise/payout-instructions?counterparty_id=eeeeeee3-eeee-4eee-8eee-eeeeeeeeeeee" \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY"
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/payout-instructions?counterparty_id=eeeeeee3-eeee-4eee-8eee-eeeeeeeeeeee', {
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_WORKSPACE_KEY}`,
    },
});
const data = await res.json();
python
import os

import requests

resp = requests.get(
    "https://api.rekberpay.com/v1/enterprise/payout-instructions?counterparty_id=eeeeeee3-eeee-4eee-8eee-eeeeeeeeeeee",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_WORKSPACE_KEY']}",
    },
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/enterprise/payout-instructions?counterparty_id=eeeeeee3-eeee-4eee-8eee-eeeeeeeeeeee');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_WORKSPACE_KEY'),
    ],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

200 OK

json
{
    "success": true,
    "data": [
        {
            "id": "fffffff3-ffff-4fff-8fff-ffffffffffff",
            "label": "Harbourline IDR collection account",
            "counterparty": {
                "id": "eeeeeee3-eeee-4eee-8eee-eeeeeeeeeeee",
                "name": "Harbourline Components Pte Ltd"
            },
            "currency": "IDR",
            "bank_name": "DBS Bank Indonesia",
            "account_number_masked": "3320****43",
            "account_holder": "Harbourline Components Pte Ltd",
            "country_code": "ID",
            "status": "verified",
            "signed": true,
            "verified_at": "2026-09-30T07:33:06.162Z",
            "created_at": "2026-09-30T03:33:06.162Z",
            "updated_at": "2026-10-13T14:33:06.231Z"
        }
    ],
    "pagination": {
        "page": 1,
        "limit": 20,
        "total": 1,
        "total_pages": 1
    }
}

Only verified instructions can receive money. Account numbers are always masked.

2. Add a new instruction ​

bash
curl -X POST https://api.rekberpay.com/v1/enterprise/payout-instructions \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY" \
  -H "Idempotency-Key: 11111114-1111-4111-8111-111111111111" \
  -H "Content-Type: application/json" \
  -d '{
    "label": "Harbourline freight account",
    "counterparty_id": "eeeeeee3-eeee-4eee-8eee-eeeeeeeeeeee",
    "currency": "IDR",
    "bank_name": "Bank Central Asia",
    "account_number": "8730 0412 55",
    "account_holder": "PT Harbourline Indonesia",
    "country_code": "ID"
  }'
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/payout-instructions', {
    method: 'POST',
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_WORKSPACE_KEY}`,
        'Content-Type': 'application/json',
        'Idempotency-Key': '11111114-1111-4111-8111-111111111111',
    },
    body: JSON.stringify({
        label: "Harbourline freight account",
        counterparty_id: "eeeeeee3-eeee-4eee-8eee-eeeeeeeeeeee",
        currency: "IDR",
        bank_name: "Bank Central Asia",
        account_number: "8730 0412 55",
        account_holder: "PT Harbourline Indonesia",
        country_code: "ID"
    }),
});
const data = await res.json();
python
import os

import requests

resp = requests.post(
    "https://api.rekberpay.com/v1/enterprise/payout-instructions",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_WORKSPACE_KEY']}",
        "Idempotency-Key": "11111114-1111-4111-8111-111111111111",
    },
    json={
        "label": "Harbourline freight account",
        "counterparty_id": "eeeeeee3-eeee-4eee-8eee-eeeeeeeeeeee",
        "currency": "IDR",
        "bank_name": "Bank Central Asia",
        "account_number": "8730 0412 55",
        "account_holder": "PT Harbourline Indonesia",
        "country_code": "ID",
    },
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/enterprise/payout-instructions');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_WORKSPACE_KEY'),
        'Content-Type: application/json',
        'Idempotency-Key: 11111114-1111-4111-8111-111111111111',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'label' => 'Harbourline freight account',
        'counterparty_id' => 'eeeeeee3-eeee-4eee-8eee-eeeeeeeeeeee',
        'currency' => 'IDR',
        'bank_name' => 'Bank Central Asia',
        'account_number' => '8730 0412 55',
        'account_holder' => 'PT Harbourline Indonesia',
        'country_code' => 'ID',
    ]),
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

201 Created

json
{
    "success": true,
    "data": {
        "id": "22222224-2222-4222-8222-222222222222",
        "label": "Harbourline freight account",
        "counterparty": {
            "id": "eeeeeee3-eeee-4eee-8eee-eeeeeeeeeeee",
            "name": "Harbourline Components Pte Ltd"
        },
        "currency": "IDR",
        "bank_name": "Bank Central Asia",
        "account_number_masked": "8730****55",
        "account_holder": "PT Harbourline Indonesia",
        "country_code": "ID",
        "status": "pending_review",
        "signed": true,
        "verified_at": null,
        "created_at": "2026-10-13T14:33:16.301Z",
        "updated_at": "2026-10-13T14:33:16.301Z"
    }
}

It starts as pending_review. Editing the label keeps it in review; editing a bank field signs it again and sends it back to review:

bash
curl -X PATCH https://api.rekberpay.com/v1/enterprise/payout-instructions/22222224-2222-4222-8222-222222222222 \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY" \
  -H "Idempotency-Key: 33333334-3333-4333-8333-333333333333" \
  -H "Content-Type: application/json" \
  -d '{
    "label": "Harbourline freight and duties"
  }'
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/payout-instructions/22222224-2222-4222-8222-222222222222', {
    method: 'PATCH',
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_WORKSPACE_KEY}`,
        'Content-Type': 'application/json',
        'Idempotency-Key': '33333334-3333-4333-8333-333333333333',
    },
    body: JSON.stringify({
        label: "Harbourline freight and duties"
    }),
});
const data = await res.json();
python
import os

import requests

resp = requests.patch(
    "https://api.rekberpay.com/v1/enterprise/payout-instructions/22222224-2222-4222-8222-222222222222",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_WORKSPACE_KEY']}",
        "Idempotency-Key": "33333334-3333-4333-8333-333333333333",
    },
    json={
        "label": "Harbourline freight and duties",
    },
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/enterprise/payout-instructions/22222224-2222-4222-8222-222222222222');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'PATCH',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_WORKSPACE_KEY'),
        'Content-Type: application/json',
        'Idempotency-Key: 33333334-3333-4333-8333-333333333333',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'label' => 'Harbourline freight and duties',
    ]),
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

RekberPay checks the account and verifies it. You see payout_instruction.verified in the event feed when that happens.

3. Release in splits ​

The split amounts must add up to the milestone amount exactly:

400 Bad Request

json
{
    "success": false,
    "error": {
        "code": "SPLITS_MISMATCH",
        "message": "Splits must add up to the milestone amount."
    }
}

With matching amounts, the release goes through and each split becomes a queued payout:

bash
curl -X POST https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/milestones/fffffff4-ffff-4fff-8fff-ffffffffffff/release \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY" \
  -H "Idempotency-Key: 33333336-3333-4333-8333-333333333333" \
  -H "Content-Type: application/json" \
  -d '{
    "splits": [
      {
        "payout_instruction_id": "fffffff3-ffff-4fff-8fff-ffffffffffff",
        "amount": 25000000
      },
      {
        "payout_instruction_id": "22222224-2222-4222-8222-222222222222",
        "amount": 5000000
      }
    ]
  }'
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/milestones/fffffff4-ffff-4fff-8fff-ffffffffffff/release', {
    method: 'POST',
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_WORKSPACE_KEY}`,
        'Content-Type': 'application/json',
        'Idempotency-Key': '33333336-3333-4333-8333-333333333333',
    },
    body: JSON.stringify({
        splits: [
            {
                payout_instruction_id: "fffffff3-ffff-4fff-8fff-ffffffffffff",
                amount: 25000000
            },
            {
                payout_instruction_id: "22222224-2222-4222-8222-222222222222",
                amount: 5000000
            }
        ]
    }),
});
const data = await res.json();
python
import os

import requests

resp = requests.post(
    "https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/milestones/fffffff4-ffff-4fff-8fff-ffffffffffff/release",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_WORKSPACE_KEY']}",
        "Idempotency-Key": "33333336-3333-4333-8333-333333333333",
    },
    json={
        "splits": [
            {
                "payout_instruction_id": "fffffff3-ffff-4fff-8fff-ffffffffffff",
                "amount": 25000000,
            },
            {
                "payout_instruction_id": "22222224-2222-4222-8222-222222222222",
                "amount": 5000000,
            },
        ],
    },
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/milestones/fffffff4-ffff-4fff-8fff-ffffffffffff/release');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_WORKSPACE_KEY'),
        'Content-Type: application/json',
        'Idempotency-Key: 33333336-3333-4333-8333-333333333333',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'splits' => [
            [
                'payout_instruction_id' => 'fffffff3-ffff-4fff-8fff-ffffffffffff',
                'amount' => 25000000,
            ],
            [
                'payout_instruction_id' => '22222224-2222-4222-8222-222222222222',
                'amount' => 5000000,
            ],
        ],
    ]),
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

200 OK

json
{
    "success": true,
    "data": {
        "milestone_id": "fffffff4-ffff-4fff-8fff-ffffffffffff",
        "status": "released",
        "deal_status": "in_progress",
        "disbursements": [
            {
                "id": "44444446-4444-4444-8444-444444444444",
                "payout_instruction_id": "fffffff3-ffff-4fff-8fff-ffffffffffff",
                "amount": 25000000,
                "currency": "IDR",
                "status": "queued"
            },
            {
                "id": "55555556-5555-4555-8555-555555555555",
                "payout_instruction_id": "22222224-2222-4222-8222-222222222222",
                "amount": 5000000,
                "currency": "IDR",
                "status": "queued"
            }
        ]
    }
}

Every instruction must be verified, in the deal currency, and belong to the deal's counterparty or to the whole workspace, otherwise the call answers 400 INSTRUCTION_NOT_ELIGIBLE. Release is final.

4. Follow the payouts ​

bash
curl "https://api.rekberpay.com/v1/enterprise/payouts?limit=2" \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY"
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/payouts?limit=2', {
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_WORKSPACE_KEY}`,
    },
});
const data = await res.json();
python
import os

import requests

resp = requests.get(
    "https://api.rekberpay.com/v1/enterprise/payouts?limit=2",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_WORKSPACE_KEY']}",
    },
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/enterprise/payouts?limit=2');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_WORKSPACE_KEY'),
    ],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

200 OK

json
{
    "success": true,
    "data": {
        "items": [
            {
                "id": "44444446-4444-4444-8444-444444444444",
                "deal_id": "eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee",
                "deal_reference": "DEAL-2026-0009",
                "milestone_id": "fffffff4-ffff-4fff-8fff-ffffffffffff",
                "milestone_title": "Tooling and proof approval",
                "payout_instruction_id": "fffffff3-ffff-4fff-8fff-ffffffffffff",
                "instruction_label": "Harbourline IDR collection account",
                "bank_name": "DBS Bank Indonesia",
                "account_number_masked": "3320****43",
                "amount": 25000000,
                "currency": "IDR",
                "status": "queued",
                "failure_reason": null,
                "settled_at": null,
                "created_at": "2026-10-13T14:33:16.480Z",
                "updated_at": "2026-10-13T14:33:16.480Z"
            },
            {
                "id": "55555556-5555-4555-8555-555555555555",
                "deal_id": "eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee",
                "deal_reference": "DEAL-2026-0009",
                "milestone_id": "fffffff4-ffff-4fff-8fff-ffffffffffff",
                "milestone_title": "Tooling and proof approval",
                "payout_instruction_id": "22222224-2222-4222-8222-222222222222",
                "instruction_label": "Harbourline freight and duties",
                "bank_name": "Bank Central Asia",
                "account_number_masked": "8730****55",
                "amount": 5000000,
                "currency": "IDR",
                "status": "queued",
                "failure_reason": null,
                "settled_at": null,
                "created_at": "2026-10-13T14:33:16.480Z",
                "updated_at": "2026-10-13T14:33:16.480Z"
            }
        ],
        "summary": {
            "today_count": 4,
            "today_amount": 133000000,
            "avg_settlement_minutes": 32,
            "queued_amount": 58000000
        }
    },
    "pagination": {
        "page": 1,
        "limit": 2,
        "total": 8,
        "total_pages": 4
    }
}

A payout moves from queued to processing to settled. One that fails at the bank stays failed with a failure_reason until RekberPay queues it again; the milestone stays released. The events disbursement.processing, disbursement.settled and disbursement.failed tell you when.

Removing an instruction ​

An instruction that never received money can be deleted:

bash
curl -X DELETE https://api.rekberpay.com/v1/enterprise/payout-instructions/44444444-4444-4444-8444-444444444444 \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY" \
  -H "Idempotency-Key: 55555554-5555-4555-8555-555555555555"
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/payout-instructions/44444444-4444-4444-8444-444444444444', {
    method: 'DELETE',
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_WORKSPACE_KEY}`,
        'Idempotency-Key': '55555554-5555-4555-8555-555555555555',
    },
});
const data = await res.json();
python
import os

import requests

resp = requests.delete(
    "https://api.rekberpay.com/v1/enterprise/payout-instructions/44444444-4444-4444-8444-444444444444",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_WORKSPACE_KEY']}",
        "Idempotency-Key": "55555554-5555-4555-8555-555555555555",
    },
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/enterprise/payout-instructions/44444444-4444-4444-8444-444444444444');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'DELETE',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_WORKSPACE_KEY'),
        'Idempotency-Key: 55555554-5555-4555-8555-555555555555',
    ],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

200 OK

json
{
    "success": true,
    "data": {
        "id": "44444444-4444-4444-8444-444444444444",
        "deleted": true
    }
}

Next steps ​

Escrow, payment services and B2B deals for Indonesian businesses.