http://localhost:5000/api
https://localhost:5001/api (with SSL)
✅ JWT Bearer Token (Implemented)
Include JWT token in Authorization header:
Authorization: Bearer <token>Get token from /api/auth/login endpoint.
Note: Health check endpoints are public (no authentication required).
{
"id": "uuid",
"data": {}
}{
"items": [...],
"pageNumber": 1,
"pageSize": 10,
"totalItems": 50,
"totalPages": 5,
"hasNextPage": true,
"hasPreviousPage": false
}{
"message": "error message",
"timestamp": "2026-06-03T10:30:00Z",
"traceId": "trace-id-here",
"errors": {
"fieldName": ["error message"]
}
}GET /health
Comprehensive health status with dependency checks.
Authentication: Not required
Response (200 OK):
{
"status": "Healthy",
"service": "NoteBook API",
"timestamp": "2026-06-03T10:30:00Z",
"version": "2.0.0",
"environment": "Production",
"databaseConnected": true,
"uptimeMs": 3600000
}Response (503 Service Unavailable):
{
"status": "Unhealthy",
"service": "NoteBook API",
"timestamp": "2026-06-03T10:30:00Z",
"version": "2.0.0",
"environment": "Production",
"databaseConnected": false,
"uptimeMs": 3600000
}Example Request:
curl http://localhost:5000/api/healthGET /health/live
Quick check that the process is alive (for Kubernetes/Docker).
Authentication: Not required
Response (200 OK):
{
"status": "alive",
"timestamp": "2026-06-03T10:30:00Z"
}Example Request:
curl http://localhost:5000/api/health/liveGET /health/ready
Check if service is ready to accept traffic.
Authentication: Not required
Response (200 OK):
{
"status": "ready",
"timestamp": "2026-06-03T10:30:00Z"
}Response (503 Service Unavailable):
{
"status": "not_ready",
"reason": "Database unavailable",
"timestamp": "2026-06-03T10:30:00Z"
}Example Request:
curl http://localhost:5000/api/health/ready📖 See HEALTH_CHECKS.md for detailed health check documentation.
POST /auth/login
Get JWT token for API access.
Request Body:
{
"username": "user@example.com",
"password": "password"
}Response (200 OK):
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"userId": "550e8400-e29b-41d4-a716-446655440001",
"username": "user@example.com"
}Errors:
401 Unauthorized: Invalid credentials
GET /notes
Returns all active notes for the current user. Supports optional pagination.
Authentication: Required (JWT Bearer Token)
Query Parameters:
pageNumber(optional, integer): Page number (1-based)pageSize(optional, integer): Items per page (1-100)
Response Without Pagination (200 OK):
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "First Note",
"content": "This is the content",
"tags": "work,important",
"userId": "550e8400-e29b-41d4-a716-446655440001",
"createdAt": "2026-06-03T10:30:00Z",
"updatedAt": "2026-06-03T10:30:00Z"
}
]Response With Pagination (200 OK):
{
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "First Note",
"content": "This is the content",
"tags": "work,important",
"userId": "550e8400-e29b-41d4-a716-446655440001",
"createdAt": "2026-06-03T10:30:00Z",
"updatedAt": "2026-06-03T10:30:00Z"
}
],
"pageNumber": 1,
"pageSize": 10,
"totalItems": 50,
"totalPages": 5,
"hasNextPage": true,
"hasPreviousPage": false
}Example Requests:
# Get all notes
curl -H "Authorization: Bearer <token>" http://localhost:5000/api/notes
# Get first page with 10 items
curl -H "Authorization: Bearer <token>" "http://localhost:5000/api/notes?pageNumber=1&pageSize=10"
# Get second page
curl -H "Authorization: Bearer <token>" "http://localhost:5000/api/notes?pageNumber=2&pageSize=10"📖 See PAGINATION.md for detailed pagination documentation.
GET /notes/{id}
Returns a specific note by its ID.
Authentication: Required
Path Parameters:
id(UUID): Note ID
Response (200 OK):
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "First Note",
"content": "This is the content",
"tags": "work,important",
"userId": "550e8400-e29b-41d4-a716-446655440001",
"createdAt": "2026-06-03T10:30:00Z",
"updatedAt": "2026-06-03T10:30:00Z"
}Errors:
404 Not Found: Note doesn't exist401 Unauthorized: Missing or invalid token
Example Request:
curl -H "Authorization: Bearer <token>" http://localhost:5000/api/notes/550e8400-e29b-41d4-a716-446655440000POST /notes
Creates a new note for the current user.
Authentication: Required
Request Body:
{
"title": "My New Note",
"content": "The content of the note",
"tags": "tag1,tag2,tag3"
}Response (201 Created):
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "My New Note",
"content": "The content of the note",
"tags": "tag1,tag2,tag3",
"userId": "550e8400-e29b-41d4-a716-446655440001",
"createdAt": "2026-06-03T10:30:00Z",
"updatedAt": "2026-06-03T10:30:00Z"
}Validation:
title: Required, max 255 characterscontent: Required, no length limittags: Optional, comma-separated values (max 500 chars)
Errors:
400 Bad Request: Validation failed401 Unauthorized: Missing or invalid token
Example Request:
curl -X POST http://localhost:5000/api/notes \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"title": "My New Note",
"content": "The content",
"tags": "work"
}'PUT /notes/{id}
Updates an existing note.
Authentication: Required
Path Parameters:
id(UUID): Note ID
Request Body:
{
"title": "Updated Title",
"content": "Updated content",
"tags": "updated,tags"
}Response (200 OK):
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Updated Title",
"content": "Updated content",
"tags": "updated,tags",
"userId": "550e8400-e29b-41d4-a716-446655440001",
"createdAt": "2026-06-03T10:30:00Z",
"updatedAt": "2026-06-03T11:00:00Z"
}Errors:
404 Not Found: Note doesn't exist400 Bad Request: Validation failed401 Unauthorized: Missing or invalid token
Example Request:
curl -X PUT http://localhost:5000/api/notes/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"title": "Updated Title",
"content": "Updated content",
"tags": "updated"
}'DELETE /notes/{id}
Soft deletes a note (marks as deleted but doesn't remove from database).
Authentication: Required
Path Parameters:
id(UUID): Note ID
Response (204 No Content):
(empty body)
Errors:
404 Not Found: Note doesn't exist401 Unauthorized: Missing or invalid token
Example Request:
curl -X DELETE http://localhost:5000/api/notes/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer <token>"GET /notes/search?term=searchterm
Searches notes by title, content, and tags.
Authentication: Required
Query Parameters:
term(string, required): Search term (minimum 1 character)
Response (200 OK):
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Note about work",
"content": "This is about the work project",
"tags": "work,project",
"userId": "550e8400-e29b-41d4-a716-446655440001",
"createdAt": "2026-06-03T10:30:00Z",
"updatedAt": "2026-06-03T10:30:00Z"
}
]Search Behavior:
- Case-insensitive
- Searches in: title, content, tags
- Returns active notes only (excludes archived and deleted)
Errors:
400 Bad Request: Search term is empty401 Unauthorized: Missing or invalid token
Example Request:
curl -H "Authorization: Bearer <token>" "http://localhost:5000/api/notes/search?term=work"| Code | Meaning | Common Cause |
|---|---|---|
| 200 | OK | Successful GET/PUT request |
| 201 | Created | Successful POST request |
| 204 | No Content | Successful DELETE request |
| 400 | Bad Request | Invalid input or validation error |
| 401 | Unauthorized | Missing/invalid token |
| 404 | Not Found | Resource doesn't exist |
| 500 | Server Error | Unhandled exception |
| 503 | Service Unavailable | Health check failed |
Planned for production: 100 requests per minute per user.
Planned: Filter by date range, tags, archive status.
# Get JWT token
TOKEN=$(curl -X POST http://localhost:5000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"user","password":"pass"}' | jq -r '.token')
# Get all notes
curl -H "Authorization: Bearer $TOKEN" http://localhost:5000/api/notes
# Get with pagination
curl -H "Authorization: Bearer $TOKEN" "http://localhost:5000/api/notes?pageNumber=1&pageSize=10"
# Create note
curl -X POST http://localhost:5000/api/notes \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Test","content":"Content","tags":"test"}'
# Update note
curl -X PUT http://localhost:5000/api/notes/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Updated","content":"Updated","tags":"test"}'
# Delete note
curl -X DELETE http://localhost:5000/api/notes/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer $TOKEN"
# Search notes
curl -H "Authorization: Bearer $TOKEN" "http://localhost:5000/api/notes/search?term=test"
# Health check (no token needed)
curl http://localhost:5000/api/health- Import API collection
- Set base URL:
http://localhost:5000/api - Login to get JWT token
- Add token to Authorization header
- Run requests
Create .http file:
@token = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
### Get all notes
GET http://localhost:5000/api/notes
Authorization: Bearer @token
### Get with pagination
GET http://localhost:5000/api/notes?pageNumber=1&pageSize=10
Authorization: Bearer @token
### Create note
POST http://localhost:5000/api/notes
Authorization: Bearer @token
Content-Type: application/json
{
"title": "Test Note",
"content": "Test content",
"tags": "test"
}
### Health check
GET http://localhost:5000/api/healthCurrent API version: 2.0.0
API structure supports future versioning with /api/v2/ path prefix when needed.
All origins allowed in development (*).
Production: Configure specific allowed origins in appsettings.json.
Version: 2.0.0
Last Updated: June 2026
New in 2.1.0: Health checks, pagination, global error handling