Skip to content
Hardcount
Run it locally
Pre-1.0 · one maintainer · Stripe and cards only · no SDKs (client libraries) yet · no production users yet. Docs describe v0.9.1 (29 Oct 2026) · What’s new →

List credit notes

GET
/v1/credit-notes
curl --request GET \
--url 'http://localhost:8080/v1/credit-notes?status=draft&refund_status=none&dir=asc&limit=50&offset=0' \
--header 'Authorization: Bearer <token>'

Lists credit notes, newest first by default. The response has no total; page with limit and offset until a page comes back shorter than limit.

invoice_id
string
customer_id
string
status
string
Allowed values: draft issued voided
refund_status
string
Allowed values: none pending succeeded failed unknown needs_attention

needs_attention returns issued, non-test-clock notes whose refund failed or has an unknown result, has been pending more than 72 hours, or has a refund amount still at none after 1 hour.

sort
string

One of credit_note_number, total_cents (alias amount), status, issued_at, created_at (default).

dir
string
Allowed values: asc desc
limit
integer
default: 50 >= 1 <= 100

Rows per page, from 1 to 100. Default 50. Any other value, or one that is not a whole number, is a 422 with param: limit.

offset
integer
0

Rows to skip, 0 or more. Default 0. A negative value, or one that is not a whole number, is a 422 with param: offset.

Credit note list.

Media typeapplication/json
object
data
required
Array<object>

A credit note reduces what a customer owes on an invoice, or gives money back after it was paid. Its total is split three ways: refund to the card (refund_amount_cents), credit to the customer’s balance (credit_amount_cents), and money returned outside Hardcount (out_of_band_amount_cents).

object
id
required
string
tenant_id
string
invoice_id
required
string
customer_id
required
string
credit_note_number
required
string
status
required
string
Allowed values: draft issued voided
reason
required
string
subtotal_cents
required
integer format: int64
tax_amount_cents
required
integer format: int64
total_cents
required
integer format: int64
refund_amount_cents
required
integer format: int64
credit_amount_cents
required
integer format: int64
out_of_band_amount_cents
required
integer format: int64
commit_retired_cents

Prepaid commit credits this note retired. Absent on other notes.

integer format: int64
currency
required
string
issued_at
string format: date-time
voided_at
string format: date-time
refund_status
required

The refund part’s state at Stripe. unknown: Stripe gave no clear answer (a timeout, a network error, a Stripe 5xx, a 409 or a 429), so the customer may already be refunded. Don’t refund it again in the Stripe Dashboard. Retry it with POST /v1/credit-notes/{id}/retry-refund, which looks for the refund at Stripe first and then resends the same request with the same idempotency key.

string
Allowed values: none pending succeeded failed unknown
stripe_refund_id
string
bill_to_snapshot

What an issued invoice or credit note prints about its buyer, copied when the document was issued (ADR-109). The printed name is legal_name when set, otherwise display_name.

object
display_name
required
string
legal_name
string
email
string
address_line1
string
address_line2
string
city
string
state
string
postal_code
string
country
string
tax_id

On an invoice, the tax ID its tax was calculated with when set, otherwise the billing profile’s tax ID at issue.

string
tax_id_type
string
supplier_snapshot

What an issued invoice or credit note prints about its seller (the tenant’s company), copied when the document was issued (ADR-109).

object
name
string
email
string
phone
string
address_line1
string
address_line2
string
city
string
state
string
postal_code
string
country
string
tax_id
string
tax_transaction_id

Tax provider’s reversal transaction, set when the note is issued.

string
is_simulated
required

True when issued_at is test-clock time.

boolean
issue_pending
required

True on a draft that Hardcount will issue automatically.

boolean
tax_reversal_pending
required

True when the tax reversal failed and will be retried.

boolean
metadata
object
key
additional properties
any
created_at
required
string format: date-time
recorded_at

Real-world time the row was written, when created_at is test-clock time.

string format: date-time
updated_at
required
string format: date-time
total
required

How many rows match the request’s filters, on every page, not only this one. The audit log and the customer list’s search and name or email sort say where they stop counting.

integer

Example

{
"data": [
{
"status": "draft",
"refund_status": "none"
}
]
}

limit or offset is out of range or not a whole number, or the request sends the removed after cursor (param names it)

Media typeapplication/json
object
error
object
type

One of invalid_request_error, authentication_error, rate_limit_error or api_error. Every error the API answers has this shape, including an unknown path (404, code route_not_found) and a method the path does not take (405, code method_not_allowed, with an Allow header). The few exceptions are listed in docs/api-surface.md.

string
code
string
message
string
request_id
string
param

The request field the error is about. Sent only when the error names one. A request body may hold only the fields its operation lists, spelled and cased as listed: any other field, or one the server sets (such as id), is refused with 422 and param naming it. An operation with no request body lists no fields: send no body, {} or null. The Stripe and Postmark webhooks and the LiteLLM callback take their sender’s body as it comes.

string

Example

{
"error": {
"type": "invalid_request_error"
}
}