REST API Documentation
Finance Backend
Role-based access control API for financial data management and dashboard analytics. Built with Express.js, MongoDB, and JWT authentication.
Base URL & Auth
Base URL
http://localhost:3000
All protected routes require the header:
Obtain a token via POST /auth/login. Tokens expire after 7 days. Inactive users cannot authenticate — their tokens are rejected on every request.
Authorization: Bearer <token>Obtain a token via POST /auth/login. Tokens expire after 7 days. Inactive users cannot authenticate — their tokens are rejected on every request.
Rate limit: 100 requests per 15 minutes per IP address.
Returns
Returns
429 Too Many Requests when exceeded.
Roles
viewer
- Read financial records
- Dashboard summary
- Category breakdown
analyst
- Everything viewer can
- Access trends endpoint
admin
- Full record management
- Create / update / delete
- Manage users & roles
Auth
POST
/auth/register
Register a new user
▼
Request Body
// application/json { "name": "Alice", "email": "alice@example.com", "password": "secret123", // required, min 6 chars "role": "viewer" // optional — "viewer" | "analyst" | "admin", defaults to "viewer" }
Response · 201
{
"id": "664a1b2c...",
"name": "Alice",
"email": "alice@example.com",
"role": "viewer"
}
Error Codes
400 — Missing required fields | 409 — Email already registered | 500 — Server error
POST
/auth/login
Login and get JWT token
▼
Request Body
{
"email": "alice@example.com",
"password": "secret123"
}
Response · 200
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"role": "admin",
"name": "Alice"
}
Error Codes
400 — Missing email or password | 401 — Invalid credentials or inactive user | 500 — Server error
Users
All user management endpoints require
admin role.
GET
/users
admin
List all users
▼
Response · 200
[
{
"_id": "664a1b2c...",
"name": "Alice",
"email": "alice@example.com",
"role": "admin",
"status": "active",
"createdAt": "2024-06-01T10:00:00.000Z",
"updatedAt": "2024-06-01T10:00:00.000Z"
}
]
Error Codes
401 — No token or invalid token | 403 — Not an admin | 500 — Server error
PATCH
/users/:id/role
admin
Update user role
▼
Path Parameters
:id // User ObjectId
Request Body
{ "role": "analyst" } // required — "viewer" | "analyst" | "admin"
Response · 200
// Updated user object (password excluded)
Error Codes
400 — Invalid role value | 404 — User not found | 401/403 — Auth errors | 500 — Server error
PATCH
/users/:id/status
admin
Activate or deactivate user
▼
Path Parameters
:id // User ObjectId
Request Body
{ "status": "inactive" } // required — "active" | "inactive"
Response · 200
// Updated user object (password excluded)
Inactive users cannot log in. Existing tokens for inactive users are rejected on every request.
Error Codes
400 — Invalid status value | 404 — User not found | 401/403 — Auth errors | 500 — Server error
Records
GET
/records
viewer+
List records with filters
▼
Query Parameters
| Param | Type | Description |
|---|---|---|
| type | string | income or expense |
| category | string | Filter by category name |
| startDate | ISO date | From date e.g. 2024-01-01 |
| endDate | ISO date | To date e.g. 2024-06-30 |
| search | string | Search in notes and category |
| page | number | Page number · default 1 |
| limit | number | Per page · default 20 |
Response · 200
{
"records": [...],
"total": 42,
"page": 1,
"pages": 3
}
Error Codes
400 — Invalid type value | 401 — No token or invalid token | 403 — Not authorized | 500 — Server error
POST
/records
admin
Create a financial record
▼
Request Body
{
"amount": 5000, // required · non-negative number
"type": "income", // required · "income" | "expense"
"category": "salary", // required
"date": "2024-06-01", // optional · Date, defaults to now
"notes": "June salary" // optional
}
Response · 201
{
"_id": "664b2e...",
"amount": 5000,
"type": "income",
"category": "salary",
"date": "2024-06-01T00:00:00.000Z",
"notes": "June salary",
"createdBy": "664a1b2c...",
"deleted": false,
"createdAt": "2024-06-01T10:00:00.000Z",
"updatedAt": "2024-06-01T10:00:00.000Z"
}
Error Codes
400 — Missing required fields, invalid type, or negative amount | 401 — No token or invalid token | 403 — Not an admin | 500 — Server error
PUT
/records/:id
admin
Update a record
▼
Path Parameters
:id // Record ObjectId
Request Body · all fields optional
{
"amount": 6000, // non-negative number
"type": "income", // "income" | "expense"
"category": "bonus", // string
"date": "2024-07-01", // Date
"notes": "Updated" // string
}
Response · 200
// Updated record object
Error Codes
400 — Invalid type or negative amount | 404 — Record not found | 401/403 — Auth errors | 500 — Server error
DELETE
/records/:id
admin
Soft-delete a record
▼
Path Parameters
:id // Record ObjectId
Response · 200
{ "message": "Record deleted" }
Sets
deleted: true on the document. Deleted records are excluded from all queries and aggregations.Error Codes
404 — Record not found | 401/403 — Auth errors | 500 — Server error
Dashboard
GET
/dashboard/summary
viewer+
Totals and recent activity
▼
Response · 200
{
"income": 50000,
"expenses": 32000,
"balance": 18000,
"recent": [...last 5 non-deleted records sorted by date desc]
}
Error Codes
401 — No token or invalid token | 403 — Not authorized | 500 — Server error
GET
/dashboard/categories
viewer+
Totals grouped by type and category
▼
Response · 200
[
{ "_id": { "type": "income", "category": "salary" }, "total": 50000 },
{ "_id": { "type": "expense", "category": "rent" }, "total": 20000 }
]
Error Codes
401 — No token or invalid token | 403 — Not authorized | 500 — Server error
GET
/dashboard/trends
analyst+
Monthly or weekly breakdown
▼
Query Parameters
| Param | Type | Description |
|---|---|---|
| period | string | monthly (default) or weekly |
Response · 200
[
{ "_id": { "period": "2024-06", "type": "income" }, "total": 25000 },
{ "_id": { "period": "2024-06", "type": "expense" }, "total": 16000 }
]
Error Codes
400 — Invalid period value | 401 — No token or invalid token | 403 — Not analyst or admin | 500 — Server error
Error Codes
All error responses follow the format:
{ "error": "<message>" }200
OK
Request succeeded
201
Created
Resource created successfully
400
Bad Request
Missing or invalid input fields
401
Unauthorized
No token, invalid token, or inactive user
403
Forbidden
Role does not have permission
404
Not Found
Resource or route does not exist
409
Conflict
Duplicate email on registration
429
Too Many Requests
Rate limit exceeded
500
Server Error
Unexpected internal failure