API Documentation
Complete API reference for the backend notification server and frontend services
Base URL: https://your-backend.vercel.app or http://localhost:3000
Health & Status
Server health monitoring endpoint
Check server status and uptime.
Response
{
"status": "healthy",
"message": "MR BunkManager Notification Server is running",
"timestamp": "26/11/2025, 03:30:45 PM",
"timezone": "Asia/Kolkata (IST)",
"uptime": 3600.5
}
Push Token Management
Register and manage device push tokens
Register a device push token for notifications.
Request Body
{
"userId": "firebase_user_id",
"token": "ExponentPushToken[xxxxx] or FCM_token"
}
Response
{
"success": true,
"message": "Push token saved successfully",
"userId": "firebase_user_id",
"tokenType": "expo",
"timestamp": "26/11/2025, 03:30:45 PM"
}
Error Codes
| Code | Description |
|---|---|
| 400 | Missing userId or token |
| 400 | Invalid token format |
| 500 | Firebase error |
Remove push token(s) for a user or specific token.
Request Body
{
"token": "ExponentPushToken[xxxxx]"
}
or
{
"userId": "firebase_user_id"
}
Get all push tokens for a specific user.
Response
{
"success": true,
"userId": "firebase_user_id",
"tokens": [
{
"id": "token_id",
"token": "ExponentPushToken[xxxxx]",
"tokenType": "expo",
"createdAt": "timestamp",
"active": true
}
],
"count": 1
}
Notification Sending
Send push notifications to users
Send notification to a specific user.
Request Body
{
"userId": "firebase_user_id",
"title": "Custom Title (optional)",
"body": "Custom message (optional)",
"data": {
"type": "custom",
"key": "value"
}
}
Response
{
"success": true,
"message": "Notification sent successfully",
"result": {
"userId": "firebase_user_id",
"sent": 1,
"failed": 0,
"invalidTokensRemoved": 0
}
}
Broadcast notification to all registered users.
Request Body
{
"title": "System Update",
"body": "Important announcement",
"data": { "type": "system" }
}
Send personalized daily reminders about tomorrow's classes. Generates contextual messages based on attendance data.
Send reminders for classes starting soon.
Request Body
{
"minutesBefore": 30
}
Valid values: 30 or 10
Group Notifications
Notify group members about activity
Notify group members about activity (messages, files, calls).
Request Body
{
"groupId": "group_id",
"groupName": "Study Group",
"senderId": "user_id",
"senderName": "John Doe",
"type": "message",
"extra": {
"message": "Hello everyone!"
}
}
Activity Types
| Type | Extra Fields | Notification |
|---|---|---|
message | message | "John Doe: Hello..." |
file | fileName | "John Doe shared a file" |
call | isVideo | "John Doe started a call" |
Follower Notifications
Notify followers about new content
Notify followers when user uploads a new note.
Request Body
{
"authorId": "user_id",
"authorName": "John Doe",
"noteId": "note_id",
"title": "Biology Notes Chapter 5",
"subject": "Biology"
}
File Upload
Upload files to cloud storage
Upload file to Google Drive. Accepts multipart/form-data with file field.
Allowed Types: JPEG, PNG, GIF, WebP, PDF (max 50MB)
Response
{
"success": true,
"fileId": "google_drive_file_id",
"fileName": "timestamp_filename.pdf",
"mimeType": "application/pdf",
"size": 2048576,
"webViewLink": "https://drive.google.com/file/d/{id}/view",
"webContentLink": "https://drive.google.com/uc?id={id}&export=download",
"thumbnailLink": "https://drive.google.com/thumbnail?id={id}&sz=w400"
}
Upload file to Catbox.moe (CORS-friendly for web/avatars).
Delete file from Google Drive.
Deep Links
Handle shared content links
Web page handler for shared note links. Returns HTML with Open Graph meta tags and auto-redirects to app on mobile.
Deep Link Format: mrbunkmanager://note/{noteId}
Error Handling
Standard error response format
Error Response Format
{
"success": false,
"error": "Error message",
"details": "Technical details",
"timestamp": "26/11/2025, 03:30:45 PM"
}
HTTP Status Codes
| Code | Description |
|---|---|
| 200 | Success |
| 400 | Bad Request (validation error) |
| 404 | Not Found |
| 429 | Rate Limit Exceeded |
| 500 | Server Error |
Rate Limiting
Window: 15 minutes | Max Requests: 100 per window per IP
{
"error": "Too many requests",
"retryAfter": 900
}
OCR & Timetable Extraction
Image text extraction and AI parsing services
ocrService - OCR.space Integration
Extracts text from images using OCR (Optical Character Recognition). Supports JPG, PNG, GIF, WebP, BMP, TIFF formats.
extractTextFromImage(imageUri: string): Promise<OCRResult>
// Input types supported:
// - data:image/...;base64,... (Web & Native)
// - file:///path/to/image (Native only)
// - content://... (Android only)
// - https://... (Web & Native)
interface OCRResult {
success: boolean;
text: string; // Extracted text
error?: string; // Error message if failed
}
timetableParserService - AI Parsing
Parses OCR-extracted text into structured timetable entries using Groq AI (Llama 4 Maverick).
parseTimetableFromText(ocrText: string): Promise<ParseResult>
interface ParseResult {
success: boolean;
entries: TimetableEntry[]; // Parsed timetable entries
error?: string;
}
interface TimetableEntry {
id: string;
day: string; // Monday, Tuesday, etc.
subject: string;
subjectCode?: string;
startTime: string; // HH:MM format
endTime: string;
type?: string; // lecture, lab, tutorial
faculty?: string;
room?: string;
}
Frontend Services
Client-side service API reference
authService
signUp(email: string, password: string, displayName: string): Promise<User>
signIn(email: string, password: string): Promise<User>
signInWithGoogle(): Promise<User>
sendVerificationEmail(): Promise<void>
resetPassword(email: string): Promise<void>
signOut(): Promise<void>
getCurrentUser(): User | null
firestoreService
// User Profile
createUserProfile(uid: string, data: UserProfile): Promise<void>
getUserProfile(uid: string): Promise<UserProfile | null>
updateUserProfile(uid: string, data: Partial<UserProfile>): Promise<void>
// Timetable
saveTimetable(uid: string, entries: TimetableEntry[]): Promise<void>
getTimetable(uid: string): Promise<TimetableEntry[]>
// Subjects & Attendance
getSubjects(uid: string): Promise<Subject[]>
addSubject(uid: string, subject: Subject): Promise<void>
updateSubjectAttendance(uid: string, subjectId: string, attended: number, total: number): Promise<void>
notesService
createNote(authorId: string, data: CreateNoteInput): Promise<Note>
updateNote(noteId: string, data: Partial<Note>): Promise<void>
deleteNote(noteId: string, authorId: string): Promise<void>
getNoteWithContext(noteId: string, userId: string): Promise<FeedNote>
getFeedNotes(userId: string, followingIds: string[], lastDoc?: any): Promise<PaginatedResult<FeedNote>>
searchNotes(userId: string, query: string, filters?: NoteFilters): Promise<FeedNote[]>
groupsService
createGroup(name: string, description: string, category: string, isPrivate: boolean, userId: string, userName: string): Promise<Group>
joinGroup(groupId: string, userId: string, userName: string): Promise<void>
leaveGroup(groupId: string, userId: string): Promise<void>
sendMessage(groupId: string, userId: string, userName: string, photoURL: string | undefined, message: string): Promise<void>
subscribeToMessages(groupId: string, callback: (messages: GroupMessage[]) => void): Unsubscribe
socialService
likeNote(noteId: string, userId: string): Promise<void>
unlikeNote(noteId: string, userId: string): Promise<void>
toggleLike(noteId: string, userId: string): Promise<boolean>
addComment(noteId: string, comment: Omit<NoteComment, 'id' | 'createdAt'>): Promise<NoteComment>
saveNote(noteId: string, userId: string): Promise<void>
getSavedNotes(userId: string, lastDoc?: any): Promise<PaginatedResult<Note>>
followService
followUser(followerId: string, followingId: string): Promise<void>
unfollowUser(followerId: string, followingId: string): Promise<void>
getFollowing(userId: string): Promise<string[]>
getFollowers(userId: string): Promise<string[]>
isFollowing(followerId: string, followingId: string): Promise<boolean>
getSuggestedUsers(userId: string, college: string, course: string): Promise<PublicUserProfile[]>
Timezone: All timestamps are in Indian Standard Time (IST) - Asia/Kolkata
Format: DD/MM/YYYY, HH:MM:SS AM/PM