API reference
Invoices
What customers are billed: drafts written freely, issued onto receivables with their due day, voided by reversal.
- GET
/v1/invoicesList invoices - POST
/v1/invoicesWrite a draft invoice - GET
/v1/invoices/{invoice_id}Get an invoice - PATCH
/v1/invoices/{invoice_id}Change a draft invoice - DELETE
/v1/invoices/{invoice_id}Delete a draft invoice - POST
/v1/invoices/{invoice_id}/issueIssue an invoice onto the books - POST
/v1/invoices/{invoice_id}/payment_linkMake a payment link for an invoice - DELETE
/v1/invoices/{invoice_id}/payment_linkTake an invoice's payment link away - PUT
/v1/invoices/{invoice_id}/remindersTurn an invoice's reminders on or off - POST
/v1/invoices/{invoice_id}/voidVoid an issued invoice
Guides: Bill customers with invoices
List invoices
GET/v1/invoices
client.invoices.list()
The invoices of these books, the newest first, each with what is still owed on it.
Parameters
| Name | Type | Description |
|---|---|---|
statusQuery | string or null | Only |
party_idQuery | string or null | An id that starts with |
limitQuery | integer | Page size, 1–200. |
cursorQuery | string or null | The |
Response
200InvoicePage
Errors
- 400
- The request was malformed or a parameter is invalid.
- 401
- No valid credential was sent.
- 403
- The credential or the member's role does not allow this.
- 404
- No such resource in this ledger.
- 409
- A conflicting request, e.g. one with the same Idempotency-Key still running.
- 422
- A well-formed request a business rule refused.
- 429
- Too many requests; retry after the Retry-After header.
- 500
- Something failed on our side; the request_id identifies it.
Example
curl "https://api.ledgerit.ai/v1/invoices" \
-H "Authorization: Bearer $LEDGERIT_TOKEN"Write a draft invoice
POST/v1/invoices· Idempotent
client.invoices.create()
Write a draft invoice for a customer. Nothing is on the books until it is issued. Its number is the next of these books' own when left out, and it falls due on the customer's payment terms (30 days without) when no due day is given.
Request body
Response
201InvoiceOut
Errors
- 400
- The request was malformed or a parameter is invalid.
- 401
- No valid credential was sent.
- 403
- The credential or the member's role does not allow this.
- 404
- No such resource in this ledger.
- 409
- A conflicting request, e.g. one with the same Idempotency-Key still running.
- 422
- A well-formed request a business rule refused.
- 429
- Too many requests; retry after the Retry-After header.
- 500
- Something failed on our side; the request_id identifies it.
Example
curl -X POST "https://api.ledgerit.ai/v1/invoices" \
-H "Authorization: Bearer $LEDGERIT_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"issue_date":"2026-09-30","lines":[{"account_id":"…","description":"…","unit_price":0}],"party_id":"…"}'Get an invoice
GET/v1/invoices/{invoice_id}
client.invoices.get()
One invoice, its lines and what is still owed on it.
Parameters
| Name | Type | Description |
|---|---|---|
invoice_idPath · Required | string | An id that starts with |
Response
200InvoiceOut
Errors
- 400
- The request was malformed or a parameter is invalid.
- 401
- No valid credential was sent.
- 403
- The credential or the member's role does not allow this.
- 404
- No such resource in this ledger.
- 409
- A conflicting request, e.g. one with the same Idempotency-Key still running.
- 422
- A well-formed request a business rule refused.
- 429
- Too many requests; retry after the Retry-After header.
- 500
- Something failed on our side; the request_id identifies it.
Example
curl "https://api.ledgerit.ai/v1/invoices/{invoice_id}" \
-H "Authorization: Bearer $LEDGERIT_TOKEN"Change a draft invoice
PATCH/v1/invoices/{invoice_id}· Idempotent
client.invoices.update()
Change a draft: any field given, and every line at once when lines
is. An issued invoice is refused with conflict: void it and issue
another.
Parameters
| Name | Type | Description |
|---|---|---|
invoice_idPath · Required | string | An id that starts with |
Request body
Response
200InvoiceOut
Errors
- 400
- The request was malformed or a parameter is invalid.
- 401
- No valid credential was sent.
- 403
- The credential or the member's role does not allow this.
- 404
- No such resource in this ledger.
- 409
- A conflicting request, e.g. one with the same Idempotency-Key still running.
- 422
- A well-formed request a business rule refused.
- 429
- Too many requests; retry after the Retry-After header.
- 500
- Something failed on our side; the request_id identifies it.
Example
curl -X PATCH "https://api.ledgerit.ai/v1/invoices/{invoice_id}" \
-H "Authorization: Bearer $LEDGERIT_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{}'Delete a draft invoice
DELETE/v1/invoices/{invoice_id}· Idempotent
client.invoices.delete()
Delete a draft. An issued invoice is refused with conflict: it is
voided instead, and stays.
Parameters
| Name | Type | Description |
|---|---|---|
invoice_idPath · Required | string | An id that starts with |
Response
204No content
Errors
- 400
- The request was malformed or a parameter is invalid.
- 401
- No valid credential was sent.
- 403
- The credential or the member's role does not allow this.
- 404
- No such resource in this ledger.
- 409
- A conflicting request, e.g. one with the same Idempotency-Key still running.
- 422
- A well-formed request a business rule refused.
- 429
- Too many requests; retry after the Retry-After header.
- 500
- Something failed on our side; the request_id identifies it.
Example
curl -X DELETE "https://api.ledgerit.ai/v1/invoices/{invoice_id}" \
-H "Authorization: Bearer $LEDGERIT_TOKEN" \
-H "Idempotency-Key: $(uuidgen)"Issue an invoice onto the books
POST/v1/invoices/{invoice_id}/issue· Idempotent
client.invoices.issue()
Put a draft on the books: one entry on its issue day, the total on accounts receivable naming the customer, against each line's account. What the customer owes then ages from the invoice's due day.
Parameters
| Name | Type | Description |
|---|---|---|
invoice_idPath · Required | string | An id that starts with |
Response
200InvoiceOut
Errors
- 400
- The request was malformed or a parameter is invalid.
- 401
- No valid credential was sent.
- 403
- The credential or the member's role does not allow this.
- 404
- No such resource in this ledger.
- 409
- A conflicting request, e.g. one with the same Idempotency-Key still running.
- 422
- A well-formed request a business rule refused.
- 429
- Too many requests; retry after the Retry-After header.
- 500
- Something failed on our side; the request_id identifies it.
Example
curl -X POST "https://api.ledgerit.ai/v1/invoices/{invoice_id}/issue" \
-H "Authorization: Bearer $LEDGERIT_TOKEN" \
-H "Idempotency-Key: $(uuidgen)"Make a payment link for an invoice
POST/v1/invoices/{invoice_id}/payment_link· Idempotent
client.invoices.createPaymentLink()
Make a Stripe-hosted payment link for what is still owed on an issued
invoice, in the books' own Stripe account, replacing one LedgerIt made
before. The link takes one payment; at the next Stripe sync that payment
is recorded and applied to the invoice. Refused with unprocessable when
the books have no Stripe connection or its key may not make payment
links, and with conflict when nothing is owed.
Parameters
| Name | Type | Description |
|---|---|---|
invoice_idPath · Required | string | An id that starts with |
Response
200InvoiceOut
Errors
- 400
- The request was malformed or a parameter is invalid.
- 401
- No valid credential was sent.
- 403
- The credential or the member's role does not allow this.
- 404
- No such resource in this ledger.
- 409
- A conflicting request, e.g. one with the same Idempotency-Key still running.
- 422
- A well-formed request a business rule refused.
- 429
- Too many requests; retry after the Retry-After header.
- 500
- Something failed on our side; the request_id identifies it.
Example
curl -X POST "https://api.ledgerit.ai/v1/invoices/{invoice_id}/payment_link" \
-H "Authorization: Bearer $LEDGERIT_TOKEN" \
-H "Idempotency-Key: $(uuidgen)"Take an invoice's payment link away
DELETE/v1/invoices/{invoice_id}/payment_link· Idempotent
client.invoices.deletePaymentLink()
Take an invoice's payment link away. One LedgerIt made is turned off in Stripe, so it takes nothing more.
Parameters
| Name | Type | Description |
|---|---|---|
invoice_idPath · Required | string | An id that starts with |
Response
200InvoiceOut
Errors
- 400
- The request was malformed or a parameter is invalid.
- 401
- No valid credential was sent.
- 403
- The credential or the member's role does not allow this.
- 404
- No such resource in this ledger.
- 409
- A conflicting request, e.g. one with the same Idempotency-Key still running.
- 422
- A well-formed request a business rule refused.
- 429
- Too many requests; retry after the Retry-After header.
- 500
- Something failed on our side; the request_id identifies it.
Example
curl -X DELETE "https://api.ledgerit.ai/v1/invoices/{invoice_id}/payment_link" \
-H "Authorization: Bearer $LEDGERIT_TOKEN" \
-H "Idempotency-Key: $(uuidgen)"Turn an invoice's reminders on or off
PUT/v1/invoices/{invoice_id}/reminders· Idempotent
client.invoices.setReminders()
Turn the customer's reminders on or off, on a draft or an issued
invoice. While on, the customer is emailed three days before the due day,
then one, seven and fourteen days after, each once, while anything is
owed. Refused with conflict on a void invoice.
Parameters
| Name | Type | Description |
|---|---|---|
invoice_idPath · Required | string | An id that starts with |
Request body
Response
200InvoiceOut
Errors
- 400
- The request was malformed or a parameter is invalid.
- 401
- No valid credential was sent.
- 403
- The credential or the member's role does not allow this.
- 404
- No such resource in this ledger.
- 409
- A conflicting request, e.g. one with the same Idempotency-Key still running.
- 422
- A well-formed request a business rule refused.
- 429
- Too many requests; retry after the Retry-After header.
- 500
- Something failed on our side; the request_id identifies it.
Example
curl -X PUT "https://api.ledgerit.ai/v1/invoices/{invoice_id}/reminders" \
-H "Authorization: Bearer $LEDGERIT_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"enabled":false}'Void an issued invoice
POST/v1/invoices/{invoice_id}/void· Idempotent
client.invoices.void()
Take an issued invoice off the books by reversing its entry. Refused
with conflict while a payment is applied to it.
Parameters
| Name | Type | Description |
|---|---|---|
invoice_idPath · Required | string | An id that starts with |
Request body
Response
200InvoiceOut
Errors
- 400
- The request was malformed or a parameter is invalid.
- 401
- No valid credential was sent.
- 403
- The credential or the member's role does not allow this.
- 404
- No such resource in this ledger.
- 409
- A conflicting request, e.g. one with the same Idempotency-Key still running.
- 422
- A well-formed request a business rule refused.
- 429
- Too many requests; retry after the Retry-After header.
- 500
- Something failed on our side; the request_id identifies it.
Example
curl -X POST "https://api.ledgerit.ai/v1/invoices/{invoice_id}/void" \
-H "Authorization: Bearer $LEDGERIT_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{}'Objects
The objects these operations take and return.
InvoicePage
| Name | Type | Description |
|---|---|---|
dataRequired | array of InvoiceOut | |
has_moreRequired | boolean | |
next_cursorRequired | string or null |
InvoiceCreate
| Name | Type | Description |
|---|---|---|
due_date | string (date) or null | When it falls due; the customer's payment terms from the issue day (30 days without) when left out. |
issue_dateRequired | string (date) | |
linesRequired | array of InvoiceLineIn | |
memo | string or null | |
number | string or null | Unique in these books; the next INV-0001-style number when left out. |
party_idRequired | string | The customer: a counterparty of these books. |
payment_link | string or null | Where the customer can pay it, as you give it. To have LedgerIt make one in your Stripe account once it is issued, use |
send_reminders | boolean or null | Email the customer reminders a few days before it is due and after it falls overdue; off when left out. |
InvoiceOut
| Name | Type | Description |
|---|---|---|
amount_dueRequired | string | What the customer still owes on it today; 0 for a draft or a void invoice. |
created_atRequired | string (date-time) | |
currencyRequired | string | |
customer_nameRequired | string or null | The customer's name as the invoice was issued to them. |
due_dateRequired | string (date) | |
entry_idRequired | string or null | An id that starts with |
idRequired | string | An id that starts with |
issue_dateRequired | string (date) | |
issued_atRequired | string (date-time) or null | |
linesRequired | array of InvoiceLineOut | |
memoRequired | string or null | |
numberRequired | string | |
party_idRequired | string | An id that starts with |
payment_linkRequired | string or null | Where the customer can pay it. |
payment_link_madeRequired | boolean | The link was made by LedgerIt in the books' Stripe account, and a payment through it is recorded and applied to this invoice at the next Stripe sync. |
remindersRequired | array of InvoiceReminderOut | The reminders the customer was sent, the earliest first. |
row_versionRequired | integer | |
send_remindersRequired | boolean | Whether the customer is emailed reminders of what is owed. |
sourceRequired | string | Where it was written: |
statusRequired | string |
|
subtotalRequired | string | |
tax_totalRequired | string | |
totalRequired | string | |
void_entry_idRequired | string or null | An id that starts with |
voided_atRequired | string (date-time) or null |
InvoiceUpdate
| Name | Type | Description |
|---|---|---|
due_date | string (date) or null | |
issue_date | string (date) or null | |
lines | array of InvoiceLineIn or null | Replaces every line when given. |
memo | string or null | |
number | string or null | |
party_id | string or null | An id that starts with |
payment_link | string or null | |
send_reminders | boolean or null |
InvoiceReminders
| Name | Type | Description |
|---|---|---|
enabledRequired | boolean | Whether the customer is emailed reminders of what is owed. |
InvoiceVoid
| Name | Type | Description |
|---|---|---|
reason | string or null | Why it is voided; written on the reversal. |
InvoiceLineIn
| Name | Type | Description |
|---|---|---|
account_idRequired | string | The income (or deferred revenue) account it is earned in. |
descriptionRequired | string | What is billed, as the customer reads it. |
quantity | number | string | Default 1 |
service_end | string (date) or null | The last day of the service it bills, if any. |
service_start | string (date) or null | The first day of the service it bills, if any. |
tax_amount | number | string | Sales tax on the line; must be 0 until tax is supported. |
unit_priceRequired | number | string | Per unit; negative for a discount line. |
InvoiceLineOut
| Name | Type | Description |
|---|---|---|
account_idRequired | string | An id that starts with |
amountRequired | string | |
descriptionRequired | string | |
line_noRequired | integer | |
quantityRequired | string | |
service_endRequired | string (date) or null | |
service_startRequired | string (date) or null | |
tax_amountRequired | string | |
unit_priceRequired | string |
InvoiceReminderOut
| Name | Type | Description |
|---|---|---|
days_from_dueRequired | integer | The stage it was sent for: days from the due day, negative before it. |
sent_onRequired | string (date) | |
sent_toRequired | string | The email address it went to. |