All protected endpoints require a valid session. The API uses NextAuth.js with JWT tokens.
GET /api/products- List products (public read)POST /api/auth/register- User registrationPOST /api/auth/[...nextauth]- NextAuth handlersGET /api/setup- Check if setup is neededPOST /api/setup- Create first admin (only works if no admin exists)
POST /api/products- Create productPUT /api/products/:id- Update productDELETE /api/products/:id- Delete productPOST /api/admin/create- Create admin userGET/PUT /api/users- User managementGET/PUT /api/profile- Profile managementPOST/DELETE /api/upload- Image uploadGET /api/dashboard- Analytics data
| Endpoint Type | Limit | Window |
|---|---|---|
| Default | 100 requests | 1 minute |
| Auth endpoints | 20 requests | 1 minute |
| Upload | 10 requests | 1 minute |
Rate limit headers included in responses:
X-RateLimit-Limit: Maximum requests allowedX-RateLimit-Remaining: Requests remainingX-RateLimit-Reset: Unix timestamp for reset
GET /api/products?page=1&limit=10&search=laptop&category=electronics
Response:
{
"products": [...],
"pagination": {
"page": 1,
"limit": 10,
"total": 50,
"pages": 5
}
}GET /api/products/:id
POST /api/products
Content-Type: application/json
{
"name": "Product Name",
"description": "Description",
"category": "electronics",
"price": 99.99,
"stock": 100,
"sku": "PROD-001",
"status": "active",
"images": ["https://..."],
"tags": ["tag1", "tag2"],
"specifications": [{"key": "Color", "value": "Black"}]
}
PUT /api/products/:id
Content-Type: application/json
{ ...product fields... }
DELETE /api/products/:id
GET /api/users
Response:
{
"users": [
{
"_id": "...",
"name": "User Name",
"email": "user@example.com",
"role": "admin",
"createdAt": "..."
}
]
}PUT /api/users
Content-Type: application/json
{
"userId": "user-id",
"role": "admin" | "user"
}
GET /api/profile
PUT /api/profile
Content-Type: application/json
{
"name": "New Name",
"currentPassword": "old-password",
"newPassword": "new-password"
}
GET /api/dashboard
Response:
{
"totalProducts": 50,
"totalRevenue": 10000.00,
"lowStockProducts": 5,
"recentSales": 25,
"salesData": [...],
"categoryDistribution": [...],
"topProducts": [...]
}POST /api/upload
Content-Type: multipart/form-data
file: <image file>
Response:
{
"url": "https://res.cloudinary.com/...",
"publicId": "citadel/..."
}DELETE /api/upload
Content-Type: application/json
{
"publicId": "citadel/..."
}
{
"error": "Error message here"
}| Status | Meaning |
|---|---|
| 400 | Bad Request - Invalid input |
| 401 | Unauthorized - Not authenticated |
| 403 | Forbidden - Not authorized |
| 404 | Not Found |
| 429 | Too Many Requests |
| 500 | Internal Server Error |