---
title: "Cancel a bill that should never have been billed (wrong patient, duplicate, service
    not rendered, goodwill write-off): Status → InvoiceStatus.Void, terminal.
    This is the exit for invoices built directly in the Payments panel, which have no
    source estimate and therefore can't revert. A required reason lands in the payment
    audit log. Refused once any money is attached — reverse the payments first (a Void
    bill can never take or hold a payment). Dispensed lines do NOT block: voiding the
    bill never returns stock (there is no reverse-dispense primitive; see
    docs/dispensing.md §5) — stock corrections are a separate inventory adjustment.
    Distinct from Superseded (finalized then replaced): merge and revert keep producing
    Superseded; Void means cancelled outright.
    Releases the bill's claims on everything upstream of it — the appointment slot, the
source quote's invoice_id, and the reverse dispense links — so a live quote
stops resolving to a written-off bill. Unlike revert-to-estimate this leaves the
quote's EstimateStatus untouched: void cancels the bill, it does not
reopen the quote for editing."
method: POST
path: "/Invoices/{id}/void"
tags: ["Invoices"]
---

# Cancel a bill that should never have been billed (wrong patient, duplicate, service
    not rendered, goodwill write-off): Status → InvoiceStatus.Void, terminal.
    This is the exit for invoices built directly in the Payments panel, which have no
    source estimate and therefore can't revert. A required reason lands in the payment
    audit log. Refused once any money is attached — reverse the payments first (a Void
    bill can never take or hold a payment). Dispensed lines do NOT block: voiding the
    bill never returns stock (there is no reverse-dispense primitive; see
    docs/dispensing.md §5) — stock corrections are a separate inventory adjustment.
    Distinct from Superseded (finalized then replaced): merge and revert keep producing
    Superseded; Void means cancelled outright.
    Releases the bill's claims on everything upstream of it — the appointment slot, the
source quote's invoice_id, and the reverse dispense links — so a live quote
stops resolving to a written-off bill. Unlike revert-to-estimate this leaves the
quote's EstimateStatus untouched: void cancels the bill, it does not
reopen the quote for editing.

`POST /Invoices/{id}/void`

## Path parameters

- `id` string, required

## Request body

- VoidInvoiceDto — Request body for POST /invoices/{id}/void — cancel a bill that should never have been billed. The reason is required: voiding erases receivable revenue, so every void must carry a human-stated why into the audit log.
  - `reason` string, nullable

## Response `200`

OK

- InvoiceDto
  - `id` string
  - `invoiceNumber` string
  - `clientId` string, nullable
  - `clientName` string, nullable
  - `patientId` string, nullable
  - `patientName` string, nullable
  - `appointmentId` string, nullable
  - `providerMode` string
  - `invoiceProviderId` string, nullable
  - `invoiceProvider` UserSummaryDto
    - `id` string
    - `email` string
    - `firstName` string, nullable
    - `lastName` string, nullable
    - `displayName` string, nullable
    - `type` string
    - `roleId` string, nullable
    - `roleName` string, nullable
  - `status` string
  - `subTotal` union
    - number, double
    - string, double
  - `taxableSubTotal` union
    - number, double
    - string, double
  - `taxRate` union
    - number, double
    - string, double
  - `taxAmount` union
    - number, double
    - string, double
  - `taxMode` string — "us-sales-tax" or "vat" — snapshot at estimate creation.
  - `discountTotal` union
    - number, double
    - string, double
  - `orderDiscountAmount` union
    - number, double
    - string, double
  - `ruleOrderDiscountAmount` union — Order-level discount produced by the price rule engine (separate from discount codes).
    - number, double
    - string, double
  - `totalAmount` union
    - number, double
    - string, double
  - `notes` string, nullable
  - `mergedIntoInvoiceId` string, nullable — Set when this invoice was merged into a new combined invoice (it is then Superseded): the id of the successor bill.
  - `mergedIntoInvoiceNumber` string, nullable — Human-readable number of the successor combined invoice this one was merged into (set only on a Superseded source). Lets the UI link forward without a second fetch.
  - `mergedFromInvoices` MergedInvoiceRefDto[] — The source invoices this combined bill was assembled from (empty for a normal invoice). Drives the "Combined from …" provenance shown on the merged invoice.
    - `id` string
    - `invoiceNumber` string
    - `patientName` string, nullable
  - `signatureData` string, nullable
  - `signedAt` string, date-time, nullable
  - `issuedAt` string, date-time, nullable — When the bill was issued (Draft → Unpaid) and its totals frozen. Null for Drafts and legacy invoices issued before the issue boundary.
  - `items` InvoiceLineItemDto[]
    - `id` string
    - `invoiceId` string
    - `serviceCatalogItemId` string, nullable
    - `retailItemId` string, nullable
    - `retailItem` RetailItemSummaryDto
      - `id` string
      - `sku` string
      - `barcode` string, nullable
      - `name` string
      - `invoiceName` string, nullable
      - `category` string
      - `unitPrice` union
        - number, double
        - string, double
      - `isTaxable` boolean
      - `isActive` boolean
      - `quantityOnHand` union
        - number, double
        - string, double
      - `isLowStock` boolean
      - `vendorId` string, nullable
      - `vendorName` string, nullable
    - `inventoryItemId` string, nullable
    - `billableItemId` string, nullable — Source BillableItem ("Charge") when this line was added from the charge catalog.
    - `billableItemName` string, nullable — Display name of the source BillableItem (snapshot, response-only).
    - `isFulfilled` boolean — True when a BillableItem charge line has been fulfilled — its inventory components dispensed (derived from linked transactions, response-only).
    - `inventoryTransactionId` string, nullable
    - `unitCost` union
      - number, double
      - string, double
    - `code` string, nullable
    - `description` string
    - `unitPrice` union
      - number, double
      - string, double
    - `quantity` union
      - number, double
      - string, double
    - `discount` union
      - number, double
      - string, double
    - `appliedDiscountPolicyId` string, nullable
    - `appliedDiscountCode` string, nullable
    - `ruleDiscount` union — Discount produced by the price rule engine (separate from the manual `Discount`).
      - number, double
      - string, double
    - `dispenseFee` union
      - number, double
      - string, double
    - `lineTotal` union
      - number, double
      - string, double
    - `isTaxable` boolean
    - `vatCategory` string, nullable
    - `lineTaxAmount` union
      - number, double
      - string, double
    - `providerId` string, nullable
    - `provider` UserSummaryDto
      - `id` string
      - `email` string
      - `firstName` string, nullable
      - `lastName` string, nullable
      - `displayName` string, nullable
      - `type` string
      - `roleId` string, nullable
      - `roleName` string, nullable
    - `notes` string, nullable
    - `displayOrder` union
      - integer
      - string, int32
    - `groupCodeId` string, nullable — Kit this line came from, when emitted via GroupCode expansion.
    - `groupCodeName` string, nullable — Snapshot of the kit's display name at time of add.
  - `appliedDiscounts` AppliedDiscountDto[]
    - `id` string
    - `invoiceId` string
    - `discountPolicyId` string
    - `invoiceLineItemId` string, nullable
    - `discountCode` string
    - `discountName` string
    - `discountType` string
    - `discountValue` union
      - number, double
      - string, double
    - `calculatedAmount` union
      - number, double
      - string, double
    - `appliedBy` UserSummaryDto
      - `id` string
      - `email` string
      - `firstName` string, nullable
      - `lastName` string, nullable
      - `displayName` string, nullable
      - `type` string
      - `roleId` string, nullable
      - `roleName` string, nullable
    - `appliedAt` string, date-time
  - `appliedPriceRules` AppliedPriceRuleDto[] — Audit records of price rules that produced discounts on this estimate.
    - `id` string
    - `priceRuleId` string
    - `invoiceLineItemId` string, nullable
    - `ruleName` string
    - `ruleType` string
    - `calculatedAmount` union
      - number, double
      - string, double
    - `evaluatedAt` string, date-time
  - `createdBy` UserSummaryDto
    - `id` string
    - `email` string
    - `firstName` string, nullable
    - `lastName` string, nullable
    - `displayName` string, nullable
    - `type` string
    - `roleId` string, nullable
    - `roleName` string, nullable
  - `createdAt` string, date-time
  - `updatedAt` string, date-time

## Other responses

- `400` — Bad Request
- `404` — Not Found
- `409` — Conflict

---

[API](https://skmtc.net/clinicos/apis/pawthosx-business-api-v1.md) · [All operations](https://skmtc.net/clinicos/apis/pawthosx-business-api-v1/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/clinicos/pawthosx-business-api-v1/versions/a905bde4e796/schema)
