Version: 1.0
Date: 27 Jan 2026
Status: Planning
Base URL: http://localhost:3000/api (Development)
- RESTful architecture
- JSON request/response format
- JWT authentication
- Consistent error handling
- Pagination for list endpoints
- Rate limiting enabled
Content-Type: application/json
Authorization: Bearer <jwt_token>
{
"success": true,
"message": "Operation successful",
"data": { ... }
}{
"success": false,
"message": "Error description",
"error": "ERROR_CODE",
"details": {
"field": "email",
"issue": "Email already exists"
}
}{
"success": true,
"data": [...],
"pagination": {
"page": 1,
"limit": 20,
"total": 100,
"totalPages": 5,
"hasNext": true,
"hasPrev": false
}
}POST /api/auth/register
Register a new user account.
Request Body:
{
"name": "John Doe",
"email": "john@example.com",
"password": "password123",
"role": "user"
}Response (201 Created):
{
"success": true,
"message": "User registered successfully",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": "clx123abc",
"name": "John Doe",
"email": "john@example.com",
"role": "user",
"createdAt": "2026-01-27T10:00:00Z"
}
}Errors:
400: Validation error (missing fields, invalid email)409: Email already exists500: Server error
POST /api/auth/login
Authenticate user and receive JWT token.
Request Body:
{
"email": "john@example.com",
"password": "password123"
}Response (200 OK):
{
"success": true,
"message": "Login successful",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": "clx123abc",
"name": "John Doe",
"email": "john@example.com",
"role": "user"
}
}Errors:
400: Missing email or password401: Invalid credentials500: Server error
GET /api/auth/me
Get authenticated user information.
Headers:
Authorization: Bearer <token>
Response (200 OK):
{
"success": true,
"message": "User retrieved successfully",
"data": {
"id": "clx123abc",
"name": "John Doe",
"email": "john@example.com",
"role": "user",
"createdAt": "2026-01-27T10:00:00Z",
"updatedAt": "2026-01-27T10:00:00Z"
}
}Errors:
401: Unauthorized (invalid/expired token)404: User not found500: Server error
POST /api/auth/logout
Logout user (client-side token removal).
Headers:
Authorization: Bearer <token>
Response (200 OK):
{
"success": true,
"message": "Logout successful"
}POST /api/auth/refresh
Refresh expired JWT token.
Request Body:
{
"refreshToken": "refresh_token_here"
}Response (200 OK):
{
"success": true,
"token": "new_jwt_token",
"refreshToken": "new_refresh_token"
}GET /api/users
Get list of all users with pagination.
Query Parameters:
page: 1 (default)
limit: 20 (default, max 100)
search: "john" (optional)
role: "user" | "admin" | "partner" (optional)
sortBy: "createdAt" | "name" | "email" (default: createdAt)
order: "asc" | "desc" (default: desc)
Example:
GET /api/users?page=1&limit=20&role=user&search=john
Response (200 OK):
{
"success": true,
"data": [
{
"id": "clx123abc",
"name": "John Doe",
"email": "john@example.com",
"role": "user",
"createdAt": "2026-01-27T10:00:00Z"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 45,
"totalPages": 3,
"hasNext": true,
"hasPrev": false
}
}Errors:
401: Unauthorized403: Forbidden (not admin)500: Server error
GET /api/users/:id
Get specific user details.
Response (200 OK):
{
"success": true,
"data": {
"id": "clx123abc",
"name": "John Doe",
"email": "john@example.com",
"role": "user",
"createdAt": "2026-01-27T10:00:00Z",
"updatedAt": "2026-01-27T10:00:00Z"
}
}Errors:
401: Unauthorized403: Forbidden (can only view own profile unless admin)404: User not found500: Server error
PUT /api/users/:id
Update user information.
Request Body:
{
"name": "John Updated",
"email": "john.new@example.com"
}Response (200 OK):
{
"success": true,
"message": "User updated successfully",
"data": {
"id": "clx123abc",
"name": "John Updated",
"email": "john.new@example.com",
"role": "user",
"updatedAt": "2026-01-27T11:00:00Z"
}
}Errors:
400: Validation error401: Unauthorized403: Forbidden (can only update own profile unless admin)404: User not found409: Email already exists500: Server error
DELETE /api/users/:id
Delete user account (soft delete).
Response (200 OK):
{
"success": true,
"message": "User deleted successfully"
}Errors:
401: Unauthorized403: Forbidden (admin only)404: User not found500: Server error
GET /api/users/me/profile
Get authenticated user's full profile.
Response (200 OK):
{
"success": true,
"data": {
"id": "clx123abc",
"name": "John Doe",
"email": "john@example.com",
"role": "user",
"avatar": "https://...",
"preferences": {
"language": "en",
"notifications": true
},
"createdAt": "2026-01-27T10:00:00Z"
}
}PUT /api/users/me/profile
Update authenticated user's profile.
Request Body:
{
"name": "John Updated",
"avatar": "https://...",
"preferences": {
"language": "id",
"notifications": false
}
}Response (200 OK):
{
"success": true,
"message": "Profile updated successfully",
"data": { ... }
}GET /api/[feature]
Get list of items with pagination and filters.
Query Parameters:
page: 1 (default)
limit: 20 (default)
search: "keyword" (optional)
status: "active" | "inactive" (optional)
sortBy: "createdAt" | "title" (default: createdAt)
order: "asc" | "desc" (default: desc)
Response (200 OK):
{
"success": true,
"data": [
{
"id": "item123",
"title": "Item Title",
"description": "Item description",
"status": "active",
"userId": "clx123abc",
"createdAt": "2026-01-27T10:00:00Z"
}
],
"pagination": { ... }
}Errors:
400: Invalid query parameters500: Server error
GET /api/[feature]/:id
Get specific item details.
Response (200 OK):
{
"success": true,
"data": {
"id": "item123",
"title": "Item Title",
"description": "Full description here",
"status": "active",
"userId": "clx123abc",
"user": {
"id": "clx123abc",
"name": "John Doe"
},
"createdAt": "2026-01-27T10:00:00Z",
"updatedAt": "2026-01-27T10:00:00Z"
}
}Errors:
404: Item not found500: Server error
POST /api/[feature]
Create new item (requires authentication).
Headers:
Authorization: Bearer <token>
Request Body:
{
"title": "New Item",
"description": "Item description",
"status": "active"
}Response (201 Created):
{
"success": true,
"message": "Item created successfully",
"data": {
"id": "item456",
"title": "New Item",
"description": "Item description",
"status": "active",
"userId": "clx123abc",
"createdAt": "2026-01-27T11:00:00Z"
}
}Errors:
400: Validation error401: Unauthorized500: Server error
PUT /api/[feature]/:id
Update existing item (requires authentication).
Headers:
Authorization: Bearer <token>
Request Body:
{
"title": "Updated Title",
"description": "Updated description",
"status": "inactive"
}Response (200 OK):
{
"success": true,
"message": "Item updated successfully",
"data": {
"id": "item123",
"title": "Updated Title",
"description": "Updated description",
"status": "inactive",
"updatedAt": "2026-01-27T12:00:00Z"
}
}Errors:
400: Validation error401: Unauthorized403: Forbidden (not owner or admin)404: Item not found500: Server error
DELETE /api/[feature]/:id
Delete item (requires authentication).
Headers:
Authorization: Bearer <token>
Response (200 OK):
{
"success": true,
"message": "Item deleted successfully"
}Errors:
401: Unauthorized403: Forbidden (not owner or admin)404: Item not found500: Server error
INVALID_CREDENTIALS: Invalid email or password
TOKEN_EXPIRED: JWT token has expired
TOKEN_INVALID: JWT token is invalid
UNAUTHORIZED: Authentication required
FORBIDDEN: Insufficient permissions
VALIDATION_ERROR: Input validation failed
MISSING_FIELD: Required field missing
INVALID_EMAIL: Email format invalid
INVALID_PASSWORD: Password too weak
FIELD_TOO_SHORT: Field below minimum length
FIELD_TOO_LONG: Field exceeds maximum length
NOT_FOUND: Resource not found
ALREADY_EXISTS: Resource already exists
CONFLICT: Resource conflict
SERVER_ERROR: Internal server error
DATABASE_ERROR: Database operation failed
NETWORK_ERROR: Network request failed
Anonymous: 60 requests / 15 minutes
Authenticated: 100 requests / 15 minutes
Admin: Unlimited
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1706356800
{
"success": false,
"message": "Too many requests",
"error": "RATE_LIMIT_EXCEEDED",
"retryAfter": 900
}page: Page number (default: 1)
limit: Items per page (default: 20, max: 100)
{
"pagination": {
"page": 2,
"limit": 20,
"total": 100,
"totalPages": 5,
"hasNext": true,
"hasPrev": true
}
}status: Filter by status
search: Search in title/description
userId: Filter by user
dateFrom: Filter from date
dateTo: Filter to date
sortBy: Field to sort by
order: "asc" or "desc"
GET /api/items?status=active&search=keyword&sortBy=createdAt&order=desc
curl -X POST http://localhost:3000/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"name": "Test User",
"email": "test@example.com",
"password": "password123"
}'curl -X POST http://localhost:3000/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "test@example.com",
"password": "password123"
}'curl http://localhost:3000/api/users/me \
-H "Authorization: Bearer YOUR_TOKEN_HERE"curl -X POST http://localhost:3000/api/items \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{
"title": "New Item",
"description": "Description here"
}'Import this collection to Postman for easy API testing:
Collection Structure:
Project API
βββ Auth
β βββ Register
β βββ Login
β βββ Get Me
βββ Users
β βββ List Users
β βββ Get User
β βββ Update User
β βββ Delete User
βββ [Feature]
βββ List Items
βββ Get Item
βββ Create Item
βββ Update Item
βββ Delete Item
Environment Variables:
base_url: http://localhost:3000/api
token: {{token}} (auto-set after login)
Note: API ini akan terus berkembang seiring kebutuhan project.