> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cleo-pay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Funding sources and rails

> List what the business can pay from on each rail, and learn how Cleo picks the rail and source for a payment from the fields you send.

A business can pay on two rails, Dwolla and Cleo Pay. It keeps both and picks one per payment. The business's default rail only applies when a payment names no rail and no source. The other rail stays usable.

## List what the business can pay from

```bash theme={null}
curl https://api.stg.cleo-pay.com/v1/funding-sources \
  --header "Authorization: Bearer $CLEO_API_KEY"
```

The key needs `payments:initiate`, `bank-accounts:read` or `bank-accounts:write`.

```json theme={null}
{
  "items": [
    {
      "id": "balance",
      "rail": "CLEO_PAY",
      "kind": "balance",
      "name": "Cleo Pay balance",
      "last4": null,
      "availableCents": 4250000,
      "isDefault": true,
      "canPay": true,
      "unavailableReason": null,
      "actionUrl": null,
      "pay": { "paymentRail": "CLEO_PAY", "fundingSource": "BALANCE" }
    },
    {
      "id": "linked_bank",
      "rail": "CLEO_PAY",
      "kind": "linked_bank",
      "name": "Chase",
      "last4": "4321",
      "availableCents": null,
      "isDefault": false,
      "canPay": false,
      "unavailableReason": "bank_funding_unavailable",
      "actionUrl": null,
      "pay": { "paymentRail": "CLEO_PAY", "fundingSource": "BANK" }
    },
    {
      "id": "7c2e9a10-3b4d-4f5e-8a6b-9c0d1e2f3a4b",
      "rail": "DWOLLA",
      "kind": "bank",
      "name": "Operating account",
      "last4": "9876",
      "availableCents": null,
      "isDefault": false,
      "canPay": true,
      "unavailableReason": null,
      "actionUrl": null,
      "pay": { "paymentRail": "DWOLLA", "bankAccountId": "7c2e9a10-3b4d-4f5e-8a6b-9c0d1e2f3a4b" }
    }
  ]
}
```

| `kind` | What it is | Appears when |
| - | - | - |
| `balance` | The Cleo Pay balance | The business has a Cleo Pay account |
| `linked_bank` | The bank linked to Cleo Pay | The business has a Cleo Pay account |
| `bank` | A verified Dwolla bank | One item per verified Dwolla bank |

Sources on the default rail come first. `isDefault` marks the source a payment uses when it names nothing. `availableCents` is set on the balance only, and only when the key can read payments or the balance.

When `canPay` is `false`, `unavailableReason` says why and `actionUrl` (when set) links to the web page where your user fixes it:

| `unavailableReason` | Meaning |
| - | - |
| `cleo_pay_not_ready` | The Cleo Pay account cannot send payments yet. |
| `no_linked_bank` | No bank is linked to Cleo Pay. |
| `bank_funding_unavailable` | Paying from the linked bank is not available through the API yet. |
| `bank_reauth` | The Dwolla bank needs to be reconnected on the web. |
| `rail_not_ready` | The business cannot send on the Dwolla rail yet. |

New reasons may be added. Treat an unknown reason as "cannot pay from this source now".

## Pay from a source

Copy the chosen item's `pay` fields into `POST /v1/payments`:

| Source | Fields to send |
| - | - |
| Cleo Pay balance | `"paymentRail": "CLEO_PAY", "fundingSource": "BALANCE"` |
| Bank linked to Cleo Pay | `"paymentRail": "CLEO_PAY", "fundingSource": "BANK", "achAuthorizationAccepted": true` |
| Dwolla bank | `"paymentRail": "DWOLLA", "bankAccountId": "<id>"` |

The listing never includes `achAuthorizationAccepted`. A list is not consent. Add it yourself, and only after your user has accepted the ACH debit authorization for the linked bank.

<Note>
  **Paying from the linked bank is not available through the API yet.** `fundingSource: "BANK"` answers `403 feature_unavailable`, and the linked bank lists with `canPay: false` and `unavailableReason: "bank_funding_unavailable"`. Pay from the balance or a Dwolla bank. When Cleo turns bank funding on, it records your API key and the request's IP address with the authorization.
</Note>

## How Cleo picks the rail

Cleo reads the fields you send in this order:

1. If you send `paymentRail`, that is the rail.
2. Otherwise, if you send `fundingSource`, the rail is Cleo Pay.
3. Otherwise, if `bankAccountId` is one of the business's Dwolla banks, the rail is Dwolla.
4. Otherwise, the business's default rail applies.

Cleo then checks that the business can send on that rail. It does not fall back to the other rail.

Some combinations are refused with `400 validation_error`, so a field is never silently ignored:

| You send | Result |
| - | - |
| `paymentRail: "DWOLLA"` with `fundingSource` | Refused |
| A Dwolla `bankAccountId` with `paymentRail: "CLEO_PAY"` or a `fundingSource` | Refused |
| The Dwolla rail without `bankAccountId`, or with a bank that is not a Dwolla bank | Refused |
| `achAuthorizationAccepted` on Dwolla, or with `fundingSource: "BALANCE"` | Refused |
| `clearing` or `scheduledAt` on Cleo Pay | Refused. Both are Dwolla only. |
| `fundingSource: "BANK"` without `achAuthorizationAccepted: true` | Refused, once bank funding is on |

A `bankAccountId` that is not one of the business's banks answers `404 not_found`. On Cleo Pay, an omitted `fundingSource` pays from the balance.

The older body `{ "payableId": "...", "bankAccountId": "..." }` still works. A Dwolla bank in it pays on Dwolla, whatever the default rail. Any other bank id on a business whose default rail is Cleo Pay pays from the Cleo Pay balance. The response always says which rail and source were used.

## Retries keep their rail

A bill whose last payment failed is retried on the rail of that failed payment, never on the current default. When nothing moved yet, the retry also uses the same source. If you pay such a bill with `POST /v1/payments`, name that rail and source. Anything else answers `validation_error` with the fields to send. See [Cancel and retry](/guides/cancel-and-retry).

## Related

* [Send a payment](/guides/send-a-payment)
* [`GET /v1/funding-sources`](/api-reference/funding-sources/list)
* [`GET /v1/business`](/api-reference/business/get) for per-rail send and receive readiness


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.