Create a Disbursement

Overview

Your Organization might use Branch to pay Workers more quickly, or simply to streamline your payment processes. Whether this means a paycheck, tips/mileage, or automatic payouts right after completing a shift, all of these payments are considered Disbursements by Branch.

Disbursements

When a job is confirmed and ready for payment, your Organization will call the Create Disbursement endpoint to post earnings to the Worker’s Branch Wallet. When successfully processed, funds are immediately available to spend, transfer, or withdraw. You may review detailed Disbursement processing reports via the Pay Admin portal.

Disbursement Adjustments

You can add Disbursement Adjustments to the API request body as metadata.
The Worker can view these adjustments by clicking into the Disbursement details in-app, and designated admins can view them in the Branch Pay Admin Portal.

The Disbursement's metadata field allows any valid JSON, but has special handling if an adjustments key is present at the top level. The adjustments metadata object fields adjustments, name, and amount are fixed and must be used as shown in the example. Their paired values can be whatever you choose, as long as they adhere to these restrictions:

  • The name value has a 50-character limit.
  • Deducted amounts are negative integer cent values, with no currency specified. For example -684
  • Added amounts are positive integer cent values with no currency specified. For example 200

Branch will not do any calculations to validate the net versus the base pay. Branch will take the Disbursement amount as net and sum the inverse of all deduction values, positive or negative, to display as a base pay amount. Any discrepancies in that value will be the customer's responsibility.

Branch displays the adjustments in the order that they were provided in the API request body.

Example Disbursement Request Body with Adjustments

{
  "worker_id": "123456",
  "external_id": "7de69037-c2ca-4214-99a7-fc76a73642c1",
  "type": "PAYCHECK",
  "amount": 500,
  "description": "Deposit Test",
  "metadata": {
    "adjustments": [
      {
        "name": "401k",
        "amount": -1000
      },
      {
        "name": "Insurance",
        "amount": -684
      },
      {
        "name": "Union Dues",
        "amount": -21
      },
      {
        "name": "Cell Phone",
        "amount": 200
      }
    ],
    "custom-key": {
      "custom-data": "custom-value"
    }
  }
}

The base pay displayed from the example data would be calculated as follows:

Summed Adjustments = -1000 + -684 + -21 + 200 = -1505

Base Pay = Disbursement Amount - Summed Adjustments = 500 - (-1505) = 2505 = $25.05

Disbursement Failures

In the event a disbursement fails, your Organization is responsible for taking the appropriate action to ensure workers receive payment. Below is a listing of the potential reason codes for situations preventing successful disbursement.

Reason Code

Description

PAYOUT_PENDING

The disbursement is still in progress.

AMOUNT_ZERO

The payout was recorded with an amount of $0.00

RETRY_PERIOD_ELAPSED

The disbursement already existed and is too old to be attempted again.

RETRY_LIMIT_EXCEEDED

The disbursement has been retried the max number of allowed attempts.

LIKELY_MATCH_FOUND

The disbursement was not attempted because another disbursement was identified as a duplicate.

WORKER_NOT_FOUND

The worker was not found on the active roster.

PAYMENT_PROFILE_NOT_FOUND

No destination account could be found for the provided worker.

PAYMENT_PROFILE_SUSPENDED

The destination account is not payable due to suspension.

PAYMENT_PROFILE_NOT_ACTIVE

The destination account is not payable because it is closed or otherwise inactive.

PAYMENT_PROFILE_FRAUDULENT

The destination account is not payable because it has been closed for fraud.

TRANSFER_FAILED

An error occurred while issuing the funds to the worker.

AMOUNT_EXCEEDS_ORG_
SINGLE_DISBURSEMENT_LIMIT

The amount exceeds the organization's limit for a single disbursement.

AMOUNT_EXCEEDS_ORG_
DAILY_DISBURSEMENT_LIMIT

The amount would exceed the organization's daily limit for disbursements.

AMOUNT_EXCEEDS_WORKER_
DAILY_DISBURSEMENT_LIMIT

The amount would exceed the worker's daily limit for disbursements.

AMOUNT_DOES_NOT_
COVER_USER_FEES

The fee to be charged to the worker exceeds or is equal to the disbursement amount.

UNEXPECTED_ERROR

Something unexpected occurred. Contact Branch support if this persists.

Disbursement Mock Responses

The Create Disbursement metadata field has special handling in the Sandbox environment depending on the value associated with a mock_response key at the top level.

Example Disbursement Request Body and associated Mock Response

{
  "worker_id": "123456",
  "external_id": "7de69037-c2ca-4214-99a7-fc76a73642c1",
  "type": "PAYCHECK",
  "amount": 500,
  "description": "Deposit Test",
  "metadata": {
    "mock_response": "LIKELY_MATCH_FOUND"
  }
}
{
  "worker_id": "123",
  "amount": 500,
  "external_id": "7de69037-c2ca-4214-99a7-fc76a73642c1",
  "type": "PAYCHECK",
  "worker_group": "Store #1",
  "description": "Deposit Test",
  "display_header_label": "Paycheck",
  "display_sub_label": "Pizza Delivery Company",
  "status": "SKIPPED",
  "reason_code": "LIKELY_MATCH_FOUND",
  "payout": {
    "id": "123",
    "payment_type": "WALLET",
    "amount": 500,
    "fee": 100,
    "org_paid_fee": 50,
    "time_completed": "2025-07-16T22:37:20.000Z"
  },
  "metadata": {
    "mock_response": "LIKELY_MATCH_FOUND"
  },
  "time_created": "2025-07-16T22:37:30.301Z",
  "time_modified": "2025-07-16T22:37:30.301Z"
}

mock_response

Reason Code

Status

HTTP

AMOUNT_ZERO

AMOUNT_ZERO

COMPLETED

201

RETRY_PERIOD_ELAPSED

RETRY_PERIOD_ELAPSED

SKIPPED

200

RETRY_LIMIT_EXCEEDED

RETRY_LIMIT_EXCEEDED

SKIPPED

200

LIKELY_MATCH_FOUND

LIKELY_MATCH_FOUND

SKIPPED

200

WORKER_NOT_FOUND

WORKER_NOT_FOUND

FAILED

202

PAYMENT_PROFILE_NOT_FOUND

PAYMENT_PROFILE_NOT_FOUND

FAILED

202

PAYMENT_PROFILE_SUSPENDED

PAYMENT_PROFILE_SUSPENDED

FAILED

202

PAYMENT_PROFILE_NOT_ACTIVE

PAYMENT_PROFILE_NOT_ACTIVE

FAILED

202

PAYMENT_PROFILE_FRAUDULENT

PAYMENT_PROFILE_FRAUDULENT

FAILED

202

TRANSFER_FAILED

TRANSFER_FAILED

FAILED

202

AMOUNT_EXCEEDS_ORG_
SINGLE_DISBURSEMENT_LIMIT

AMOUNT_EXCEEDS_ORG_
SINGLE_DISBURSEMENT_LIMIT

FAILED

202

AMOUNT_EXCEEDS_ORG_
DAILY_DISBURSEMENT_LIMIT

AMOUNT_EXCEEDS_ORG_
DAILY_DISBURSEMENT_LIMIT

FAILED

429

AMOUNT_EXCEEDS_WORKER_
DAILY_DISBURSEMENT_LIMIT

AMOUNT_EXCEEDS_WORKER_
DAILY_DISBURSEMENT_LIMIT

FAILED

202

AMOUNT_DOES_NOT_
COVER_USER_FEES

AMOUNT_DOES_NOT_
COVER_USER_FEES

FAILED

202

UNEXPECTED_ERROR

UNEXPECTED_ERROR

FAILED

202

PAYOUT_PENDING

PAYOUT_PENDING

PENDING

202

SCHEDULED

null

SCHEDULED

201

DUPLICATE_SCHEDULED

null

SCHEDULED

200

COMPLETED

null

COMPLETED

201

DUPLICATE_COMPLETED

null

COMPLETED

200

CANCELED

null

CANCELED

200

BAD_REQUEST

null

null

400

INTERNAL_SERVER_ERROR

null

null

500