A REST API for tracking expenses, built with Node.js, Express.js, MongoDB, and JWT authentication.
- User registration and login with JWT authentication.
- CRUD operations for expenses with custom categories and tags.
- Filter expenses by date (week, month, three months, custom range) and category.
- Pagination and sorting for expense listing.
- Spending analytics by category.
- Custom category management.
- Bulk expense deletion.
- Email notifications for new users.
- Rate limiting on login.
- Detailed logging for requests and errors.
- Node.js >= 18
- MongoDB (local or MongoDB Atlas)
- Email service (e.g., Gmail, SendGrid) for notifications
- Clone the repository:
git clone <your-repo-url> cd expense-tracker-api - Install dependencies:
npm install - Create
.envfile:PORT=5000 MONGO_URI=mongodb+srv://<user>:<password>@cluster0.xxxxx.mongodb.net/expense-tracker?retryWrites=true&w=majority JWT_SECRET=generate_a_very_long_random_string_32_chars_minimum EMAIL_HOST=smtp.gmail.com EMAIL_PORT=587 EMAIL_USER=your-email@gmail.com EMAIL_PASS=your-email-password - Start the server:
npm run dev
- For development (with auto-restart):
npm run dev - For production:
npm start
-
POST /api/auth/register
Content-Type: application/json { "name": "John Doe", "email": "john@example.com", "password": "Password123" } Response (200): { "token": "jwt_token" } -
POST /api/auth/login
Content-Type: application/json { "email": "john@example.com", "password": "Password123" } Response (200): { "token": "jwt_token" }
-
GET /api/expenses
Authorization: Bearer <jwt_token> Query: ?filter=month&category=Groceries&page=1&limit=10&sortBy=date&sortOrder=desc Response (200): { "expenses": [...], "total": 50, "page": 1, "limit": 10 } -
GET /api/expenses/analytics
Authorization: Bearer <jwt_token> Query: ?startDate=2025-01-01&endDate=2025-03-31 Response (200): [{ "_id": "Groceries", "totalAmount": 500.75, "count": 10 }, ...] -
POST /api/expenses
Authorization: Bearer <jwt_token> Content-Type: application/json { "category": "Groceries", "amount": 55.75, "description": "Weekly shopping", "date": "2025-07-19", "tags": ["food", "weekly"] } Response (200): Created expense object -
PUT /api/expenses/:id
Authorization: Bearer <jwt_token> Content-Type: application/json { "amount": 60.00, "description": "Weekly shopping + snacks" } Response (200): Updated expense object -
DELETE /api/expenses/:id
Authorization: Bearer <jwt_token> Response (200): { "msg": "Expense removed" } -
DELETE /api/expenses
Authorization: Bearer <jwt_token> Content-Type: application/json { "expenseIds": ["id1", "id2"] } Response (200): { "msg": "2 expenses removed" }
-
POST /api/categories
Authorization: Bearer <jwt_token> Content-Type: application/json { "name": "Travel" } Response (200): Created category object -
GET /api/categories
Authorization: Bearer <jwt_token> Response (200): Array of category objects -
DELETE /api/categories/:name
Authorization: Bearer <jwt_token> Response (200): { "msg": "Category removed" }
-
Register a User
curl -X POST -H "Content-Type: application/json" -d '{"name":"John Doe","email":"john@example.com","password":"Password123"}' http://localhost:5000/api/auth/registerCopy the
jwt_tokenfrom the response. -
Login
curl -X POST -H "Content-Type: application/json" -d '{"email":"john@example.com","password":"Password123"}' http://localhost:5000/api/auth/loginCopy the
jwt_tokenfrom the response. -
Add a Category
curl -X POST -H "Authorization: Bearer <jwt_token>" -H "Content-Type: application/json" -d '{"name":"Travel"}' http://localhost:5000/api/categories -
List Categories
curl -X GET -H "Authorization: Bearer <jwt_token>" http://localhost:5000/api/categories -
Add an Expense
curl -X POST -H "Authorization: Bearer <jwt_token>" -H "Content-Type: application/json" -d '{"category":"Travel","amount":55.75,"description":"Flight ticket","date":"2025-07-19","tags":["vacation"]}' http://localhost:5000/api/expenses -
List Expenses
curl -X GET -H "Authorization: Bearer <jwt_token>" http://localhost:5000/api/expenses?filter=month&category=Travel&page=1&limit=10 -
Get Analytics
curl -X GET -H "Authorization: Bearer <jwt_token>" http://localhost:5000/api/expenses/analytics?startDate=2025-01-01&endDate=2025-07-19 -
Update an Expense
curl -X PUT -H "Authorization: Bearer <jwt_token>" -H "Content-Type: application/json" -d '{"amount":60.00,"description":"Flight ticket + fees"}' http://localhost:5000/api/expenses/<expense_id>Replace
<expense_id>with a valid expense ID. -
Delete an Expense
curl -X DELETE -H "Authorization: Bearer <jwt_token>" http://localhost:5000/api/expenses/<expense_id>Replace
<expense_id>with a valid expense ID. -
Bulk Delete Expenses
curl -X DELETE -H "Authorization: Bearer <jwt_token>" -H "Content-Type: application/json" -d '{"expenseIds":["<expense_id1>","<expense_id2>"]}' http://localhost:5000/api/expensesReplace
<expense_id1>and<expense_id2>with valid expense IDs. -
Delete a Category
curl -X DELETE -H "Authorization: Bearer <jwt_token>" http://localhost:5000/api/categories/Travel