Expenses API
Record and manage expenses for an organization — create, list, retrieve, and update.
Authentication
All endpoints require a valid Bearer token in the Authorization header.
Endpoints
| Method | Path | Description |
|---|---|---|
POST | /api/expense/:orgId/create | Create a new expense |
GET | /api/expense/:orgId/list | List all expenses |
GET | /api/expense/:orgId/by-code/:code | Get expense by code |
GET | /api/expense/:orgId/:expenseId | Get expense by ID |
PUT | /api/expense/:orgId/:expenseId/update | Update an expense |
Path Parameters
| Parameter | Type | Description |
|---|---|---|
orgId | string | Organization ID |
expenseId | string | Expense document ID |
code | string | Unique expense code (e.g. EXP-001) |
Create Expense
POST /api/expense/:orgId/createRequest Body
json
{
"expenseCode": "EXP-001",
"date": "2026-02-20",
"paid_through_account": "64f1b2c3d4e5f6a7b8c9d0a1",
"vendor": "64f1b2c3d4e5f6a7b8c9d0a2",
"reference": "INV-2026-0045",
"items": [
{
"accountId": "64f1b2c3d4e5f6a7b8c9d0a3",
"description": "Housekeeping supplies",
"quantity": 50,
"rate": 200,
"amount": 10000,
"taxes": [
{
"taxId": "64f1b2c3d4e5f6a7b8c9d0a4",
"name": "CGST",
"rate": 9,
"amount": 900
},
{
"taxId": "64f1b2c3d4e5f6a7b8c9d0a5",
"name": "SGST",
"rate": 9,
"amount": 900
}
]
},
{
"accountId": "64f1b2c3d4e5f6a7b8c9d0a6",
"description": "Laundry detergent",
"quantity": 20,
"rate": 150,
"amount": 3000,
"taxes": [
{
"taxId": "64f1b2c3d4e5f6a7b8c9d0a4",
"name": "CGST",
"rate": 9,
"amount": 270
},
{
"taxId": "64f1b2c3d4e5f6a7b8c9d0a5",
"name": "SGST",
"rate": 9,
"amount": 270
}
]
}
],
"notes": "Monthly housekeeping procurement"
}Success Response 201
json
{
"success": true,
"message": "Expense created successfully",
"data": {
"_id": "64f1b2c3d4e5f6a7b8c9d0b0",
"expenseCode": "EXP-001",
"date": "2026-02-20",
"paid_through_account": {
"_id": "64f1b2c3d4e5f6a7b8c9d0a1",
"name": "Petty Cash"
},
"vendor": {
"_id": "64f1b2c3d4e5f6a7b8c9d0a2",
"name": "CleanPro Supplies"
},
"reference": "INV-2026-0045",
"items": [
{
"accountId": "64f1b2c3d4e5f6a7b8c9d0a3",
"description": "Housekeeping supplies",
"quantity": 50,
"rate": 200,
"amount": 10000,
"taxes": [
{ "taxId": "64f1b2c3d4e5f6a7b8c9d0a4", "name": "CGST", "rate": 9, "amount": 900 },
{ "taxId": "64f1b2c3d4e5f6a7b8c9d0a5", "name": "SGST", "rate": 9, "amount": 900 }
]
},
{
"accountId": "64f1b2c3d4e5f6a7b8c9d0a6",
"description": "Laundry detergent",
"quantity": 20,
"rate": 150,
"amount": 3000,
"taxes": [
{ "taxId": "64f1b2c3d4e5f6a7b8c9d0a4", "name": "CGST", "rate": 9, "amount": 270 },
{ "taxId": "64f1b2c3d4e5f6a7b8c9d0a5", "name": "SGST", "rate": 9, "amount": 270 }
]
}
],
"subTotal": 13000,
"taxTotal": 2340,
"total": 15340,
"notes": "Monthly housekeeping procurement",
"orgId": "64f1b2c3d4e5f6a7b8c9d0e0",
"createdAt": "2026-02-20T10:00:00.000Z",
"updatedAt": "2026-02-20T10:00:00.000Z"
}
}Error Response 400
json
{
"success": false,
"message": "Validation error",
"errors": [
"items must contain at least one entry",
"paid_through_account is required"
]
}List Expenses
GET /api/expense/:orgId/listQuery Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | number | 1 | Page number |
limit | number | 10 | Results per page |
search | string | — | Search by expense code, vendor, or reference |
from | string | — | Start date filter (YYYY-MM-DD) |
to | string | — | End date filter (YYYY-MM-DD) |
vendorId | string | — | Filter by vendor ID |
Success Response 200
json
{
"success": true,
"data": [
{
"_id": "64f1b2c3d4e5f6a7b8c9d0b0",
"expenseCode": "EXP-001",
"date": "2026-02-20",
"vendor": {
"_id": "64f1b2c3d4e5f6a7b8c9d0a2",
"name": "CleanPro Supplies"
},
"subTotal": 13000,
"taxTotal": 2340,
"total": 15340,
"reference": "INV-2026-0045",
"createdAt": "2026-02-20T10:00:00.000Z"
}
],
"pagination": {
"total": 85,
"page": 1,
"limit": 10,
"totalPages": 9
}
}Get Expense by Code
GET /api/expense/:orgId/by-code/:codeSuccess Response 200
json
{
"success": true,
"data": {
"_id": "64f1b2c3d4e5f6a7b8c9d0b0",
"expenseCode": "EXP-001",
"date": "2026-02-20",
"paid_through_account": {
"_id": "64f1b2c3d4e5f6a7b8c9d0a1",
"name": "Petty Cash"
},
"vendor": {
"_id": "64f1b2c3d4e5f6a7b8c9d0a2",
"name": "CleanPro Supplies"
},
"reference": "INV-2026-0045",
"items": [
{
"accountId": "64f1b2c3d4e5f6a7b8c9d0a3",
"description": "Housekeeping supplies",
"quantity": 50,
"rate": 200,
"amount": 10000,
"taxes": [
{ "taxId": "64f1b2c3d4e5f6a7b8c9d0a4", "name": "CGST", "rate": 9, "amount": 900 },
{ "taxId": "64f1b2c3d4e5f6a7b8c9d0a5", "name": "SGST", "rate": 9, "amount": 900 }
]
},
{
"accountId": "64f1b2c3d4e5f6a7b8c9d0a6",
"description": "Laundry detergent",
"quantity": 20,
"rate": 150,
"amount": 3000,
"taxes": [
{ "taxId": "64f1b2c3d4e5f6a7b8c9d0a4", "name": "CGST", "rate": 9, "amount": 270 },
{ "taxId": "64f1b2c3d4e5f6a7b8c9d0a5", "name": "SGST", "rate": 9, "amount": 270 }
]
}
],
"subTotal": 13000,
"taxTotal": 2340,
"total": 15340,
"notes": "Monthly housekeeping procurement",
"createdAt": "2026-02-20T10:00:00.000Z",
"updatedAt": "2026-02-20T10:00:00.000Z"
}
}Error Response 404
json
{
"success": false,
"message": "Expense not found"
}Get Expense by ID
GET /api/expense/:orgId/:expenseIdSuccess Response 200
Same structure as Get Expense by Code.
Error Response 404
json
{
"success": false,
"message": "Expense not found"
}Update Expense
PUT /api/expense/:orgId/:expenseId/updateRequest Body
json
{
"items": [
{
"accountId": "64f1b2c3d4e5f6a7b8c9d0a3",
"description": "Housekeeping supplies (revised)",
"quantity": 60,
"rate": 200,
"amount": 12000,
"taxes": [
{
"taxId": "64f1b2c3d4e5f6a7b8c9d0a4",
"name": "CGST",
"rate": 9,
"amount": 1080
},
{
"taxId": "64f1b2c3d4e5f6a7b8c9d0a5",
"name": "SGST",
"rate": 9,
"amount": 1080
}
]
}
],
"notes": "Revised quantity for housekeeping supplies"
}Success Response 200
json
{
"success": true,
"message": "Expense updated successfully",
"data": {
"_id": "64f1b2c3d4e5f6a7b8c9d0b0",
"expenseCode": "EXP-001",
"subTotal": 12000,
"taxTotal": 2160,
"total": 14160,
"notes": "Revised quantity for housekeeping supplies",
"updatedAt": "2026-02-21T09:00:00.000Z"
}
}Error Response 404
json
{
"success": false,
"message": "Expense not found"
}