Skip to main content
Cancels an open or overdue invoice and moves it to void status. The invoice number is kept on the record — it is not recycled or reassigned to a future invoice. This is intentional: an auditor reviewing a consecutive series expects to find every number accounted for. A voided invoice with a reason is the correct audit artifact; a missing number is a red flag. After voiding, amount_due drops to 0, voided_at is set to the current server time, and the invoice.voided webhook event fires.
Base URL: https://invoice.horizonpay.co

Authentication

string
required
Bearer token in the form Bearer inv_live_…. The token must carry the invoices:finalize scope (finalizing and voiding are the two halves of controlling the invoice number series).
string
required
A unique key (UUID or any string up to 255 characters) you generate per logical void operation. This endpoint requires the header — the request is rejected with 428 if it is absent.
string
application/json. Required when sending a body; may be omitted if the body is empty.

Path Parameters

string
required
The invoice’s public ID (in_…) or its UUID. The invoice must currently be in open or overdue status.

Body Parameters

string
Human-readable explanation for why the invoice is being voided (e.g. "Duplicate invoice created in error", "Customer requested cancellation", "Incorrect amount — replacement invoice issued as INV/25-26/0043"). Stored in void_reason and shown in the invoice timeline. Optional, but strongly recommended for audit purposes.

Request Example


Response Example

Idempotency-Key is required on this endpoint. Voiding an invoice with a number is a legally significant, irreversible action. A retry without a key on an already-voided invoice returns 409 invalid_state, but a race between two retries could fire two invoice.voided webhook deliveries. Always generate a fresh UUID per void operation and retain it for retries.
Paid invoices cannot be voided. Once an invoice has been marked paid, reversing it requires a credit note — a separate document with its own number and audit trail. Credit notes are out of scope for v1. Attempting to void a paid invoice returns 409 invalid_state.
Draft invoices do not need to be voided — they can be deleted with DELETE /api/v1/invoices/:id because they have no number. Void is only meaningful once a number has been assigned by finalization.
The response does not include the lines field. The line items are unchanged by voiding and can be retrieved with GET /api/v1/invoices/:id if needed.

Response Fields

string
Unique public identifier for the invoice, prefixed in_.
string
Always "invoice".
string
The invoice number is preserved on the void record. It is never reassigned.
string
"void" after a successful void operation.
integer
Always 0 after the invoice is voided.
string
ISO 8601 datetime when the invoice was voided.
string | null
The reason string you supplied, or null if none was provided.
null
Always null — a voided invoice was never paid.
For all other fields, see the Retrieve Invoice response fields.

Error Codes