Skip to main content

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",
"email": "[email protected]",
"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):

AreaRoute prefixDetails
Authapi/Authenticationlogin, 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
Postsapi/Postfeed, create, get, update, delete, save / unsave, reactions
Commentsapi/Commentcreate, get, update, delete, reactions
Reactionsapi/Post/{id}/reactions, api/Comment/{id}/reactionsadd, remove
Storiesapi/Storycreate, feed, view, react, archive
Friendsapi/Friendship, api/Follow, api/friendsrequests, suggestions, search
Chatapi/Chat, api/Call, api/StrangerChatmessages, groups, calls
Notificationsapi/Notificationpaged, unread count, mark read
Announcementsapi/Announcementcreate, history, delete (admin)
Hashtagsapi/Hashtagssearch, details, posts, trending
Searchapi/Searchuniversal, posts, blogs, users, hashtags, autocomplete
Blogsapi/Blog, api/blog-commentslist, slug, create, publish, uploads, comments
Mediaapi/media, api/media/performanceavatar, wallpaper, story, default, stats
Licenseapi/license, api/license/generationactivate, status, validate; generate (MAIN)
Email Campaignsapi/EmailCampaignlist, get, history, create, update, cancel, generate-queue, delete
Support Ticketsapi/tickets, api/ticket-commentslist, get, status; comments
AI Agentapi/ai-agentsettings, logs, costs, generate, test-api-key
Contactapi/ContactPOST send message (public)
SEOapi/Sitemapsitemap.xml, robots.txt
Application Settingsapi/ApplicationSettingsread/write (admin)
Pushapi/PushSubscriptionweb push subscriptions
Moderationapi/Moderationreport, moderation actions
Adminapi/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​

Posts (api/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 requests
  • 201 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:

CodeHTTP StatusDescription
UNAUTHORIZED401Authentication required or invalid token
FORBIDDEN403Insufficient permissions
NOT_FOUND404Resource not found
VALIDATION_ERROR400Request validation failed
CONFLICT409Resource conflict (e.g., duplicate entry)
RATE_LIMIT_EXCEEDED429Too many requests
INTERNAL_ERROR500Server 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​

ParameterTypeDefaultDescription
pageinteger1Page number (1-indexed)
limitinteger20Items per page (max: 100)
sortBystring"createdAt"Field to sort by
sortOrderstring"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 limit values (10-50 for most cases)
  • Implement infinite scroll or "Load More" buttons
  • Cache paginated results when possible
  • Use sortBy and sortOrder for consistent ordering

Request/Response Examples​

cURL Examples​

Login:

curl -X POST http://localhost:5000/api/Authentication/login \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","password":"password"}'

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):

HubPathHosted byPurpose
Chat/hubs/chatChatWorkerReal-time chat messages, typing, read receipts, reactions
Chat online/hubs/chat-onlineChatWorkerChat presence
Notification/hubs/notificationWebSocketWorkerIn-app notifications
Online users/hubs/onlineusersWebSocketWorkerUser 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:

  1. Set base URL: http://localhost:5000/api
  2. Add authentication header: Authorization: Bearer {token}
  3. 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, save posts
  • Saved Posts — Bookmark collection (/profile/saved)
  • 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.)