API Reference
Complete API documentation for the Bellamy Book application. All endpoints are RESTful and return JSON responses.
Base URL
Development:
http://localhost:5000/api
Production:
https://api.your-domain.com/api
Authentication
Most endpoints require authentication using JWT (JSON Web Tokens). The API uses Bearer token authentication.
Getting a Token
Authenticate using email and password:
POST /api/Authentication/login
Content-Type: application/json
{
"email": "[email protected]",
"password": "password"
}
Response:
{
"success": true,
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "refresh-token-here",
"expiresIn": 3600,
"user": {
"id": "user-id",
"fullName": "John Doe",
"username": "johndoe"
}
}
}
Using the Token
Include the token in the Authorization header for all authenticated requests:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Example:
const response = await fetch('http://localhost:5000/api/Post/feed/home', {
method: 'GET',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
Token Expiration
- Access Token: Valid for 60 minutes (configurable)
- Refresh Token: Valid for 7 days (configurable)
When the access token expires, use the refresh token to get a new access token:
POST /api/Authentication/refresh-token
Content-Type: application/json
{
"refreshToken": "your-refresh-token"
}
API Route Structure
The backend uses ASP.NET Core controller-based routing. Main route prefixes (case-insensitive):
| Area | Route prefix | Details |
|---|---|---|
| Auth | api/Authentication | login, register, refresh-token, logout, me, user profile; forgot-password, reset-password, verify-email, send-verification-email; 2FA (setup-2fa, enable-2fa, verify-2fa, disable-2fa); change-password, update-profile, update-about-info; avatar, wallpaper; close-account; external-login; impersonate, exit-impersonation |
| Posts | api/Post | feed, create, get, update, delete, reactions |
| Comments | api/Comment | create, get, update, delete, reactions |
| Reactions | api/Post/{id}/reactions, api/Comment/{id}/reactions | add, remove |
| Stories | api/Story | create, feed, view, react, archive |
| Friends | api/Friendship, api/Follow, api/friends | requests, suggestions, search |
| Chat | api/Chat, api/Call, api/StrangerChat | messages, groups, calls |
| Notifications | api/Notification | paged, unread count, mark read |
| Announcements | api/Announcement | create, history, delete (admin) |
| Hashtags | api/Hashtags | search, details, posts, trending |
| Search | api/Search | universal, posts, blogs, users, hashtags, autocomplete |
| Blogs | api/Blog, api/blog-comments | list, slug, create, publish, uploads, comments |
| Media | api/media, api/media/performance | avatar, wallpaper, story, default, stats |
| License | api/license, api/license/generation | activate, status, validate; generate (MAIN) |
| Email Campaigns | api/EmailCampaign | list, get, history, create, update, cancel, generate-queue, delete |
| Support Tickets | api/tickets, api/ticket-comments | list, get, status; comments |
| AI Agent | api/ai-agent | settings, logs, costs, generate, test-api-key |
| Contact | api/Contact | POST send message (public) |
| SEO | api/Sitemap | sitemap.xml, robots.txt |
| Application Settings | api/ApplicationSettings | read/write (admin) |
| Push | api/PushSubscription | web push subscriptions |
| Moderation | api/Moderation | report, moderation actions |
| Admin | api/admin/dashboard, api/admin/backup, api/admin/elasticsearch, etc. | dashboard, backup, analytics |
Further API details (endpoints, request/response): see the corresponding feature docs under Features (e.g. Blogs, Search, Backup, License System).
API Structure
Authentication (api/Authentication)
- Register —
POST /api/Authentication/register - Login —
POST /api/Authentication/login - Refresh Token —
POST /api/Authentication/refresh-token
Users
- Get User —
GET /api/Authentication/me,GET /api/Authentication/user/{userId} - Update Profile
- Friends —
api/Friendship,api/friends
Posts (api/Post)
- Create Post —
POST /api/Post/users/{userId} - Get Post
- Update Post
- Delete Post
Comments (api/Comment)
Reactions
Response Format
All API responses follow a consistent format.
Success Response
{
"success": true,
"data": {
// Response data here
},
"message": "Operation successful" // Optional
}
Status Codes:
200 OK- Successful GET, PUT, PATCH requests201 Created- Successful POST requests (resource created)204 No Content- Successful DELETE requests
Error Response
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message",
"details": {
// Additional error details (optional)
}
}
}
Common Error Codes:
| Code | HTTP Status | Description |
|---|---|---|
UNAUTHORIZED | 401 | Authentication required or invalid token |
FORBIDDEN | 403 | Insufficient permissions |
NOT_FOUND | 404 | Resource not found |
VALIDATION_ERROR | 400 | Request validation failed |
CONFLICT | 409 | Resource conflict (e.g., duplicate entry) |
RATE_LIMIT_EXCEEDED | 429 | Too many requests |
INTERNAL_ERROR | 500 | Server error |
Example Error Response:
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": {
"email": ["Email is required"],
"password": ["Password must be at least 8 characters"]
}
}
}
Rate Limiting
API requests are rate-limited to prevent abuse and ensure fair usage.
Rate Limits:
- Authenticated Users: 1000 requests per hour
- Unauthenticated Users: 100 requests per hour
- Specific Endpoints: May have different limits (e.g., login: 5 requests per minute)
Rate Limit Headers:
All responses include rate limit information in headers:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1640995200
When Rate Limit Exceeded:
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1640995200
Retry-After: 3600
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Please try again later.",
"retryAfter": 3600
}
}
Best Practices:
- Implement exponential backoff for retries
- Cache responses when possible
- Use pagination to reduce request count
- Monitor rate limit headers
Pagination
List endpoints support pagination to efficiently retrieve large datasets.
Pagination Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number (1-indexed) |
limit | integer | 20 | Items per page (max: 100) |
sortBy | string | "createdAt" | Field to sort by |
sortOrder | string | "desc" | Sort order: "asc" or "desc" |
Example Request
GET /api/Post/feed/home?userId={userId}&limit=20&offset=0
Paginated Response
{
"success": true,
"data": [
// Array of items
],
"pagination": {
"page": 1,
"limit": 20,
"total": 100,
"totalPages": 5,
"hasNext": true,
"hasPrevious": false
}
}
Pagination Best Practices
- Use appropriate
limitvalues (10-50 for most cases) - Implement infinite scroll or "Load More" buttons
- Cache paginated results when possible
- Use
sortByandsortOrderfor consistent ordering
Request/Response Examples
cURL Examples
Login:
curl -X POST http://localhost:5000/api/Authentication/login \
-H "Content-Type: application/json" \
Create Post:
curl -X POST http://localhost:5000/api/Post/users/{userId} \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "caption=Hello, world!" \
-F "visibility=Public"
Get Feed:
curl -X GET "http://localhost:5000/api/Post/feed/home?userId=USER_ID&limit=20&offset=0" \
-H "Authorization: Bearer YOUR_TOKEN"
JavaScript/TypeScript Examples
Using Fetch API:
// Login
const loginResponse = await fetch('http://localhost:5000/api/Authentication/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
password: 'password'
})
});
const loginData = await loginResponse.json();
const token = loginData.data.token;
// Create Post (multipart/form-data with caption, visibility, optional mediaFiles)
const formData = new FormData();
formData.append('caption', 'Hello, world!');
formData.append('visibility', 'Public');
const postResponse = await fetch(`http://localhost:5000/api/Post/users/${userId}`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
},
body: formData
});
Using Axios:
import axios from 'axios';
const api = axios.create({
baseURL: 'http://localhost:5000/api',
headers: {
'Content-Type': 'application/json',
},
});
// Add token to requests
api.interceptors.request.use((config) => {
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
// Login
const { data } = await api.post('/Authentication/login', {
password: 'password'
});
// Create Post (FormData: caption, visibility, optional mediaFiles)
const formData = new FormData();
formData.append('caption', 'Hello, world!');
formData.append('visibility', 'Public');
await api.post(`/Post/users/${userId}`, formData);
SignalR (Real-time)
Real-time features use SignalR (not raw WebSockets). The frontend uses @microsoft/signalr.
Hub endpoints (base URL may differ per environment; chat hub is often on a separate worker):
| Hub | Path | Hosted by | Purpose |
|---|---|---|---|
| Chat | /hubs/chat | ChatWorker | Real-time chat messages, typing, read receipts, reactions |
| Chat online | /hubs/chat-online | ChatWorker | Chat presence |
| Notification | /hubs/notification | WebSocketWorker | In-app notifications |
| Online users | /hubs/onlineusers | WebSocketWorker | User presence (online/offline) |
Configuration: Set VITE_SIGNALR_BASE_URL (and optionally VITE_CHAT_HUB_URL for chat) in the frontend. ChatWorker typically runs on a different port (e.g. 5210) than the main API.
Example (Chat):
import * as signalR from '@microsoft/signalr';
const connection = new signalR.HubConnectionBuilder()
.withUrl(`${chatHubBaseUrl}/hubs/chat?userId=${userId}`, {
accessTokenFactory: () => token
})
.withAutomaticReconnect()
.build();
await connection.start();
connection.on('ReceiveMessage', (message) => { /* handle new message */ });
await connection.invoke('JoinConversation', conversationId);
await connection.invoke('SendMessage', { recipientId, content, type: 'text' });
See Messaging Feature for full Chat API and SignalR usage, and Workers for ChatWorker vs WebSocketWorker.
Testing the API
Using Swagger UI
If Swagger is enabled, access the interactive API documentation:
http://localhost:5000/swagger
Using Postman
Import the API collection (if available) or manually test endpoints:
- Set base URL:
http://localhost:5000/api - Add authentication header:
Authorization: Bearer {token} - Test endpoints with different parameters
API Versioning
Currently, the API is at version 1. Future versions will be accessible via:
/api/v2/...
Learn More
- Authentication API — Login, register, refresh tokens
- Posts API — Create, read, update, delete posts
- Users API — User profiles and management
- Comments API — Comment management
- Reactions API — Like and react to content
- Features — All features with API summaries (Blogs, Search, Backup, Media, License, Email Campaigns, Support Tickets, AI Agent, Announcements, etc.)