Invoice
Core invoice CRUD and lifecycle actions (send, mark paid/sent, PDF, duplicate)
Display a listing of invoices
GET /api/v1/invoices
Requires authentication (Bearer token) and the X-Organization-Id header.
Parameters
| Name |
In |
Type |
Required |
Description |
status |
query |
string |
no |
|
date_from |
query |
string |
no |
|
date_to |
query |
string |
no |
|
per_page |
query |
string |
no |
|
Responses
| Status |
Description |
| 200 |
For non-paginated data, return as before |
Example request
curl -X GET "https://kworia.com/api/v1/invoices" \
-H "Authorization: Bearer {{access_token}}" \
-H "X-Organization-Id: {{organization_id}}" \
-H "Accept: application/json"
Store a newly created invoice
POST /api/v1/invoices
Requires authentication (Bearer token) and the X-Organization-Id header.
Per-line tax handling (Epic #617): each item may set tax_exempt: true (no tax on that line) or supply tax_rate_ids (explicit organization TaxRate ids). When a line provides neither, the organization's default tax rates are auto-applied. Item responses return the resolved unified tax-lines in tax_rates.
Request body
| Field |
Type |
Required |
Description |
customer_id |
integer |
yes |
|
issue_date |
string |
yes |
|
due_date |
string |
yes |
|
currency |
string |
yes |
|
notes |
string |
no |
|
terms |
string |
no |
|
items |
array |
yes |
|
Responses
| Status |
Description |
| 201 |
For non-paginated data, return as before |
| 422 |
|
| 403 |
|
Example request
curl -X POST "https://kworia.com/api/v1/invoices" \
-H "Authorization: Bearer {{access_token}}" \
-H "X-Organization-Id: {{organization_id}}" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"customer_id": 1,
"issue_date": "string",
"due_date": "string",
"currency": "string",
"notes": "string",
"terms": "string",
"items": []
}'
Display the specified invoice
GET /api/v1/invoices/{id}
Requires authentication (Bearer token) and the X-Organization-Id header.
Parameters
| Name |
In |
Type |
Required |
Description |
id |
path |
integer |
yes |
|
Responses
| Status |
Description |
| 200 |
For non-paginated data, return as before |
Example request
curl -X GET "https://kworia.com/api/v1/invoices/{id}" \
-H "Authorization: Bearer {{access_token}}" \
-H "X-Organization-Id: {{organization_id}}" \
-H "Accept: application/json"
Update the specified invoice
PUT /api/v1/invoices/{id}
Requires authentication (Bearer token) and the X-Organization-Id header.
Parameters
| Name |
In |
Type |
Required |
Description |
id |
path |
integer |
yes |
|
Request body
| Field |
Type |
Required |
Description |
customer_id |
integer |
no |
|
issue_date |
string |
no |
|
due_date |
string |
no |
|
currency |
string |
no |
|
notes |
string |
no |
|
terms |
string |
no |
|
items |
array |
no |
|
Responses
| Status |
Description |
| 200 |
For non-paginated data, return as before |
| 422 |
|
| 403 |
|
Example request
curl -X PUT "https://kworia.com/api/v1/invoices/{id}" \
-H "Authorization: Bearer {{access_token}}" \
-H "X-Organization-Id: {{organization_id}}" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"customer_id": 1,
"issue_date": "string",
"due_date": "string",
"currency": "string",
"notes": "string",
"terms": "string",
"items": []
}'
Remove the specified invoice
DELETE /api/v1/invoices/{id}
Requires authentication (Bearer token) and the X-Organization-Id header.
Parameters
| Name |
In |
Type |
Required |
Description |
id |
path |
integer |
yes |
|
Responses
| Status |
Description |
| 200 |
For non-paginated data, return as before |
| 422 |
#764 part 2: retention/lock refusal is a domain rule, not a server error. Surface 422 with the message instead of a 500 + stack trace. |
Example request
curl -X DELETE "https://kworia.com/api/v1/invoices/{id}" \
-H "Authorization: Bearer {{access_token}}" \
-H "X-Organization-Id: {{organization_id}}" \
-H "Accept: application/json"
Duplicate an invoice
POST /api/v1/invoices/{id}/duplicate
Requires authentication (Bearer token) and the X-Organization-Id header.
Parameters
| Name |
In |
Type |
Required |
Description |
id |
path |
integer |
yes |
|
Responses
| Status |
Description |
| 201 |
For non-paginated data, return as before |
Example request
curl -X POST "https://kworia.com/api/v1/invoices/{id}/duplicate" \
-H "Authorization: Bearer {{access_token}}" \
-H "X-Organization-Id: {{organization_id}}" \
-H "Accept: application/json"
Mark invoice as paid
POST /api/v1/invoices/{id}/mark-paid
Requires authentication (Bearer token) and the X-Organization-Id header.
Parameters
| Name |
In |
Type |
Required |
Description |
id |
path |
integer |
yes |
|
Request body
| Field |
Type |
Required |
Description |
payment_date |
string |
no |
|
amount |
number |
no |
|
amount_paid |
number |
no |
|
payment_method |
string |
no |
|
reference |
string |
no |
|
payment_reference |
string |
no |
|
notes |
string |
no |
|
Responses
| Status |
Description |
| 200 |
For non-paginated data, return as before |
| 422 |
|
Example request
curl -X POST "https://kworia.com/api/v1/invoices/{id}/mark-paid" \
-H "Authorization: Bearer {{access_token}}" \
-H "X-Organization-Id: {{organization_id}}" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"payment_date": "string",
"amount": 1,
"amount_paid": 1,
"payment_method": "string",
"reference": "string",
"payment_reference": "string",
"notes": "string"
}'
Mark invoice as sent
POST /api/v1/invoices/{id}/mark-sent
Requires authentication (Bearer token) and the X-Organization-Id header.
Parameters
| Name |
In |
Type |
Required |
Description |
id |
path |
integer |
yes |
|
Request body
| Field |
Type |
Required |
Description |
sent_at |
string |
no |
|
sent_method |
string |
no |
|
Responses
| Status |
Description |
| 200 |
For non-paginated data, return as before |
| 422 |
|
Example request
curl -X POST "https://kworia.com/api/v1/invoices/{id}/mark-sent" \
-H "Authorization: Bearer {{access_token}}" \
-H "X-Organization-Id: {{organization_id}}" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"sent_at": "string",
"sent_method": "string"
}'
Download invoice PDF
GET /api/v1/invoices/{id}/pdf
Requires authentication (Bearer token) and the X-Organization-Id header.
Uses method injection for the PDF service (only this method needs it).
Parameters
| Name |
In |
Type |
Required |
Description |
id |
path |
integer |
yes |
|
Responses
Example request
curl -X GET "https://kworia.com/api/v1/invoices/{id}/pdf" \
-H "Authorization: Bearer {{access_token}}" \
-H "X-Organization-Id: {{organization_id}}" \
-H "Accept: application/json"
Send invoice via email
POST /api/v1/invoices/{id}/send
Requires authentication (Bearer token) and the X-Organization-Id header.
Parameters
| Name |
In |
Type |
Required |
Description |
id |
path |
integer |
yes |
|
Request body
| Field |
Type |
Required |
Description |
recipients |
string |
no |
|
message |
string |
no |
|
attach_pdf |
string |
no |
|
Responses
| Status |
Description |
| 200 |
For non-paginated data, return as before |
Example request
curl -X POST "https://kworia.com/api/v1/invoices/{id}/send" \
-H "Authorization: Bearer {{access_token}}" \
-H "X-Organization-Id: {{organization_id}}" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"recipients": "string",
"message": "string",
"attach_pdf": "string"
}'