Invoices API
Create, list, retrieve, and update invoices linked to bookings and guests.
Authentication
All invoice endpoints require a valid PASETO token:
http
Authorization: Bearer <token>Endpoints
| Method | Path | Description |
|---|---|---|
POST | /api/invoice/:orgId/create | Create a new invoice |
GET | /api/invoice/:orgId/list | List invoices (paginated) |
GET | /api/invoice/:orgId/by-code/:code | Get invoice by code |
GET | /api/invoice/:orgId/:invoiceId | Get invoice by ID |
PUT | /api/invoice/:orgId/:invoiceId/update | Update an invoice |
Common Path Parameters
| Parameter | Type | Description |
|---|---|---|
orgId | string | Organisation ID |
invoiceId | string | Invoice document ID |
code | string | Human-readable invoice code (e.g. INV-0078) |
POST /api/invoice/:orgId/create
Create a new invoice.
Request Body
json
{
"bookingId": "bk_xyz789",
"guestId": "guest_abc123",
"guestName": "Jane Smith",
"guestEmail": "jane@example.com",
"guestPhone": "+919876543210",
"guestAddress": "42 MG Road, Bengaluru 560001",
"guestGSTIN": "29ABCDE1234F1ZK",
"invoiceDate": "2026-03-18",
"dueDate": "2026-03-25",
"items": [
{
"description": "Deluxe Room — 3 nights",
"quantity": 3,
"rate": 3500,
"amount": 10500,
"hsnCode": "9963"
},
{
"description": "Restaurant charges",
"quantity": 1,
"rate": 2400,
"amount": 2400,
"hsnCode": "9963"
}
],
"taxes": [
{
"name": "CGST",
"rate": 6,
"amount": 774
},
{
"name": "SGST",
"rate": 6,
"amount": 774
}
],
"summary": {
"subtotal": 12900,
"taxTotal": 1548,
"discountAmount": 0,
"grandTotal": 14448,
"amountPaid": 3000,
"balanceDue": 11448
},
"notes": "Thank you for staying with us",
"terms": "Payment due within 7 days"
}| Field | Type | Required | Description |
|---|---|---|---|
bookingId | string | No | Associated booking ID |
guestId | string | No | Guest ID |
guestName | string | Yes | Guest / billing name |
guestEmail | string | No | Guest email |
guestPhone | string | No | Guest phone |
guestAddress | string | No | Billing address |
guestGSTIN | string | No | Guest's GSTIN (for B2B) |
invoiceDate | string | Yes | Invoice date (YYYY-MM-DD) |
dueDate | string | No | Payment due date |
items | array | Yes | Line items |
items[].description | string | Yes | Item description |
items[].quantity | number | Yes | Quantity |
items[].rate | number | Yes | Unit rate |
items[].amount | number | Yes | Line total |
items[].hsnCode | string | No | HSN/SAC code |
taxes | array | No | Applied taxes |
taxes[].name | string | Yes | Tax name (e.g. CGST) |
taxes[].rate | number | Yes | Tax percentage |
taxes[].amount | number | Yes | Tax amount |
summary | object | Yes | Invoice totals |
summary.subtotal | number | Yes | Sum of item amounts |
summary.taxTotal | number | Yes | Sum of taxes |
summary.discountAmount | number | No | Discount applied |
summary.grandTotal | number | Yes | Grand total |
summary.amountPaid | number | No | Amount already paid |
summary.balanceDue | number | Yes | Remaining balance |
notes | string | No | Notes on the invoice |
terms | string | No | Terms and conditions |
Response — 201 Created
json
{
"success": true,
"message": "Invoice created successfully",
"data": {
"invoiceId": "inv_pqr456",
"code": "INV-0078",
"guestName": "Jane Smith",
"grandTotal": 14448,
"balanceDue": 11448,
"status": "unpaid",
"invoiceDate": "2026-03-18",
"createdAt": "2026-03-18T12:00:00.000Z"
}
}Error — 400 Bad Request
json
{
"success": false,
"message": "Validation failed: items array is required"
}GET /api/invoice/:orgId/list
List invoices with pagination and optional filters.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | number | 1 | Page number |
limit | number | 20 | Items per page |
status | string | — | Filter by status (unpaid, partial, paid, cancelled) |
from | string | — | Invoice date from (YYYY-MM-DD) |
to | string | — | Invoice date to (YYYY-MM-DD) |
search | string | — | Search by guest name, code, or phone |
Response — 200 OK
json
{
"success": true,
"data": [
{
"invoiceId": "inv_pqr456",
"code": "INV-0078",
"guestName": "Jane Smith",
"grandTotal": 14448,
"balanceDue": 11448,
"status": "unpaid",
"invoiceDate": "2026-03-18"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 42,
"totalPages": 3
}
}GET /api/invoice/:orgId/by-code/:code
Retrieve an invoice by its human-readable code.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
code | string | Invoice code (e.g. INV-0078) |
Response — 200 OK
json
{
"success": true,
"data": {
"invoiceId": "inv_pqr456",
"code": "INV-0078",
"bookingId": "bk_xyz789",
"guestName": "Jane Smith",
"guestEmail": "jane@example.com",
"guestPhone": "+919876543210",
"guestAddress": "42 MG Road, Bengaluru 560001",
"invoiceDate": "2026-03-18",
"dueDate": "2026-03-25",
"items": [
{
"description": "Deluxe Room — 3 nights",
"quantity": 3,
"rate": 3500,
"amount": 10500
}
],
"taxes": [
{ "name": "CGST", "rate": 6, "amount": 774 },
{ "name": "SGST", "rate": 6, "amount": 774 }
],
"summary": {
"subtotal": 12900,
"taxTotal": 1548,
"discountAmount": 0,
"grandTotal": 14448,
"amountPaid": 3000,
"balanceDue": 11448
},
"status": "unpaid",
"createdAt": "2026-03-18T12:00:00.000Z"
}
}Error — 404 Not Found
json
{
"success": false,
"message": "Invoice not found"
}GET /api/invoice/:orgId/:invoiceId
Retrieve full invoice details by ID. Response format is identical to the by-code endpoint above.
Response — 200 OK
json
{
"success": true,
"data": {
"invoiceId": "inv_pqr456",
"code": "INV-0078",
"bookingId": "bk_xyz789",
"guestName": "Jane Smith",
"invoiceDate": "2026-03-18",
"items": [],
"taxes": [],
"summary": {
"subtotal": 12900,
"taxTotal": 1548,
"grandTotal": 14448,
"amountPaid": 3000,
"balanceDue": 11448
},
"status": "unpaid",
"createdAt": "2026-03-18T12:00:00.000Z",
"updatedAt": "2026-03-18T12:00:00.000Z"
}
}PUT /api/invoice/:orgId/:invoiceId/update
Update an existing invoice.
Request Body
json
{
"items": [
{
"description": "Deluxe Room — 5 nights",
"quantity": 5,
"rate": 3500,
"amount": 17500,
"hsnCode": "9963"
},
{
"description": "Restaurant charges",
"quantity": 1,
"rate": 3200,
"amount": 3200,
"hsnCode": "9963"
}
],
"taxes": [
{ "name": "CGST", "rate": 6, "amount": 1242 },
{ "name": "SGST", "rate": 6, "amount": 1242 }
],
"summary": {
"subtotal": 20700,
"taxTotal": 2484,
"discountAmount": 500,
"grandTotal": 22684,
"amountPaid": 3000,
"balanceDue": 19684
},
"dueDate": "2026-03-28",
"notes": "Updated for extended stay"
}| Field | Type | Required | Description |
|---|---|---|---|
items | array | No | Updated line items (replaces all) |
taxes | array | No | Updated taxes |
summary | object | No | Updated totals |
dueDate | string | No | Updated due date |
notes | string | No | Updated notes |
terms | string | No | Updated terms |
Response — 200 OK
json
{
"success": true,
"message": "Invoice updated successfully",
"data": {
"invoiceId": "inv_pqr456",
"code": "INV-0078",
"grandTotal": 22684,
"balanceDue": 19684,
"updatedAt": "2026-03-20T09:15:00.000Z"
}
}Error — 404 Not Found
json
{
"success": false,
"message": "Invoice not found"
}