---
title: "Purchases & Payables"
description: "Bills, vendor credits, supplier payments and recurring bills — record what you owe and settle it through the approval workflow."
url: "https://bareledger.app/guides/api-purchases"
category: "Developers & API"
updated: "2026-11-04"
publisher: "BareLedger (Syneria Technologies OPC)"
---

# Purchases & Payables

> Bills, vendor credits, supplier payments and recurring bills — record what you owe and settle it through the approval workflow.

## Bills

| Method & Path | Permission | Purpose | Side effects |
|---|---|---|---|
| `GET/POST bills`, `GET/PUT/DELETE bills/{document}` | `purchase.view`/`purchase.manage` | CRUD | — |
| `GET bills/{document}/pdf` / `/history` | `purchase.view` | PDF / history | — |
| `POST bills/{document}/submit` \| `/review` \| `/approve` \| `/reject` \| `/reverse` | `purchase.submit/review/approve/reject/reverse` | Workflow | `approve` **posts to ledger** (402 `usage_limit_reached` at the monthly transaction cap) |
| `GET/POST bills/{document}/attachments` | `purchase.view`/`purchase.manage` | Attachments | Stores file, audit |

## Vendor Credits

Mirror of bills at `vendor-credits` (kind=`vendor_credit`). Same CRUD + workflow shape, permission `purchase.*`. Approving posts the reverse of a bill's entries and reduces the linked bill's outstanding balance when one is set. Whatever the bill cannot absorb — a standalone credit, a bill not yet posted, or a credit larger than the bill's balance — is booked Dr `1320 Advances to Suppliers` as a **supplier prepayment** (below), never as a negative payable.

## Supplier prepayments

The purchase mirror of [customer credits](api-sales). A supplier payment above its allocations must carry `overpayment_action: "supplier_prepayment"` (`422` otherwise); when it posts, the remainder is debited to `1320 Advances to Suppliers` (an asset) instead of Accounts Payable and becomes a `SA-` numbered prepayment. A vendor credit's unapplied excess creates one the same way.

| Method & Path | Permission | Purpose | Side effects |
|---|---|---|---|
| `GET supplier-prepayments` / `GET supplier-prepayments/{prepayment}` | `payment.view` | List / detail (`?status=open|partially_applied|applied|refunded|voided|usable`, `?contact_id=`) | Each row carries `pending_request` (the open apply/refund sign-off, or `null`) |
| `POST supplier-prepayments/{prepayment}/apply` | `payment.manage` | Request applying the prepayment to a posted bill (`document_id`, `amount`, optional `reason`) | **`202`** with an approval-request row (domain `payment`, action `prepayment_apply`); posts nothing yet |
| `POST supplier-prepayments/{prepayment}/refund` | `payment.manage` | Request recording the supplier's cash refund (`cash_account_id`, optional `amount`, `reason`) | **`202`** with an approval-request row (action `prepayment_refund`); posts nothing yet |
| `POST supplier-prepayments/{prepayment}/void` | `payment.manage` | Void a prepayment that has no ledger leg | `422` while its advance sits on `1320` — apply or refund it instead |

Apply/refund requests share the customer-credit sign-off queue (`GET approval-requests?domain=payment`, same `payment.*` permissions and payment approval tiers). Approval posts `Dr Accounts Payable / Cr Advances to Suppliers` (application, settling the bill like a payment allocation) or `Dr cash / Cr Advances to Suppliers` (refund); the resulting journal entry carries the request's maker, reviewer and approver and cannot be reversed from the journal. Reversing the originating payment or vendor credit voids an untouched prepayment and is refused once it has been applied or refunded. `GET bills/{document}/payments` lists `prepayment_applications` and counts them in `summary.credits`. Web: **Purchases → Supplier Prepayments** (`/app/supplier-prepayments`) and **Prepayment Approvals**; a posted bill's detail offers **Apply prepayment** when its supplier holds an open one.

## Recurring Bills (`recurring-bills`)

Same shape as [recurring journal entries](https://bareledger.app/guides/recurring) — permission `purchase.view`/`purchase.manage`. A `source_document_id` must reference an **approved and posted** bill (`422` otherwise).
