Skip to main content
The Cleo Pay API gives you two ways to send an ACH payment: you can pay against an existing payable (invoice), or send funds directly to a contact without referencing an invoice. Both paths use the same POST /v1/payments endpoint — the only difference is which identifier you supply.
payableId and contactId are mutually exclusive. Include one or the other in a single request — never both. Sending both fields returns a 400 Bad Request.

Path A — Pay an existing payable (invoice)

Use this path when you have an outstanding invoice or payable tracked in Cleo Pay and want to apply a payment against it.
1

Get your payable's ID

Retrieve the payable you want to pay. You can find its ID either from the response when the payable was created (POST /v1/payables) or by listing your payables (GET /v1/payables).The id field on the payable object is the value you’ll pass as payableId.
2

Submit the payment

Call POST /v1/payments with the payableId and the bankAccountId of the account you want to fund the payment from.
Pay a payable in full
3

Make a partial payment (optional)

By default, the payment amount equals the remaining balance on the payable. To pay only part of it, include amountCents in your request body. The minimum value is 1 (one cent).
Partial payment of $250.00
4

Check the returned payment status

The response includes the payableId and a payments array. Each payment object has a status field. Immediately after creation the status will be pending (or scheduled if you supplied scheduledAt).
Payment response

Path B — Send directly to a contact

Use this path when you want to push funds to a vendor or payee without attaching the payment to a specific invoice.
1

Confirm the contact is payment-ready

Before sending, ensure the contact’s paymentReady flag is true. A contact becomes payment-ready once it has a verified bank account on file.If paymentReady is false, the payment will be created with a held status and will not process until the contact adds a bank account.
A payment in held status means the contact has no bank account yet. The payment will release automatically once the contact links and verifies their account.
2

Submit the payment

Call POST /v1/payments with contactId, amountCents, and bankAccountId. You can optionally add a human-readable description and your own reference number via customNumber (maximum 21 characters).
Send $500.00 directly to a contact
3

Check the returned payment status

The response mirrors Path A — a payments array with the new payment object. When no payableId is involved, the payableId field in the response will be null.
Direct contact payment response

Payment status flow

After you create a payment, it moves through the following statuses: The typical happy-path progression is:
For scheduled payments the flow starts with scheduled before entering pending on the execution date: