Quotes API
Create, list, retrieve, update, and delete quotations.
Authentication
All quote endpoints require a valid PASETO token:
http
Authorization: Bearer <token>Endpoints
| Method | Path | Description |
|---|---|---|
POST | /api/quote/:orgId/create | Create a new quote |
GET | /api/quote/:orgId/list | List quotes (paginated) |
GET | /api/quote/:orgId/by-code/:code | Get quote by code |
GET | /api/quote/:orgId/:quoteId | Get quote by ID |
PUT | /api/quote/:orgId/:quoteId/update | Update a quote |
DELETE | /api/quote/:orgId/:quoteId/delete | Delete a quote |
Common Path Parameters
| Parameter | Type | Description |
|---|---|---|
orgId | string | Organisation ID |
quoteId | string | Quote document ID |
code | string | Human-readable quote code (e.g. QT-0015) |
POST /api/quote/:orgId/create
Create a new quotation.
Request Body
json
{
"guestId": "guest_abc123",
"guestName": "Jane Smith",
"guestEmail": "jane@example.com",
"guestPhone": "+919876543210",
"guestAddress": "42 MG Road, Bengaluru 560001",
"quoteDate": "2026-03-10",
"validUntil": "2026-03-20",
"checkIn": "2026-03-15",
"checkOut": "2026-03-18",
"items": [
{
"description": "Deluxe Room — 3 nights",
"quantity": 3,
"rate": 3500,
"amount": 10500,
"hsnCode": "9963"
},
{
"description": "Airport pickup",
"quantity": 1,
"rate": 1500,
"amount": 1500
}
],
"taxes": [
{ "name": "CGST", "rate": 6, "amount": 720 },
{ "name": "SGST", "rate": 6, "amount": 720 }
],
"summary": {
"subtotal": 12000,
"taxTotal": 1440,
"discountAmount": 500,
"grandTotal": 12940
},
"notes": "Prices valid for the mentioned dates only",
"terms": "50% advance required to confirm booking"
}| Field | Type | Required | Description |
|---|---|---|---|
guestId | string | No | Existing guest ID |
guestName | string | Yes | Guest / client name |
guestEmail | string | No | Guest email |
guestPhone | string | No | Guest phone |
guestAddress | string | No | Billing address |
quoteDate | string | Yes | Quote date (YYYY-MM-DD) |
validUntil | string | No | Expiry date for the quote |
checkIn | string | No | Proposed check-in date |
checkOut | string | No | Proposed check-out 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 |
taxes[].rate | number | Yes | Tax percentage |
taxes[].amount | number | Yes | Tax amount |
summary | object | Yes | Quote 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 |
notes | string | No | Notes on the quote |
terms | string | No | Terms and conditions |
Response — 201 Created
json
{
"success": true,
"message": "Quote created successfully",
"data": {
"quoteId": "qt_stu012",
"code": "QT-0015",
"guestName": "Jane Smith",
"grandTotal": 12940,
"status": "draft",
"quoteDate": "2026-03-10",
"validUntil": "2026-03-20",
"createdAt": "2026-03-10T09:00:00.000Z"
}
}Error — 400 Bad Request
json
{
"success": false,
"message": "Validation failed: items array is required"
}GET /api/quote/:orgId/list
List quotes 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 (draft, sent, accepted, expired, cancelled) |
from | string | — | Quote date from (YYYY-MM-DD) |
to | string | — | Quote date to (YYYY-MM-DD) |
search | string | — | Search by guest name, code, or phone |
Response — 200 OK
json
{
"success": true,
"data": [
{
"quoteId": "qt_stu012",
"code": "QT-0015",
"guestName": "Jane Smith",
"grandTotal": 12940,
"status": "draft",
"quoteDate": "2026-03-10",
"validUntil": "2026-03-20"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 25,
"totalPages": 2
}
}GET /api/quote/:orgId/by-code/:code
Retrieve a quote by its human-readable code.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
code | string | Quote code (e.g. QT-0015) |
Response — 200 OK
json
{
"success": true,
"data": {
"quoteId": "qt_stu012",
"code": "QT-0015",
"guestName": "Jane Smith",
"guestEmail": "jane@example.com",
"guestPhone": "+919876543210",
"guestAddress": "42 MG Road, Bengaluru 560001",
"quoteDate": "2026-03-10",
"validUntil": "2026-03-20",
"checkIn": "2026-03-15",
"checkOut": "2026-03-18",
"items": [
{
"description": "Deluxe Room — 3 nights",
"quantity": 3,
"rate": 3500,
"amount": 10500
},
{
"description": "Airport pickup",
"quantity": 1,
"rate": 1500,
"amount": 1500
}
],
"taxes": [
{ "name": "CGST", "rate": 6, "amount": 720 },
{ "name": "SGST", "rate": 6, "amount": 720 }
],
"summary": {
"subtotal": 12000,
"taxTotal": 1440,
"discountAmount": 500,
"grandTotal": 12940
},
"status": "draft",
"notes": "Prices valid for the mentioned dates only",
"terms": "50% advance required to confirm booking",
"createdAt": "2026-03-10T09:00:00.000Z"
}
}Error — 404 Not Found
json
{
"success": false,
"message": "Quote not found"
}GET /api/quote/:orgId/:quoteId
Retrieve full quote details by ID. Response format is identical to the by-code endpoint above.
Response — 200 OK
json
{
"success": true,
"data": {
"quoteId": "qt_stu012",
"code": "QT-0015",
"guestName": "Jane Smith",
"quoteDate": "2026-03-10",
"validUntil": "2026-03-20",
"items": [],
"taxes": [],
"summary": {
"subtotal": 12000,
"taxTotal": 1440,
"discountAmount": 500,
"grandTotal": 12940
},
"status": "draft",
"createdAt": "2026-03-10T09:00:00.000Z",
"updatedAt": "2026-03-10T09:00:00.000Z"
}
}PUT /api/quote/:orgId/:quoteId/update
Update an existing quote.
Request Body
json
{
"items": [
{
"description": "Suite Room — 3 nights",
"quantity": 3,
"rate": 6000,
"amount": 18000,
"hsnCode": "9963"
},
{
"description": "Airport pickup + drop",
"quantity": 2,
"rate": 1500,
"amount": 3000
}
],
"taxes": [
{ "name": "CGST", "rate": 6, "amount": 1260 },
{ "name": "SGST", "rate": 6, "amount": 1260 }
],
"summary": {
"subtotal": 21000,
"taxTotal": 2520,
"discountAmount": 1000,
"grandTotal": 22520
},
"validUntil": "2026-03-25",
"notes": "Upgraded to suite per guest request",
"status": "sent"
}| Field | Type | Required | Description |
|---|---|---|---|
items | array | No | Updated line items (replaces all) |
taxes | array | No | Updated taxes |
summary | object | No | Updated totals |
validUntil | string | No | Updated expiry date |
checkIn | string | No | Updated check-in date |
checkOut | string | No | Updated check-out date |
notes | string | No | Updated notes |
terms | string | No | Updated terms |
status | string | No | Status (draft, sent, accepted, expired, cancelled) |
Response — 200 OK
json
{
"success": true,
"message": "Quote updated successfully",
"data": {
"quoteId": "qt_stu012",
"code": "QT-0015",
"grandTotal": 22520,
"status": "sent",
"updatedAt": "2026-03-12T11:45:00.000Z"
}
}Error — 404 Not Found
json
{
"success": false,
"message": "Quote not found"
}DELETE /api/quote/:orgId/:quoteId/delete
Permanently delete a quote. Only quotes in draft status can be deleted.
Response — 200 OK
json
{
"success": true,
"message": "Quote deleted successfully"
}Error — 400 Bad Request
json
{
"success": false,
"message": "Only draft quotes can be deleted"
}Error — 404 Not Found
json
{
"success": false,
"message": "Quote not found"
}