Invoices
Create and manage GST-compliant tax invoices. Invoices are the core transactional record in Katixo — each invoice automatically updates receivables, inventory, and GST filing data. All endpoints require JWT Bearer token authentication.
Endpoints
/api/v1/invoices/api/v1/invoices/{id}/api/v1/invoices/api/v1/invoices/{id}/send/api/v1/invoices/{id}/cancel/api/v1/invoices/{id}/pdf/api/v1/invoices/{id}/payments/api/v1/invoices/{id}/payments/api/v1/invoices/{id}/payments/{paymentId}/api/v1/invoices/bulk-send/api/v1/invoices/bulk-cancelAuthorization header. All IDs are UUIDs.The InvoiceResponse object
{
"success": true,
"message": "Invoice retrieved successfully",
"data": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"invoiceNumber": "KTX/2026-27/0042",
"contactId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"customerName": "Sharma Kirana Store",
"invoiceDate": "2026-06-11",
"dueDate": "2026-07-11",
"status": "SENT",
"subtotal": 1450.00,
"taxAmount": 72.50,
"totalAmount": 1522.50,
"amountPaid": 0.00,
"balanceDue": 1522.50,
"placeOfSupply": "27",
"notes": "Payment due within 30 days",
"lines": [
{
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"lineNumber": 1,
"description": "Toor Dal 1kg",
"hsnCode": "07139090",
"itemId": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"quantity": 10,
"unitPrice": 145.00,
"discountPercent": 0,
"discountAmount": 0.00,
"taxableAmount": 1450.00,
"gstRate": 5.00,
"taxAmount": 72.50,
"lineTotal": 1522.50
}
],
"createdAt": "2026-06-11T05:00:00Z"
},
"errors": null
}Invoice statuses
| Status | Description |
|---|---|
DRAFT | Invoice created but not yet sent to the customer. |
SENT | Invoice has been sent to the customer and is awaiting payment. |
PAID | Full payment has been received. Balance due is zero. |
OVERDUE | Invoice is past its due date with balance still outstanding. |
CANCELLED | Invoice has been cancelled. Remains in system for audit purposes. |
List invoices
/api/v1/invoicesReturns a paginated list of invoices. The response is wrapped in ApiResponse<PagedResponse<InvoiceResponse>>.
Roles: OWNER, ADMIN, ACCOUNTANT, OPERATOR, VIEWER
Query parameters
| Parameter | Type | Description |
|---|---|---|
status | String | Filter by status: DRAFT, SENT, PAID, CANCELLED, OVERDUE. |
contactId | UUID | Filter by contact (customer). |
dateFrom | LocalDate | Invoice date on or after this date (YYYY-MM-DD). |
dateTo | LocalDate | Invoice date on or before this date. |
search | String | Free-text search across invoice number and customer name. |
page | int | Page number (zero-based, default: 0). |
size | int | Results per page (default: 20). |
sort | String | Sort field and direction, e.g. invoiceDate,desc. |
curl https://api.katixo.com/api/v1/invoices?status=SENT&dateFrom=2026-04-01&page=0&size=10 \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
# Response
{
"success": true,
"message": "Invoices retrieved successfully",
"data": {
"content": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"invoiceNumber": "KTX/2026-27/0042",
"contactId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"customerName": "Sharma Kirana Store",
"invoiceDate": "2026-06-11",
"dueDate": "2026-07-11",
"status": "SENT",
"subtotal": 1450.00,
"taxAmount": 72.50,
"totalAmount": 1522.50,
"amountPaid": 0.00,
"balanceDue": 1522.50,
"placeOfSupply": "27",
"notes": null,
"lines": [...],
"createdAt": "2026-06-11T05:00:00Z"
}
],
"page": 0,
"size": 10,
"totalElements": 42,
"totalPages": 5,
"last": false
},
"errors": null
}Get an invoice
/api/v1/invoices/{id}Retrieves a single invoice by its UUID. Returns ApiResponse<InvoiceResponse>.
curl https://api.katixo.com/api/v1/invoices/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."Create an invoice
/api/v1/invoicesCreates a new invoice in DRAFT status. Returns 201 Created on success.
Roles: OWNER, ADMIN, ACCOUNTANT, OPERATOR
CreateInvoiceRequest body
| Field | Type | Required | Description |
|---|---|---|---|
contactId | UUID | Yes | ID of the customer contact. |
invoiceDate | LocalDate | Yes | Date of the invoice (YYYY-MM-DD). |
dueDate | LocalDate | No | Payment due date. Defaults based on contact payment terms. |
placeOfSupply | String | No | State code (e.g. "27" for Maharashtra). Determines CGST+SGST vs IGST. |
notes | String | No | Free-text notes printed on the invoice. |
termsAndConditions | String | No | Terms and conditions text printed on the invoice. |
lines | InvoiceLineRequest[] | Yes | At least one line item is required. See line item fields below. |
InvoiceLineRequest fields
| Field | Type | Required | Description |
|---|---|---|---|
itemId | UUID | No | Reference to an item in the item master. Optional for ad-hoc line items. |
description | String | Yes | Description of the item or service. |
hsnCode | String | No | HSN/SAC code for GST classification. |
quantity | BigDecimal | Yes | Quantity of items. |
unitPrice | BigDecimal | Yes | Price per unit (before tax). |
discountPercent | BigDecimal | No | Discount percentage on this line (e.g. 5.00 for 5%). |
gstRate | BigDecimal | No | GST rate percentage (e.g. 5.00, 12.00, 18.00). Auto-resolved from item master if omitted. |
taxGroupId | UUID | No | Tax group to apply. Overrides gstRate if provided. |
Example: create an invoice for a kirana store
curl -X POST https://api.katixo.com/api/v1/invoices \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"contactId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"invoiceDate": "2026-06-11",
"dueDate": "2026-07-11",
"placeOfSupply": "27",
"notes": "Delivery to Sharma Kirana Store, Pune",
"termsAndConditions": "Payment due within 30 days. Late fee of 1.5% per month.",
"lines": [
{
"itemId": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"description": "Toor Dal 1kg",
"hsnCode": "07139090",
"quantity": 10,
"unitPrice": 145.00,
"gstRate": 5.00
},
{
"itemId": "d4e5f6a7-b8c9-0123-def0-234567890123",
"description": "Basmati Rice 5kg",
"hsnCode": "10063010",
"quantity": 5,
"unitPrice": 420.00,
"discountPercent": 2.00,
"gstRate": 5.00
},
{
"description": "Ghee 1L (Amul)",
"hsnCode": "04059090",
"quantity": 3,
"unitPrice": 560.00,
"gstRate": 12.00
}
]
}'
# Response (201 Created)
{
"success": true,
"message": "Invoice created successfully",
"data": {
"id": "e5f6a7b8-c9d0-1234-ef01-345678901234",
"invoiceNumber": "KTX/2026-27/0043",
"contactId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"customerName": "Sharma Kirana Store",
"invoiceDate": "2026-06-11",
"dueDate": "2026-07-11",
"status": "DRAFT",
"subtotal": 4558.00,
"taxAmount": 375.70,
"totalAmount": 4933.70,
"amountPaid": 0.00,
"balanceDue": 4933.70,
"placeOfSupply": "27",
"notes": "Delivery to Sharma Kirana Store, Pune",
"lines": [
{
"id": "11111111-1111-1111-1111-111111111111",
"lineNumber": 1,
"description": "Toor Dal 1kg",
"hsnCode": "07139090",
"itemId": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"quantity": 10,
"unitPrice": 145.00,
"discountPercent": 0,
"discountAmount": 0.00,
"taxableAmount": 1450.00,
"gstRate": 5.00,
"taxAmount": 72.50,
"lineTotal": 1522.50
},
{
"id": "22222222-2222-2222-2222-222222222222",
"lineNumber": 2,
"description": "Basmati Rice 5kg",
"hsnCode": "10063010",
"itemId": "d4e5f6a7-b8c9-0123-def0-234567890123",
"quantity": 5,
"unitPrice": 420.00,
"discountPercent": 2.00,
"discountAmount": 42.00,
"taxableAmount": 2058.00,
"gstRate": 5.00,
"taxAmount": 102.90,
"lineTotal": 2160.90
},
{
"id": "33333333-3333-3333-3333-333333333333",
"lineNumber": 3,
"description": "Ghee 1L (Amul)",
"hsnCode": "04059090",
"itemId": null,
"quantity": 3,
"unitPrice": 560.00,
"discountPercent": 0,
"discountAmount": 0.00,
"taxableAmount": 1680.00,
"gstRate": 12.00,
"taxAmount": 201.60,
"lineTotal": 1881.60
}
],
"createdAt": "2026-06-11T05:30:00Z"
},
"errors": null
}Send an invoice
/api/v1/invoices/{id}/sendTransitions the invoice from DRAFT to SENT and delivers it to the customer via the configured channel (email, WhatsApp, etc).
Roles: OWNER, ADMIN, ACCOUNTANT, OPERATOR
curl -X POST https://api.katixo.com/api/v1/invoices/e5f6a7b8-c9d0-1234-ef01-345678901234/send \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
# Response
{
"success": true,
"message": "Invoice sent successfully",
"data": null,
"errors": null
}Cancel an invoice
/api/v1/invoices/{id}/cancelCancels an invoice. This reverses inventory deductions and outstanding receivable entries. Cancelled invoices remain in the system for audit purposes but are excluded from GST filing data. A cancelled invoice cannot be un-cancelled — create a new invoice instead.
Roles: OWNER, ADMIN, ACCOUNTANT
curl -X POST https://api.katixo.com/api/v1/invoices/e5f6a7b8-c9d0-1234-ef01-345678901234/cancel \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
# Response
{
"success": true,
"message": "Invoice cancelled successfully",
"data": null,
"errors": null
}Download PDF
/api/v1/invoices/{id}/pdfReturns the invoice as a PDF file. The response has Content-Type: application/pdf and the body is the raw PDF bytes. The PDF uses your organization's configured invoice template, logo, and bank details.
curl https://api.katixo.com/api/v1/invoices/e5f6a7b8-c9d0-1234-ef01-345678901234/pdf \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-o invoice_KTX_2026-27_0043.pdfPayments
Record, list, and delete payments against an invoice. When the total payments equal the invoice total, the invoice status automatically transitions to PAID.
Record a payment
/api/v1/invoices/{id}/paymentsInvoicePaymentRequest body
| Field | Type | Required | Description |
|---|---|---|---|
amount | BigDecimal | Yes | Amount received. |
paymentDate | LocalDate | Yes | Date of payment (YYYY-MM-DD). |
paymentMode | String | Yes | Payment method (e.g. UPI, NEFT, CASH, CHEQUE, CARD). |
reference | String | No | Transaction reference (UPI ref, cheque number, NEFT UTR, etc). |
paidThroughAccountId | UUID | No | Bank/cash account the payment was deposited into. |
curl -X POST https://api.katixo.com/api/v1/invoices/e5f6a7b8-c9d0-1234-ef01-345678901234/payments \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"amount": 2000.00,
"paymentDate": "2026-06-15",
"paymentMode": "UPI",
"reference": "426198374512",
"paidThroughAccountId": "a0b1c2d3-e4f5-6789-0abc-def012345678"
}'
# Response
{
"success": true,
"message": "Payment recorded successfully",
"data": {
"id": "f6a7b8c9-d0e1-2345-f012-456789012345",
"invoiceId": "e5f6a7b8-c9d0-1234-ef01-345678901234",
"amount": 2000.00,
"paymentDate": "2026-06-15",
"paymentMode": "UPI",
"reference": "426198374512"
},
"errors": null
}List payments
/api/v1/invoices/{id}/paymentsReturns all payments recorded against the specified invoice.
curl https://api.katixo.com/api/v1/invoices/e5f6a7b8-c9d0-1234-ef01-345678901234/payments \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
# Response
{
"success": true,
"message": "Payments retrieved successfully",
"data": [
{
"id": "f6a7b8c9-d0e1-2345-f012-456789012345",
"invoiceId": "e5f6a7b8-c9d0-1234-ef01-345678901234",
"amount": 2000.00,
"paymentDate": "2026-06-15",
"paymentMode": "UPI",
"reference": "426198374512"
}
],
"errors": null
}Delete a payment
/api/v1/invoices/{id}/payments/{paymentId}Removes a payment record from the invoice. The invoice balance due is updated accordingly, and the status may revert from PAID back to SENT if the balance becomes non-zero.
curl -X DELETE https://api.katixo.com/api/v1/invoices/e5f6a7b8-c9d0-1234-ef01-345678901234/payments/f6a7b8c9-d0e1-2345-f012-456789012345 \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
# Response
{
"success": true,
"message": "Payment deleted successfully",
"data": null,
"errors": null
}Bulk operations
Bulk send
/api/v1/invoices/bulk-sendSend multiple draft invoices at once. The request body is a JSON array of invoice UUIDs.
curl -X POST https://api.katixo.com/api/v1/invoices/bulk-send \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '[
"a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"e5f6a7b8-c9d0-1234-ef01-345678901234",
"b2c3d4e5-f6a7-8901-bcde-f12345678901"
]'
# Response
{
"success": true,
"message": "3 invoices sent successfully",
"data": null,
"errors": null
}Bulk cancel
/api/v1/invoices/bulk-cancelCancel multiple invoices at once. The request body is a JSON array of invoice UUIDs.
Roles: OWNER, ADMIN, ACCOUNTANT
curl -X POST https://api.katixo.com/api/v1/invoices/bulk-cancel \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '[
"a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"b2c3d4e5-f6a7-8901-bcde-f12345678901"
]'
# Response
{
"success": true,
"message": "2 invoices cancelled successfully",
"data": null,
"errors": null
}LineResponse object
Each invoice contains an array of line items. The server computes discount amounts, taxable amounts, tax, and line totals automatically from the inputs you provide.
| Field | Type | Description |
|---|---|---|
id | UUID | Unique identifier for this line item. |
lineNumber | int | Position of the line item (1-based). |
description | String | Description of the item or service. |
hsnCode | String | HSN/SAC code for GST classification. |
itemId | UUID | Reference to item master (null for ad-hoc items). |
quantity | BigDecimal | Quantity of items. |
unitPrice | BigDecimal | Price per unit. |
discountPercent | BigDecimal | Discount percentage applied. |
discountAmount | BigDecimal | Computed discount amount (quantity x unitPrice x discountPercent / 100). |
taxableAmount | BigDecimal | Amount after discount, before tax. |
gstRate | BigDecimal | GST rate applied (e.g. 5.00, 12.00, 18.00). |
taxAmount | BigDecimal | Computed tax amount (taxableAmount x gstRate / 100). |
lineTotal | BigDecimal | Total for this line (taxableAmount + taxAmount). |
Error handling
All error responses follow the standard ApiResponse wrapper with success: false and details in the errors array.
# 400 Bad Request — validation error
{
"success": false,
"message": "Validation failed",
"data": null,
"errors": [
"contactId: must not be null",
"lines: must not be empty"
]
}
# 404 Not Found
{
"success": false,
"message": "Invoice not found",
"data": null,
"errors": ["No invoice found with id: e5f6a7b8-c9d0-1234-ef01-345678901234"]
}
# 403 Forbidden — insufficient role
{
"success": false,
"message": "Access denied",
"data": null,
"errors": ["You do not have permission to cancel invoices"]
}