> ## 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.

# Invoices and getting paid

> Invoices are what customers owe the business. Create and send them with a hosted pay link, follow their status, void them, and check whether the business can receive payments.

An invoice is money a customer owes the business. The business creates it for one of its contacts, Cleo emails the customer a link, and the customer pays on Cleo's hosted page. Bills the business owes its vendors are [payables](/concepts/payables), a separate resource.

| Call | Permission scope | Does |
| - | - | - |
| [`GET /v1/invoices`](/api-reference/invoices/list) | `invoices:read` | Lists invoices, newest first. |
| [`GET /v1/invoices/{invoiceId}`](/api-reference/invoices/get) | `invoices:read` | Reads one invoice with its line items and pay link. |
| [`POST /v1/invoices`](/api-reference/invoices/create) | `invoices:write` | Creates an invoice, as a draft or sent right away. |
| [`POST /v1/invoices/{invoiceId}/send`](/api-reference/invoices/send) | `invoices:write` | Finalizes a draft if needed and emails the pay link. |
| [`POST /v1/invoices/{invoiceId}/void`](/api-reference/invoices/void) | `invoices:write` | Voids the invoice and turns its link off. |
| [`POST /v1/invoices/{invoiceId}/mark-paid`](/api-reference/invoices/mark-paid) | `invoices:write` | Records money received outside Cleo. |
| [`PUT /v1/invoices/{invoiceId}/payment-link`](/api-reference/invoices/payment-link) | `invoices:write` | Turns the hosted pay link on or off. |
| [`GET /v1/receiving`](/api-reference/receiving/get) | `invoices:read` | Says whether customers can pay the business now, and on which rail. |

`invoices:write` does not include reads. Most integrations request both scopes.

## Status

| `status` | Meaning |
| - | - |
| `draft` | Not sent yet. Its link is off. |
| `open` | Sent and waiting for payment. |
| `paid` | Fully paid, on either rail, or marked paid outside Cleo. |
| `void` | Voided. |
| `declined`, `blocked` | The customer's business refused it. |

`paymentStatus` tracks the payments on the invoice with the same values as on a payable: `none`, `scheduled`, `processing`, `held`, `settled`, `failed` and `clawback`.

## Creating an invoice

```json theme={null}
{
  "contactId": "8a7b6c5d-4e3f-4a1b-9c8d-7e6f5a4b3c2d",
  "items": [
    { "name": "Event catering", "quantity": 1, "unitAmountCents": 480000 },
    { "name": "Staffing", "quantity": 4, "unitAmountCents": 12500 }
  ],
  "dueDate": "2026-11-30",
  "customNumber": "INV-2026-118",
  "description": "Catering for the 14 November launch",
  "send": { "message": "Thanks for your business." }
}
```

* The total is the sum of the line totals. It must be at least \$1.00.
* Each item needs a `name` and a `unitAmountCents` of at least 1. `quantity` defaults to 1 and can be up to 99,999,999.
* The contact must be active, not archived, and set to `bidirectional` or `can_be_paid`.
* Without `send`, the invoice is a draft. With `send`, Cleo checks that the business can receive, finalizes the invoice and emails it. `send` needs the edit permission that `invoices:write` grants.
* `send.emails` overrides the recipients. By default Cleo uses the customer's email on file. `send.subject` and `send.message` change the email.

If the invoice is created but the email fails, the error names the invoice id. A retry with the same `Idempotency-Key` returns that answer instead of creating a second invoice. Send it with `POST /v1/invoices/{invoiceId}/send`.

## The pay link

```json theme={null}
"paymentLink": {
  "enabled": true,
  "url": "https://stg.cleo-pay.com/pay/2Yt8kQ...",
  "expiresAt": null
}
```

`enabled` is `true` only while the customer can pay through the link: the link is on and not expired, the invoice is open with money still due, and the business can receive. The hosted page refuses draft, awaiting-approval, declined and blocked invoices. The PDF is never attached to the email; the hosted page offers it.

## Can the business receive?

`GET /v1/receiving` answers before you send:

```json theme={null}
{
  "canReceive": true,
  "customerPaymentRail": "CLEO_PAY",
  "cardPaymentsEnabled": true,
  "blockedCode": null,
  "blockedReason": null,
  "requirement": null,
  "actionUrl": null,
  "rails": [
    { "rail": "DWOLLA", "canReceive": true, "blockedReason": null },
    { "rail": "CLEO_PAY", "canReceive": true, "blockedReason": null }
  ]
}
```

| Field | Meaning |
| - | - |
| `customerPaymentRail` | The rail a customer pays on through a pay link today. It is the business's default rail. |
| `cardPaymentsEnabled` | Customers can pay by card. Cleo Pay rail only. |
| `blockedCode` | `payments_locked`, `setup_incomplete`, `setup_required` or `feature_unavailable`, the same codes as the error envelope. |
| `requirement` | With `setup_required`: what to set up on the web. |
| `actionUrl` | Where the business fixes the block. While payments are locked, the booking link. |
| `rails` | Each rail's own readiness. |

Sends and link changes that cannot proceed answer with the same codes.

## Voiding and marking paid

* **Void**: only the business that created the invoice can void it. Paid, partly paid and scheduled invoices cannot be voided, and an invoice with a payment in flight answers `payment_in_progress`. The customer sees `reason`.
* **Mark paid**: records `amountCents` (default: what is still due), `method` (`check`, `ach`, `zelle`, `wire_transfer`, `cash`, `venmo`, `credit_card` or `other`) and a `note`. It works on an open invoice awaiting payment, a partly paid one, or one whose Cleo payment failed.

## Events

Invoices send `invoice.sent` and `invoice.paid`, plus the `payable.*` events. See [Webhooks](/reference/webhooks).


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