📚 API Documentation
0 endpoints
Admin Management 3 endpoints
GET
api/v1/admins
Returns list of admins from the same district (zila) as the authenticated user
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Admin list fetched successfully",
    "data": [
        {
            "id": 1,
            "name": "Admin User",
            "email": "admin@example.com",
            "phone_number": "01712345678",
            "date_of_birth": "1985-01-01",
            "gender": "male",
            "zila": {
                "id": 1,
                "name": "Dhaka",
                "bn_name": "\u09a2\u09be\u0995\u09be"
            },
            "upazila": {
                "id": 5,
                "name": "Dhanmondi",
                "bn_name": "\u09a7\u09be\u09a8\u09ae\u09a8\u09cd\u09a1\u09bf"
            },
            "admin": {
                "id": 1,
                "user_id": 1,
                "blood_group": "A+",
                "status": "active",
                "admin_profile_image": "admins/profile1.jpg",
                "image_url": "http://example.com/storage/admins/profile1.jpg"
            }
        },
        {
            "id": 2,
            "name": "Second Admin",
            "email": "admin2@example.com",
            "phone_number": "01812345678",
            "date_of_birth": "1988-05-15",
            "gender": "female",
            "zila": {
                "id": 1,
                "name": "Dhaka",
                "bn_name": "\u09a2\u09be\u0995\u09be"
            },
            "upazila": {
                "id": 6,
                "name": "Gulshan",
                "bn_name": "\u0997\u09c1\u09b2\u09b6\u09be\u09a8"
            },
            "admin": {
                "id": 2,
                "user_id": 2,
                "blood_group": "B+",
                "status": "active",
                "admin_profile_image": null,
                "image_url": null
            }
        }
    ]
}
POST
api/v1/admins
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
📦 Request Body Parameters
Field Name Type Validation Rules & Description
blood_group Optional String Allowed values: A+, A-, B+, B-, AB+, AB-, O+, O-
admin_profile_image Optional String max:2048 - image mimes:jpg,jpeg,png,webp
📄 JSON Request Example
{
    "blood_group": "nullable|string|in:A+,A-,B+,B-,AB+,AB-,O+,O-",
    "admin_profile_image": "nullable|image|mimes:jpg,jpeg,png,webp|max:2048"
}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 201,
    "message": "Admin created successfully",
    "data": {
        "user": {
            "id": 3,
            "name": "New Admin",
            "email": "newadmin@example.com",
            "phone_number": "01912345678",
            "zila": {
                "id": 1,
                "name": "Dhaka",
                "bn_name": "\u09a2\u09be\u0995\u09be"
            },
            "upazila": {
                "id": 5,
                "name": "Dhanmondi",
                "bn_name": "\u09a7\u09be\u09a8\u09ae\u09a8\u09cd\u09a1\u09bf"
            },
            "admin": {
                "id": 3,
                "user_id": 3,
                "blood_group": "O+",
                "status": "active",
                "admin_profile_image": "admins/profile3.jpg"
            }
        },
        "admin": {
            "id": 3,
            "user_id": 3,
            "blood_group": "O+",
            "status": "active",
            "admin_profile_image": "admins/profile3.jpg"
        },
        "image_url": "http://example.com/storage/admins/profile3.jpg"
    }
}
GET
api/v1/admins/{id}
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Admin details fetched successfully",
    "data": {
        "id": 1,
        "name": "Admin User",
        "email": "admin@example.com",
        "phone_number": "01712345678",
        "date_of_birth": "1985-01-01",
        "gender": "male",
        "zila": {
            "id": 1,
            "name": "Dhaka",
            "bn_name": "\u09a2\u09be\u0995\u09be"
        },
        "upazila": {
            "id": 5,
            "name": "Dhanmondi",
            "bn_name": "\u09a7\u09be\u09a8\u09ae\u09a8\u09cd\u09a1\u09bf"
        },
        "admin": {
            "id": 1,
            "user_id": 1,
            "blood_group": "A+",
            "status": "active",
            "admin_profile_image": "admins/profile1.jpg",
            "image_url": "http://example.com/storage/admins/profile1.jpg"
        }
    }
}
App Updates 4 endpoints
POST
api/v1/app/check-update
Check for app updates. Authenticated endpoint - uses user location (zila_id, upazila_id) for location-based updates. Returns update information based on user location, Android version, and device ABI. Supports location-based updates (upazila-specific > zila-specific > global), Android version targeting, and device architecture targeting. If device_abi is not sent, only global versions (null ABI) are returned.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
📦 Request Body Parameters
Field Name Type Validation Rules & Description
current_version_code Required Integer min:1 - Current app version code (build number)
platform Required String Allowed values: android, ios - Platform type
current_version Optional String optional Current app version name (e.g., "1.0.0")
android_version Optional Integer min:1, max:15 - optional Android OS version (e.g., 8, 9, 10, 11, 12, 13, 14, 15)
device_abi Optional String Allowed values: arm64-v8a, armeabi-v7a, x86 - optional Device ABI (Application Binary Interface). If provided, returns ABI-specific versions first, then global versions. If not provided, returns only global versions.
📄 JSON Request Example
{
    "current_version_code": "required|integer|min:1|Current app version code (build number)",
    "platform": "required|string|in:android,ios|Platform type",
    "current_version": "optional|string|Current app version name (e.g., \"1.0.0\")",
    "android_version": "optional|integer|min:1|max:15|Android OS version (e.g., 8, 9, 10, 11, 12, 13, 14, 15)",
    "device_abi": "optional|string|in:arm64-v8a,armeabi-v7a,x86|Device ABI (Application Binary Interface). If provided, returns ABI-specific versions first, then global versions. If not provided, returns only global versions."
}
✅ Success Response
📥 Response Example
{
    "success": true,
    "status": 200,
    "message": "Update check completed",
    "data": {
        "update_available": false,
        "current_version_code": 2,
        "current_version": "1.1.0"
    },
    "notes": [
        "If user is authenticated, the system uses their zila_id and upazila_id for location-based updates.",
        "Priority order: upazila-specific > zila-specific > global versions.",
        "If android_version is provided, only versions compatible with that Android OS version are returned.",
        "If device_abi is provided, ABI-specific versions are prioritized, then global versions (null ABI) as fallback.",
        "If device_abi is not provided, only global versions (null ABI) are returned.",
        "force_update is true when update_type is \"force\" and update is available."
    ]
}
GET
api/v1/app/versions
Get all app versions for a platform. Requires authentication. Returns all versions (active and inactive) ordered by version_code descending.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
🔍 Query Parameters
Parameter Name Type Validation Rules & Description
platform Optional String Allowed: android, ios, default:android - Filter by platform
✅ Success Response
📥 Response Example
{
    "success": true,
    "status": 200,
    "message": "App versions retrieved successfully",
    "data": [
        {
            "id": 1,
            "version": "1.1.0",
            "version_code": 2,
            "platform": "android",
            "download_url": "https://yoursite.com/apps/app-v1.1.0.apk",
            "update_type": "optional",
            "changelog": "Bug fixes",
            "release_notes": "Detailed notes...",
            "file_size": 15728640,
            "is_active": true,
            "zila_id": null,
            "upazila_id": null,
            "min_android_version": null,
            "max_android_version": null,
            "supported_android_versions": null,
            "device_abi": null,
            "created_at": "2025-11-12T10:00:00.000000Z",
            "updated_at": "2025-11-12T10:00:00.000000Z"
        },
        {
            "id": 2,
            "version": "1.0.0",
            "version_code": 1,
            "platform": "android",
            "download_url": "https://yoursite.com/apps/app-v1.0.0.apk",
            "update_type": "optional",
            "changelog": "Initial release",
            "release_notes": null,
            "file_size": 15000000,
            "is_active": false,
            "zila_id": 1,
            "upazila_id": 5,
            "min_android_version": 8,
            "max_android_version": 11,
            "supported_android_versions": [
                8,
                9,
                10,
                11
            ],
            "device_abi": "arm64-v8a",
            "created_at": "2025-11-01T08:00:00.000000Z",
            "updated_at": "2025-11-01T08:00:00.000000Z"
        }
    ]
}
POST
api/v1/app/versions
Create a new app version. Requires authentication (admin). Supports location-based targeting (zila/upazila/global), Android version targeting (min/max range or specific versions), and device ABI targeting. If supported_android_versions is provided, it overrides min/max_android_version. If device_abi is null, the version is global and works on all architectures. If device_abi is set, only devices with that ABI will receive this version (with fallback to global versions).
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
📦 Request Body Parameters
Field Name Type Validation Rules & Description
version Required String max:50 - Version name (e.g., "1.2.0")
version_code Required Integer min:1 - unique Version code (build number, must be unique per platform)
platform Required String Allowed values: android, ios - Platform type
download_url Required String url Public URL where APK/IPA can be downloaded
update_type Required String Allowed values: force, optional - Update type (force = mandatory, optional = user can skip)
changelog Optional String optional Brief summary of changes
release_notes Optional String optional Detailed release notes
file_size Optional Integer min:0 - optional File size in bytes
is_active Optional Boolean optional default:true Whether this version is active and available for updates
zila_id Optional Integer optional exists:zilas,id Target specific district (null = global)
upazila_id Optional Integer optional exists:upazilas,id Target specific upazila (null = global or zila-specific)
min_android_version Optional Integer min:1, max:15 - optional Minimum Android OS version (e.g., 8 for Android 8.0)
max_android_version Optional Integer min:1, max:15 - optional gte:min_android_version Maximum Android OS version
supported_android_versions Optional Array optional Specific Android versions supported (e.g., [8, 9, 11])
supported_android_versions.* Optional Integer min:1, max:15 - Each Android version in the array
device_abi Optional String Allowed values: arm64-v8a, armeabi-v7a, x86 - optional Device ABI targeting. Leave empty (null) for global version that works on all architectures. Set to specific ABI (arm64-v8a, armeabi-v7a, x86) to target specific device architectures.
📄 JSON Request Example
{
    "version": "required|string|max:50|Version name (e.g., \"1.2.0\")",
    "version_code": "required|integer|min:1|unique|Version code (build number, must be unique per platform)",
    "platform": "required|string|in:android,ios|Platform type",
    "download_url": "required|url|Public URL where APK/IPA can be downloaded",
    "update_type": "required|string|in:force,optional|Update type (force = mandatory, optional = user can skip)",
    "changelog": "optional|string|Brief summary of changes",
    "release_notes": "optional|string|Detailed release notes",
    "file_size": "optional|integer|min:0|File size in bytes",
    "is_active": "optional|boolean|default:true|Whether this version is active and available for updates",
    "zila_id": "optional|integer|exists:zilas,id|Target specific district (null = global)",
    "upazila_id": "optional|integer|exists:upazilas,id|Target specific upazila (null = global or zila-specific)",
    "min_android_version": "optional|integer|min:1|max:15|Minimum Android OS version (e.g., 8 for Android 8.0)",
    "max_android_version": "optional|integer|min:1|max:15|gte:min_android_version|Maximum Android OS version",
    "supported_android_versions": "optional|array|Specific Android versions supported (e.g., [8, 9, 11])",
    "supported_android_versions.*": "integer|min:1|max:15|Each Android version in the array",
    "device_abi": "optional|string|in:arm64-v8a,armeabi-v7a,x86|Device ABI targeting. Leave empty (null) for global version that works on all architectures. Set to specific ABI (arm64-v8a, armeabi-v7a, x86) to target specific device architectures."
}
✅ Success Response
📥 Response Example
{
    "success": true,
    "status": 201,
    "message": "App version created successfully",
    "data": {
        "id": 3,
        "version": "1.2.0",
        "version_code": 3,
        "platform": "android",
        "download_url": "https://yoursite.com/apps/app-v1.2.0.apk",
        "update_type": "force",
        "changelog": "Major security update",
        "release_notes": "This update includes critical security patches...",
        "file_size": 16200000,
        "is_active": true,
        "zila_id": null,
        "upazila_id": null,
        "min_android_version": null,
        "max_android_version": null,
        "supported_android_versions": null,
        "device_abi": null,
        "created_at": "2025-11-12T12:00:00.000000Z",
        "updated_at": "2025-11-12T12:00:00.000000Z"
    },
    "error_examples": {
        "validation_failed": {
            "success": false,
            "status": 422,
            "message": "Validation failed",
            "data": {
                "errors": {
                    "version_code": [
                        "The version code has already been taken for android platform."
                    ],
                    "download_url": [
                        "The download url must be a valid URL."
                    ]
                }
            }
        },
        "unauthenticated": {
            "success": false,
            "status": 401,
            "message": "Unauthenticated."
        }
    }
}
PUT
api/v1/app/versions/{id}
Update an existing app version. Requires authentication (admin). All fields are optional - only send the fields you want to update. Supports device ABI targeting: set to null for global version, or specific ABI (arm64-v8a, armeabi-v7a, x86) for architecture-specific versions.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
📦 Request Body Parameters
Field Name Type Validation Rules & Description
version Optional String max:50 - optional Version name
version_code Optional Integer min:1 - optional unique Version code (must be unique per platform)
platform Optional String Allowed values: android, ios - optional Platform type
download_url Optional String optional url Public URL where APK/IPA can be downloaded
update_type Optional String Allowed values: force, optional - optional Update type
changelog Optional String optional Brief summary of changes
release_notes Optional String optional Detailed release notes
file_size Optional Integer min:0 - optional File size in bytes
is_active Optional Boolean optional Whether this version is active
zila_id Optional Integer optional exists:zilas,id Target specific district
upazila_id Optional Integer optional exists:upazilas,id Target specific upazila
min_android_version Optional Integer min:1, max:15 - optional Minimum Android OS version
max_android_version Optional Integer min:1, max:15 - optional gte:min_android_version Maximum Android OS version
supported_android_versions Optional Array optional Specific Android versions supported
supported_android_versions.* Optional Integer min:1, max:15 - Each Android version in the array
device_abi Optional String Allowed values: arm64-v8a, armeabi-v7a, x86 - optional Device ABI targeting. Leave empty (null) for global version that works on all architectures.
📄 JSON Request Example
{
    "version": "optional|string|max:50|Version name",
    "version_code": "optional|integer|min:1|unique|Version code (must be unique per platform)",
    "platform": "optional|string|in:android,ios|Platform type",
    "download_url": "optional|url|Public URL where APK/IPA can be downloaded",
    "update_type": "optional|string|in:force,optional|Update type",
    "changelog": "optional|string|Brief summary of changes",
    "release_notes": "optional|string|Detailed release notes",
    "file_size": "optional|integer|min:0|File size in bytes",
    "is_active": "optional|boolean|Whether this version is active",
    "zila_id": "optional|integer|exists:zilas,id|Target specific district",
    "upazila_id": "optional|integer|exists:upazilas,id|Target specific upazila",
    "min_android_version": "optional|integer|min:1|max:15|Minimum Android OS version",
    "max_android_version": "optional|integer|min:1|max:15|gte:min_android_version|Maximum Android OS version",
    "supported_android_versions": "optional|array|Specific Android versions supported",
    "supported_android_versions.*": "integer|min:1|max:15|Each Android version in the array",
    "device_abi": "optional|string|in:arm64-v8a,armeabi-v7a,x86|Device ABI targeting. Leave empty (null) for global version that works on all architectures."
}
✅ Success Response
📥 Response Example
{
    "success": true,
    "status": 200,
    "message": "App version updated successfully",
    "data": {
        "id": 3,
        "version": "1.2.1",
        "version_code": 3,
        "platform": "android",
        "download_url": "https://yoursite.com/apps/app-v1.2.1.apk",
        "update_type": "force",
        "changelog": "Minor bug fixes",
        "release_notes": "Fixed critical bugs...",
        "file_size": 16250000,
        "is_active": true,
        "zila_id": 1,
        "upazila_id": 5,
        "min_android_version": 8,
        "max_android_version": 12,
        "supported_android_versions": [
            8,
            9,
            10,
            11,
            12
        ],
        "device_abi": "armeabi-v7a",
        "created_at": "2025-11-12T12:00:00.000000Z",
        "updated_at": "2025-11-12T14:30:00.000000Z"
    },
    "error_examples": {
        "not_found": {
            "success": false,
            "status": 404,
            "message": "No query results for model [Modules\\Genarel\\Models\\AppVersion] {id}"
        },
        "validation_failed": {
            "success": false,
            "status": 422,
            "message": "Validation failed",
            "data": {
                "errors": {
                    "max_android_version": [
                        "The max android version must be greater than or equal to min android version."
                    ]
                }
            }
        }
    }
}
Authentication 9 endpoints
POST
api/auth/forgot-password
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "OTP sent to your email",
    "data": null
}
POST
api/auth/login
Authenticate user and receive access token. Old tokens are automatically deleted. Device token is registered/updated if provided. Returns user data with roles, location, and role-specific data (donor/admin profile).
📦 Request Body Parameters
Field Name Type Validation Rules & Description
email Required Email User email address
password Required String min:8, max:255 - User password
device_token Optional String optional Device token for push notifications
📄 JSON Request Example
{
    "email": "required|email|User email address",
    "password": "required|string|min:8|max:255|User password",
    "device_token": "optional|string|Device token for push notifications"
}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Login successful",
    "data": {
        "access_token": "1|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "token_type": "Bearer",
        "user": {
            "id": 1,
            "name": "John Doe",
            "email": "john@example.com",
            "phone_number": "01712345678",
            "date_of_birth": "1990-01-01",
            "gender": "male",
            "roles": [
                "donor"
            ],
            "role": "donor",
            "location": {
                "zila": {
                    "id": 1,
                    "name": "Dhaka"
                },
                "upazila": {
                    "id": 2,
                    "name": "Dhanmondi"
                }
            },
            "donor": {
                "id": 1,
                "blood_group": "A+",
                "available": true,
                "last_donation_date": "2024-01-15",
                "total_donations": 5,
                "status": "approved",
                "profile_complete": "yes",
                "profile_image": "http://example.com/storage/donars/image.jpg"
            }
        }
    },
    "notes": [
        "For admin users, the response includes an \"admin\" object instead of \"donor\" object with fields: id, blood_group, status, profile_image.",
        "Location object is included only if user has zila_id or upazila_id assigned.",
        "Old tokens are automatically deleted when a new login occurs.",
        "Device token is registered/updated if provided in the request.",
        "profile_complete indicates whether the donor profile is complete (yes) or incomplete (no). It can be set manually via the profile update API."
    ],
    "error_examples": {
        "user_not_found": {
            "success": false,
            "code": 404,
            "message": "User not found with this email"
        },
        "incorrect_password": {
            "success": false,
            "code": 401,
            "message": "Incorrect password"
        },
        "validation_failed": {
            "success": false,
            "code": 422,
            "message": "Validation failed",
            "data": {
                "errors": {
                    "email": [
                        "The email field is required."
                    ],
                    "password": [
                        "The password must be at least 8 characters."
                    ]
                }
            }
        }
    }
}
POST
api/auth/otp-verify
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "OTP verified",
    "data": {
        "token": "short_lived_otp_token"
    }
}
POST
api/auth/reset-password
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Password reset successfully",
    "data": null
}
POST
api/v1/auth/logout
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Logged out successfully",
    "data": null
}
POST
api/v1/auth/update-password
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
📦 Request Body Parameters
Field Name Type Validation Rules & Description
currentPassword Optional String oldPassword123
newPassword Optional String newPassword123
confirmPassword Optional String newPassword123
📄 JSON Request Example
{
    "currentPassword": "oldPassword123",
    "newPassword": "newPassword123",
    "confirmPassword": "newPassword123"
}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Password updated successfully",
    "data": null
}
GET
api/v1/auth/user
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "User information retrieved successfully",
    "data": {
        "user": {
            "id": 1,
            "name": "Updated Name",
            "email": "newemail@example.com",
            "phone_number": "01812345678",
            "gender": "female",
            "date_of_birth": "1995-05-15",
            "zila": {
                "id": 2,
                "name": "Chattogram",
                "bn_name": "\u099a\u099f\u09cd\u099f\u0997\u09cd\u09b0\u09be\u09ae"
            },
            "upazila": {
                "id": 5,
                "name": "Patiya",
                "bn_name": "\u09aa\u099f\u09bf\u09af\u09bc\u09be"
            }
        }
    }
}
PUT
api/v1/auth/user/update
Legacy endpoint for basic user profile update. Recommended to use the unified profile API instead.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
📦 Request Body Parameters
Field Name Type Validation Rules & Description
name Optional String Updated Name
email Optional String newemail@example.com
phone_number Optional String 01812345678
zila_id Optional Integer Numeric value
upazila_id Optional Integer Numeric value
date_of_birth Optional String 1995-05-15
gender Optional String female
📄 JSON Request Example
{
    "name": "Updated Name",
    "email": "newemail@example.com",
    "phone_number": "01812345678",
    "zila_id": 2,
    "upazila_id": 5,
    "date_of_birth": "1995-05-15",
    "gender": "female"
}
GET
api/v1/auth/users/by-upazila
Get all users belonging to the same upazila as the authenticated user. Includes donor and admin status, roles, and images.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
🔍 Query Parameters
Parameter Name Type Validation Rules & Description
per_page Optional Integer default:20 - Number of items per page. Use -1 to return all records.
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Users retrieved successfully",
    "data": {
        "current_page": 1,
        "per_page": 20,
        "total": 50,
        "data": [
            {
                "id": 1,
                "name": "John Doe",
                "email": "john@example.com",
                "phone_number": "01712345678",
                "gender": "male",
                "date_of_birth": "1990-01-01",
                "roles": [
                    "donor"
                ],
                "zila": {
                    "id": 1,
                    "name": "Dhaka",
                    "bn_name": "\u09a2\u09be\u0995\u09be"
                },
                "upazila": {
                    "id": 5,
                    "name": "Dhanmondi",
                    "bn_name": "\u09a7\u09be\u09a8\u09ae\u09a8\u09cd\u09a1\u09bf"
                },
                "donor": {
                    "id": 1,
                    "blood_group": "A+",
                    "available": true,
                    "status": "approved"
                },
                "images": [
                    {
                        "id": 1,
                        "type": "profile",
                        "url": "http://example.com/storage/users/profile1.jpg"
                    }
                ],
                "created_at": "2024-01-01T00:00:00.000000Z"
            }
        ]
    }
}
Blood Requests 5 endpoints
POST
api/v1/blood-requests
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
📦 Request Body Parameters
Field Name Type Validation Rules & Description
patient_name Optional String John Doe
blood_group_needed Optional String A+
units_needed Optional Integer Numeric value
urgency Optional String High
hospital_name Optional String Dhaka Medical College
hospital_address Optional String Dhaka, Bangladesh
contact_name Optional String Jane Doe
contact_phone Optional String 017XXXXXXXX
contact_email Optional String jane@example.com
medical_reason Optional String Surgery
required_by Optional String 2025-10-25
zila_id Optional Integer Numeric value
upazila_id Optional Integer Numeric value
📄 JSON Request Example
{
    "patient_name": "John Doe",
    "blood_group_needed": "A+",
    "units_needed": 2,
    "urgency": "High",
    "hospital_name": "Dhaka Medical College",
    "hospital_address": "Dhaka, Bangladesh",
    "contact_name": "Jane Doe",
    "contact_phone": "017XXXXXXXX",
    "contact_email": "jane@example.com",
    "medical_reason": "Surgery",
    "required_by": "2025-10-25",
    "zila_id": 1,
    "upazila_id": 5
}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 201,
    "message": "Blood request created successfully",
    "data": {
        "id": 1,
        "patient_name": "John Doe",
        "blood_group_needed": "A+",
        "units_needed": 2,
        "urgency": "High",
        "hospital_name": "Dhaka Medical College",
        "hospital_address": "Dhaka, Bangladesh",
        "contact_name": "Jane Doe",
        "contact_phone": "017XXXXXXXX",
        "contact_email": "jane@example.com",
        "medical_reason": "Surgery",
        "required_by": "2025-10-25",
        "status": "pending",
        "zila": {
            "id": 1,
            "name": "Dhaka",
            "bn_name": "\u09a2\u09be\u0995\u09be"
        },
        "upazila": {
            "id": 5,
            "zila_id": 1,
            "name": "Dhanmondi",
            "bn_name": "\u09a7\u09be\u09a8\u09ae\u09a8\u09cd\u09a1\u09bf"
        },
        "created_at": "2025-10-22T09:00:00.000000Z"
    }
}
GET
api/v1/blood-requests
Returns paginated list of blood requests. Shows: 1) Requests created by the authenticated user, 2) Requests where upazila_id matches user's upazila_id, 3) Requests where forward_to (JSON array) contains user's upazila_id. Results are sorted by most recent first.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
🔍 Query Parameters
Parameter Name Type Validation Rules & Description
page Optional Integer default:1 - Page number
per_page Optional Integer default:15, max:100 - Number of items per page
✅ Success Response
📥 Response Example
{
    "success": true,
    "hasError": false,
    "status": 200,
    "message": "Blood requests fetched successfully",
    "data": {
        "current_page": 1,
        "per_page": 15,
        "total": 50,
        "last_page": 4,
        "from": 1,
        "to": 15,
        "next_page_url": "http://example.com/api/v1/blood-requests?page=2",
        "prev_page_url": null,
        "data": [
            {
                "id": 1,
                "patient_name": "John Doe",
                "blood_group_needed": "A+",
                "units_needed": 2,
                "urgency": "High",
                "hospital_name": "Dhaka Medical College",
                "hospital_address": "Dhaka, Bangladesh",
                "contact_name": "Jane Doe",
                "contact_phone": "017XXXXXXXX",
                "contact_email": "jane@example.com",
                "medical_reason": "Surgery",
                "required_by": "2025-10-25",
                "status": "approved",
                "forward_to": [
                    1,
                    2,
                    3
                ],
                "user": {
                    "id": 1,
                    "name": "John Doe",
                    "email": "john@example.com"
                },
                "zila": {
                    "id": 1,
                    "name": "Dhaka",
                    "bn_name": "\u09a2\u09be\u0995\u09be"
                },
                "upazila": {
                    "id": 5,
                    "zila_id": 1,
                    "name": "Dhanmondi",
                    "bn_name": "\u09a7\u09be\u09a8\u09ae\u09a8\u09cd\u09a1\u09bf"
                },
                "created_at": "2025-10-22T09:00:00.000000Z"
            },
            {
                "id": 2,
                "patient_name": "Alice Smith",
                "blood_group_needed": "B-",
                "units_needed": 1,
                "urgency": "Medium",
                "hospital_name": "Chittagong Hospital",
                "hospital_address": "Chattogram, Bangladesh",
                "contact_name": "Bob Smith",
                "contact_phone": "018XXXXXXXX",
                "contact_email": "bob@example.com",
                "medical_reason": null,
                "required_by": "2025-10-27",
                "status": "approved",
                "user": {
                    "id": 2,
                    "name": "Alice Smith",
                    "email": "alice@example.com"
                },
                "zila": {
                    "id": 2,
                    "name": "Chattogram",
                    "bn_name": "\u099a\u099f\u09cd\u099f\u0997\u09cd\u09b0\u09be\u09ae"
                },
                "upazila": {
                    "id": 12,
                    "zila_id": 2,
                    "name": "Patiya",
                    "bn_name": "\u09aa\u099f\u09bf\u09af\u09bc\u09be"
                },
                "created_at": "2025-10-22T10:00:00.000000Z"
            }
        ]
    }
}
GET
api/v1/blood-requests/by-status
Returns paginated list of blood requests filtered by status. Only accessible by admins and donors. Admins see all requests, donors see only requests from their location (upazila or zila).
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
🔍 Query Parameters
Parameter Name Type Validation Rules & Description
status Required String Allowed: pending, approved, rejected, in_progress, fulfilled - Filter by request status
per_page Optional Integer min:1, max:100, default:15 - Number of items per page
✅ Success Response
📥 Response Example
{
    "success": true,
    "hasError": false,
    "status": 200,
    "message": "Blood requests fetched successfully",
    "data": {
        "current_page": 1,
        "per_page": 15,
        "total": 30,
        "last_page": 2,
        "from": 1,
        "to": 15,
        "next_page_url": "http://example.com/api/v1/blood-requests/by-status?status=in_progress&page=2",
        "prev_page_url": null,
        "data": [
            {
                "id": 1,
                "patient_name": "John Doe",
                "blood_group_needed": "A+",
                "units_needed": 2,
                "urgency": "High",
                "hospital_name": "Dhaka Medical College",
                "hospital_address": "Dhaka, Bangladesh",
                "contact_name": "Jane Doe",
                "contact_phone": "017XXXXXXXX",
                "contact_email": "jane@example.com",
                "medical_reason": "Surgery",
                "required_by": "2025-10-25",
                "status": "in_progress",
                "user": {
                    "id": 1,
                    "name": "John Doe",
                    "email": "john@example.com"
                },
                "zila": {
                    "id": 1,
                    "name": "Dhaka",
                    "bn_name": "\u09a2\u09be\u0995\u09be"
                },
                "upazila": {
                    "id": 5,
                    "zila_id": 1,
                    "name": "Dhanmondi",
                    "bn_name": "\u09a7\u09be\u09a8\u09ae\u09a8\u09cd\u09a1\u09bf"
                },
                "donations": [
                    {
                        "id": 1,
                        "donar_id": 1,
                        "blood_request_id": 1,
                        "donation_date": "2025-10-24",
                        "status": "pending",
                        "location": "Dhaka Medical College",
                        "hospital_name": "Dhaka Medical College",
                        "recipient_name": "John Doe",
                        "notes": null
                    }
                ],
                "created_at": "2025-10-22T09:00:00.000000Z"
            },
            {
                "id": 2,
                "patient_name": "Alice Smith",
                "blood_group_needed": "B-",
                "units_needed": 1,
                "urgency": "Medium",
                "hospital_name": "Chittagong Hospital",
                "hospital_address": "Chattogram, Bangladesh",
                "contact_name": "Bob Smith",
                "contact_phone": "018XXXXXXXX",
                "contact_email": "bob@example.com",
                "medical_reason": null,
                "required_by": "2025-10-27",
                "status": "in_progress",
                "user": {
                    "id": 2,
                    "name": "Alice Smith",
                    "email": "alice@example.com"
                },
                "zila": {
                    "id": 2,
                    "name": "Chattogram",
                    "bn_name": "\u099a\u099f\u09cd\u099f\u0997\u09cd\u09b0\u09be\u09ae"
                },
                "upazila": {
                    "id": 12,
                    "zila_id": 2,
                    "name": "Patiya",
                    "bn_name": "\u09aa\u099f\u09bf\u09af\u09bc\u09be"
                },
                "donations": [],
                "created_at": "2025-10-22T10:00:00.000000Z"
            }
        ]
    }
}
POST
api/v1/blood-requests/{id}/forward
Forward a blood request to one or more upazilas. Only admins and super-admins can forward requests. The forward_to field will be updated with the provided upazila IDs (merged with existing ones to avoid duplicates). Admins in the newly forwarded upazilas will receive notifications. Users in those upazilas will see the request in their list.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
📦 Request Body Parameters
Field Name Type Validation Rules & Description
upazila_ids Required Array min:1 - Array of upazila IDs to forward the blood request to
upazila_ids.* Required Integer exists:upazilas,id Each upazila ID must exist in the database
📄 JSON Request Example
{
    "upazila_ids": "required|array|min:1|Array of upazila IDs to forward the blood request to",
    "upazila_ids.*": "required|integer|exists:upazilas,id|Each upazila ID must exist in the database"
}
✅ Success Response
📥 Response Example
{
    "success": true,
    "status": 200,
    "message": "Blood request forwarded successfully",
    "data": {
        "blood_request": {
            "id": 1,
            "patient_name": "John Doe",
            "blood_group_needed": "A+",
            "units_needed": 2,
            "urgency": "urgent",
            "status": "approved",
            "forward_to": [
                1,
                2,
                3
            ],
            "user": {
                "id": 5,
                "name": "Request Creator",
                "phone_number": "01712345678"
            },
            "zila": {
                "id": 1,
                "name": "Dhaka"
            },
            "upazila": {
                "id": 2,
                "name": "Dhanmondi"
            }
        },
        "forwarded_to": [
            1,
            2,
            3
        ],
        "new_upazilas": [
            1,
            2,
            3
        ]
    },
    "error_examples": {
        "access_denied": {
            "success": false,
            "status": 403,
            "message": "Access denied. Only admins can forward blood requests."
        },
        "validation_failed": {
            "success": false,
            "status": 422,
            "message": "Validation failed",
            "data": {
                "errors": {
                    "upazila_ids": [
                        "The upazila ids field is required."
                    ],
                    "upazila_ids.0": [
                        "The selected upazila ids.0 is invalid."
                    ]
                }
            }
        },
        "not_found": {
            "success": false,
            "status": 404,
            "message": "No query results for model [Modules\\Genarel\\Models\\BloodRequest] {id}"
        }
    }
}
PUT
api/v1/blood-requests/{id}/status
Update blood request status. Normal users cannot update status. Other roles (admin, etc.) can update status.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
📦 Request Body Parameters
Field Name Type Validation Rules & Description
status Required String Allowed values: pending, approved, fulfilled, cancelled
📄 JSON Request Example
{
    "status": "required|string|in:pending,approved,fulfilled,cancelled"
}
✅ Success Response
📥 Response Example
{
    "success": true,
    "hasError": false,
    "status": 200,
    "message": "Blood request status updated successfully",
    "data": {
        "id": 1,
        "patient_name": "John Doe",
        "blood_group_needed": "A+"
    }
}
Donation 8 endpoints
POST
api/v1/donations
Create a donation and fulfill a blood request. Admins can create donations for any donor by specifying donar_id, or for themselves if they have a donor profile. Regular users can only create donations for themselves using their own donor profile ID. Blood group must match between donor and request. If donation status is "completed", the blood request will be marked as "fulfilled" and donor stats will be updated. Note: Admin users without a donor profile must specify a donar_id. Image field is optional and accepts jpg, jpeg, png, or webp formats with max size of 2MB.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
📦 Request Body Parameters
Field Name Type Validation Rules & Description
blood_request_id Required String exists:blood_requests,id The ID of the blood request to fulfill
donation_date Required Date The date of the donation
donar_id Optional String exists:donars,id Admin can specify which donor. Regular users must use their own donor profile ID.
status Required String Allowed values: pending, processing, completed, cancelled - The status of the donation
location Required String max:255 - Donation location address
hospital_name Required String max:255 - Hospital name where donation will take place
notes Optional String Additional notes about the donation
image Optional String max:2048 - image mimes:jpg,jpeg,png,webp Donation image (optional)
📄 JSON Request Example
{
    "blood_request_id": "required|exists:blood_requests,id|The ID of the blood request to fulfill",
    "donation_date": "required|date|The date of the donation",
    "donar_id": "nullable|exists:donars,id|Admin can specify which donor. Regular users must use their own donor profile ID.",
    "status": "required|string|in:pending,processing,completed,cancelled|The status of the donation",
    "location": "required|string|max:255|Donation location address",
    "hospital_name": "required|string|max:255|Hospital name where donation will take place",
    "notes": "nullable|string|Additional notes about the donation",
    "image": "nullable|image|mimes:jpg,jpeg,png,webp|max:2048|Donation image (optional)"
}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 201,
    "message": "Donation created successfully",
    "data": {
        "donation": {
            "id": 1,
            "donar_id": 1,
            "blood_request_id": 1,
            "donation_date": "2025-10-25",
            "status": "pending",
            "location": "Dhaka Medical College",
            "hospital_name": "Dhaka Medical College",
            "recipient_name": "John Doe",
            "notes": null,
            "image": "donations/donation_image.jpg",
            "created_at": "2025-10-22T10:00:00.000000Z",
            "updated_at": "2025-10-22T10:00:00.000000Z",
            "donar": {
                "id": 1,
                "user_id": 1,
                "blood_group": "A+",
                "available": true,
                "last_donation_date": null,
                "total_donations": 0,
                "status": "approved"
            }
        },
        "blood_request": {
            "id": 1,
            "patient_name": "John Doe",
            "blood_group_needed": "A+",
            "units_needed": 2,
            "urgency": "High",
            "hospital_name": "Dhaka Medical College",
            "status": "in_progress",
            "created_at": "2025-10-22T09:00:00.000000Z"
        },
        "donar": {
            "id": 1,
            "user_id": 1,
            "blood_group": "A+",
            "available": true,
            "last_donation_date": null,
            "total_donations": 0,
            "status": "approved"
        },
        "image_url": "http://example.com/storage/donations/donation_image.jpg"
    }
}
GET
api/v1/donations/by-status
Get donations filtered by status. Admins see all donations from their upazila (filtered by status if provided). Donors see only their own donations (filtered by status if provided). Only admins and donors can access this endpoint.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
🔍 Query Parameters
Parameter Name Type Validation Rules & Description
status Optional String Allowed: pending, processing, completed, cancelled - Filter donations by status. If not provided, returns all donations.
page Optional Integer min:1, default:1 - Page number for pagination
per_page Optional Integer min:1, max:100, default:15 - Number of items per page
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Donations fetched successfully",
    "data": {
        "current_page": 1,
        "per_page": 15,
        "total": 25,
        "last_page": 2,
        "from": 1,
        "to": 15,
        "next_page_url": "http://example.com/api/v1/donations/by-status?status=pending&page=2",
        "prev_page_url": null,
        "data": [
            {
                "id": 1,
                "donar_id": 1,
                "blood_request_id": 1,
                "donation_date": "2025-10-25",
                "status": "pending",
                "location": "Dhaka Medical College",
                "hospital_name": "Dhaka Medical College",
                "recipient_name": "John Doe",
                "notes": null,
                "image": "donations/donation_image1.jpg",
                "image_url": "http://example.com/storage/donations/donation_image1.jpg",
                "created_at": "2025-10-22T10:00:00.000000Z",
                "updated_at": "2025-10-22T10:00:00.000000Z",
                "donar": {
                    "id": 1,
                    "user_id": 1,
                    "blood_group": "A+",
                    "available": true,
                    "last_donation_date": null,
                    "total_donations": 0,
                    "status": "approved",
                    "image_url": "http://example.com/storage/donars/profile1.jpg",
                    "user_info": {
                        "id": 1,
                        "name": "John Doe",
                        "email": "john@example.com",
                        "phone_number": "01712345678"
                    }
                },
                "bloodRequest": {
                    "id": 1,
                    "patient_name": "John Doe",
                    "blood_group_needed": "A+",
                    "units_needed": 2,
                    "urgency": "High",
                    "hospital_name": "Dhaka Medical College",
                    "status": "in_progress",
                    "created_at": "2025-10-22T09:00:00.000000Z"
                }
            },
            {
                "id": 2,
                "donar_id": 2,
                "blood_request_id": 2,
                "donation_date": "2025-10-26",
                "status": "processing",
                "location": "Chittagong Hospital",
                "hospital_name": "Chittagong Hospital",
                "recipient_name": "Alice Smith",
                "notes": "Urgent donation",
                "image": null,
                "image_url": null,
                "created_at": "2025-10-23T08:00:00.000000Z",
                "updated_at": "2025-10-23T09:00:00.000000Z",
                "donar": {
                    "id": 2,
                    "user_id": 2,
                    "blood_group": "B+",
                    "available": true,
                    "last_donation_date": "2025-09-15",
                    "total_donations": 3,
                    "status": "approved",
                    "image_url": null,
                    "user_info": {
                        "id": 2,
                        "name": "Jane Smith",
                        "email": "jane@example.com",
                        "phone_number": "01812345678"
                    }
                },
                "bloodRequest": {
                    "id": 2,
                    "patient_name": "Alice Smith",
                    "blood_group_needed": "B+",
                    "units_needed": 1,
                    "urgency": "Medium",
                    "hospital_name": "Chittagong Hospital",
                    "status": "in_progress",
                    "created_at": "2025-10-23T07:00:00.000000Z"
                }
            }
        ]
    }
}
POST
api/v1/donations/{id}
Update donation details including image. Admins can update any donation. Donors can update their own donations. All fields are optional - only send the fields you want to update. If image is provided, the old image will be automatically deleted. If status is updated to "completed", the blood request will be marked as "fulfilled" and donor stats will be updated. If status is changed from "completed" to something else, donor stats will be decremented.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
📦 Request Body Parameters
Field Name Type Validation Rules & Description
donation_date Optional Date optional The date of the donation
location Optional String max:255 - optional Donation location address
hospital_name Optional String max:255 - optional Hospital name where donation took place
notes Optional String optional Additional notes about the donation
status Optional String Allowed values: pending, processing, completed, cancelled - optional The status of the donation
image Optional String max:2048 - optional image mimes:jpg,jpeg,png,webp Donation image (optional). If provided, old image will be deleted and replaced with new one.
📄 JSON Request Example
{
    "donation_date": "optional|date|The date of the donation",
    "location": "optional|string|max:255|Donation location address",
    "hospital_name": "optional|string|max:255|Hospital name where donation took place",
    "notes": "optional|string|Additional notes about the donation",
    "status": "optional|string|in:pending,processing,completed,cancelled|The status of the donation",
    "image": "optional|image|mimes:jpg,jpeg,png,webp|max:2048|Donation image (optional). If provided, old image will be deleted and replaced with new one."
}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Donation updated successfully",
    "data": {
        "donation": {
            "id": 1,
            "donar_id": 1,
            "blood_request_id": 1,
            "donation_date": "2025-10-25",
            "status": "completed",
            "location": "Updated Location",
            "hospital_name": "Updated Hospital Name",
            "notes": "Updated notes about the donation",
            "image": "donations/updated_donation_image.jpg",
            "created_at": "2025-10-22T10:00:00.000000Z",
            "updated_at": "2025-10-22T12:00:00.000000Z",
            "donar": {
                "id": 1,
                "user_id": 1,
                "blood_group": "A+",
                "available": true,
                "last_donation_date": "2025-10-25",
                "total_donations": 1,
                "status": "approved",
                "user": {
                    "id": 1,
                    "name": "John Doe",
                    "email": "john@example.com",
                    "phone_number": "01712345678"
                }
            },
            "bloodRequest": {
                "id": 1,
                "patient_name": "John Doe",
                "blood_group_needed": "A+",
                "units_needed": 2,
                "urgency": "High",
                "hospital_name": "Dhaka Medical College",
                "status": "fulfilled",
                "created_at": "2025-10-22T09:00:00.000000Z"
            }
        },
        "image_url": "http://example.com/storage/donations/updated_donation_image.jpg"
    }
}
POST
api/v1/donations/{id}/comment
Add a comment to a donation. Anyone can comment on donations. Maximum comment length is 1000 characters. Returns the updated comments count.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
📦 Request Body Parameters
Field Name Type Validation Rules & Description
comment Required String max:1000 - Comment text
📄 JSON Request Example
{
    "comment": "required|string|max:1000|Comment text"
}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 201,
    "message": "Comment added successfully",
    "data": {
        "id": 1,
        "user_id": 2,
        "user_name": "Jane Smith",
        "comment": "Great work! Thank you for saving a life.",
        "created_at": "2025-10-22T11:10:00.000000Z",
        "comments_count": 5
    }
}
GET
api/v1/donations/{id}/comments
Get all comments for a specific donation. Comments are returned in reverse chronological order (newest first).
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
🔍 Query Parameters
Parameter Name Type Validation Rules & Description
page Optional Integer min:1, default:1 - Page number for pagination
per_page Optional Integer min:1, max:100, default:20 - Number of items per page
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Comments fetched successfully",
    "data": {
        "current_page": 1,
        "per_page": 20,
        "total": 15,
        "last_page": 1,
        "from": 1,
        "to": 15,
        "next_page_url": null,
        "prev_page_url": null,
        "data": [
            {
                "id": 15,
                "user_id": 5,
                "user_name": "Bob Wilson",
                "comment": "Latest comment",
                "created_at": "2025-10-22T12:00:00.000000Z"
            },
            {
                "id": 14,
                "user_id": 4,
                "user_name": "Charlie Brown",
                "comment": "Amazing contribution!",
                "created_at": "2025-10-22T11:50:00.000000Z"
            },
            {
                "id": 1,
                "user_id": 2,
                "user_name": "Jane Smith",
                "comment": "Great work! Thank you for saving a life.",
                "created_at": "2025-10-22T11:10:00.000000Z"
            }
        ]
    }
}
POST
api/v1/donations/{id}/like
Like or react to a donation. If user already reacted with the same reaction, it will be removed (unlike). If user reacted with a different reaction, it will be updated. Anyone can like/react to donations. Returns the updated likes count.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
📦 Request Body Parameters
Field Name Type Validation Rules & Description
reaction Optional String Allowed values: like, love, celebrate, support - optional default:like Type of reaction
📄 JSON Request Example
{
    "reaction": "optional|string|in:like,love,celebrate,support|default:like|Type of reaction"
}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 201,
    "message": "Reaction added successfully",
    "data": {
        "liked": true,
        "reaction": "like",
        "likes_count": 15
    },
    "notes": [
        "If user already reacted with the same reaction, the response will have code 200 with message \"Reaction removed successfully\" and liked: false.",
        "If user reacted with a different reaction, the response will have code 200 with message \"Reaction updated successfully\" and the new reaction type.",
        "Response always includes the updated likes_count."
    ]
}
GET
api/v1/donations/{id}/likes
Get all likes/reactions for a specific donation. Likes are returned in reverse chronological order (newest first).
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
🔍 Query Parameters
Parameter Name Type Validation Rules & Description
page Optional Integer min:1, default:1 - Page number for pagination
per_page Optional Integer min:1, max:100, default:20 - Number of items per page
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Likes fetched successfully",
    "data": {
        "current_page": 1,
        "per_page": 20,
        "total": 15,
        "last_page": 1,
        "from": 1,
        "to": 15,
        "next_page_url": null,
        "prev_page_url": null,
        "data": [
            {
                "id": 15,
                "user_id": 5,
                "user_name": "Bob Wilson",
                "reaction": "love",
                "created_at": "2025-10-22T12:00:00.000000Z"
            },
            {
                "id": 14,
                "user_id": 4,
                "user_name": "Charlie Brown",
                "reaction": "like",
                "created_at": "2025-10-22T11:50:00.000000Z"
            },
            {
                "id": 1,
                "user_id": 2,
                "user_name": "Jane Smith",
                "reaction": "like",
                "created_at": "2025-10-22T11:10:00.000000Z"
            }
        ]
    }
}
PUT
api/v1/donations/{id}/status
Update donation status. Admins can update any donation status. Donors can update their own donation status. When status is changed to "completed", the blood request will be marked as "fulfilled" and donor stats will be updated automatically. If status is changed from "completed" to something else, donor stats will be decremented.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
📦 Request Body Parameters
Field Name Type Validation Rules & Description
status Required String Allowed values: pending, processing, completed, cancelled - The new status for the donation
📄 JSON Request Example
{
    "status": "required|string|in:pending,processing,completed,cancelled|The new status for the donation"
}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Donation status updated successfully",
    "data": {
        "donation": {
            "id": 1,
            "donar_id": 1,
            "blood_request_id": 1,
            "donation_date": "2025-10-25",
            "status": "completed",
            "location": "Dhaka Medical College",
            "hospital_name": "Dhaka Medical College",
            "recipient_name": "John Doe",
            "notes": null,
            "image": "donations/donation_image.jpg",
            "created_at": "2025-10-22T10:00:00.000000Z",
            "updated_at": "2025-10-22T11:00:00.000000Z",
            "donar": {
                "id": 1,
                "user_id": 1,
                "blood_group": "A+",
                "available": true,
                "last_donation_date": "2025-10-25",
                "total_donations": 1,
                "status": "approved"
            },
            "bloodRequest": {
                "id": 1,
                "patient_name": "John Doe",
                "blood_group_needed": "A+",
                "units_needed": 2,
                "urgency": "High",
                "hospital_name": "Dhaka Medical College",
                "status": "fulfilled",
                "created_at": "2025-10-22T09:00:00.000000Z"
            }
        },
        "blood_request": {
            "id": 1,
            "patient_name": "John Doe",
            "blood_group_needed": "A+",
            "units_needed": 2,
            "urgency": "High",
            "hospital_name": "Dhaka Medical College",
            "status": "fulfilled",
            "created_at": "2025-10-22T09:00:00.000000Z"
        }
    }
}
Donors 7 endpoints
GET
api/v1/donar
Returns list of donors. Regular users see donors from the same district (zila) as the authenticated user. Admin users see donors from the same upazila as the authenticated user. If page is set to -1, returns all matching donors without pagination. Admin users must have upazila_id assigned.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
🔍 Query Parameters
Parameter Name Type Validation Rules & Description
page Optional Integer default:1 - Page number. Use -1 to get all donors without pagination
per_page Optional Integer default:15, max:100 - Number of items per page (ignored if page=-1)
✅ Success Response
📥 Response Example
{
    "success": true,
    "hasError": false,
    "status": 200,
    "message": "Donor list fetched successfully",
    "data": {
        "current_page": 1,
        "per_page": 15,
        "total": 45,
        "last_page": 3,
        "from": 1,
        "to": 15,
        "next_page_url": "http://example.com/api/v1/donar?page=2",
        "prev_page_url": null,
        "data": [
            {
                "id": 1,
                "name": "John Doe",
                "email": "john@example.com",
                "phone_number": "01712345678",
                "date_of_birth": "1990-01-01",
                "gender": "male",
                "zila": {
                    "id": 1,
                    "name": "Dhaka",
                    "bn_name": "\u09a2\u09be\u0995\u09be"
                },
                "upazila": {
                    "id": 5,
                    "name": "Dhanmondi",
                    "bn_name": "\u09a7\u09be\u09a8\u09ae\u09a8\u09cd\u09a1\u09bf"
                },
                "donar": {
                    "id": 1,
                    "user_id": 1,
                    "blood_group": "A+",
                    "available": true,
                    "last_donation_date": "2025-09-15",
                    "total_donations": 5,
                    "donar_profile_image": "donars/profile1.jpg",
                    "image_url": "http://example.com/storage/donars/profile1.jpg"
                }
            },
            {
                "id": 2,
                "name": "Jane Smith",
                "email": "jane@example.com",
                "phone_number": "01812345678",
                "date_of_birth": "1992-05-20",
                "gender": "female",
                "zila": {
                    "id": 1,
                    "name": "Dhaka",
                    "bn_name": "\u09a2\u09be\u0995\u09be"
                },
                "upazila": {
                    "id": 6,
                    "name": "Gulshan",
                    "bn_name": "\u0997\u09c1\u09b2\u09b6\u09be\u09a8"
                },
                "donar": {
                    "id": 2,
                    "user_id": 2,
                    "blood_group": "B+",
                    "available": true,
                    "last_donation_date": null,
                    "total_donations": 0,
                    "donar_profile_image": null,
                    "image_url": null
                }
            }
        ]
    }
}
POST
api/v1/donar
Create or register the authenticated user as a donor. If email is provided, it will be updated for the user. The user's is_donar_request field will be set to "yes". If blood_request_id is provided, the donor will be marked as a temporary donor (is_temporary_donor will be set to "yes"), otherwise it will be set to "no". Response includes is_temporary_donor field which contains the blood_request_id if provided, or empty string if not.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
📦 Request Body Parameters
Field Name Type Validation Rules & Description
blood_group Required String Allowed values: A+, A-, B+, B-, AB+, AB-, O+, O- - Blood group
last_donated_at Optional Date optional Last donation date
is_available Optional Boolean optional Donor availability status
donar_profile_image Optional String max:2048 - optional image mimes:jpg,jpeg,png,webp Donor profile image
email Required Email unique User email address (will update user email if provided)
blood_request_id Optional String optional exists:blood_requests,id If provided, the donor will be marked as a temporary donor (is_temporary_donor = "yes")
📄 JSON Request Example
{
    "blood_group": "required|string|in:A+,A-,B+,B-,AB+,AB-,O+,O-|Blood group",
    "last_donated_at": "optional|date|Last donation date",
    "is_available": "optional|boolean|Donor availability status",
    "donar_profile_image": "optional|image|mimes:jpg,jpeg,png,webp|max:2048|Donor profile image",
    "email": "required|email|unique|User email address (will update user email if provided)",
    "blood_request_id": "optional|exists:blood_requests,id|If provided, the donor will be marked as a temporary donor (is_temporary_donor = \"yes\")"
}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 201,
    "message": "Donor created successfully",
    "data": {
        "user": {
            "id": 3,
            "name": "Alice Johnson",
            "email": "alice@example.com",
            "phone_number": "01912345678",
            "zila": {
                "id": 1,
                "name": "Dhaka",
                "bn_name": "\u09a2\u09be\u0995\u09be"
            },
            "upazila": {
                "id": 5,
                "name": "Dhanmondi",
                "bn_name": "\u09a7\u09be\u09a8\u09ae\u09a8\u09cd\u09a1\u09bf"
            }
        },
        "donar": {
            "id": 3,
            "user_id": 3,
            "blood_group": "O+",
            "available": true,
            "last_donation_date": "2025-08-10",
            "total_donations": 0,
            "donar_profile_image": "donars/profile3.jpg"
        },
        "image_url": "http://example.com/storage/donars/profile3.jpg"
    }
}
GET
api/v1/donar/{id}
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Donor details fetched successfully",
    "data": {
        "id": 1,
        "name": "John Doe",
        "email": "john@example.com",
        "phone_number": "01712345678",
        "date_of_birth": "1990-01-01",
        "gender": "male",
        "zila": {
            "id": 1,
            "name": "Dhaka",
            "bn_name": "\u09a2\u09be\u0995\u09be"
        },
        "upazila": {
            "id": 5,
            "name": "Dhanmondi",
            "bn_name": "\u09a7\u09be\u09a8\u09ae\u09a8\u09cd\u09a1\u09bf"
        },
        "donar": {
            "id": 1,
            "user_id": 1,
            "blood_group": "A+",
            "available": true,
            "last_donation_date": "2025-09-15",
            "total_donations": 5,
            "status": "approved",
            "donar_profile_image": "donars/profile1.jpg",
            "image_url": "http://example.com/storage/donars/profile1.jpg"
        }
    }
}
PUT
api/v1/donar/{id}
Update donor profile. Users can only update their own profile. Status field can only be updated by admins. All other fields can be updated by the donor.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
📦 Request Body Parameters
Field Name Type Validation Rules & Description
last_donated_at Optional Date nullable|date
is_available Optional Boolean nullable|boolean
blood_group Optional String Allowed values: A+, A-, B+, B-, AB+, AB-, O+, O-
donar_profile_image Optional String max:2048 - image mimes:jpg,jpeg,png,webp
status Optional String Allowed values: pending, approved, rejected
📄 JSON Request Example
{
    "last_donated_at": "nullable|date",
    "is_available": "nullable|boolean",
    "blood_group": "nullable|string|in:A+,A-,B+,B-,AB+,AB-,O+,O-",
    "donar_profile_image": "nullable|image|mimes:jpg,jpeg,png,webp|max:2048",
    "status": "nullable|string|in:pending,approved,rejected"
}
✅ Success Response
📥 Response Example
{
    "success": true,
    "hasError": false,
    "status": 200,
    "message": "Donor profile updated successfully",
    "data": {
        "user": {
            "id": 1,
            "name": "John Doe",
            "email": "john@example.com",
            "phone_number": "01712345678"
        },
        "donar": {
            "id": 1,
            "user_id": 1,
            "blood_group": "A+",
            "available": true,
            "last_donation_date": "2025-10-01",
            "total_donations": 5,
            "status": "approved",
            "donar_profile_image": "donars/profile1.jpg"
        },
        "image_url": "http://example.com/storage/donars/profile1.jpg"
    }
}
DELETE
api/v1/donar/{id}
Only admins can delete donors
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Donor deleted successfully",
    "data": null
}
GET
api/v1/donars/reques_list
Returns paginated list of donor requests (users with is_donar_request="yes") from the same upazila as the authenticated user. Supports filtering by blood group, availability, and status. User must have upazila_id assigned.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
🔍 Query Parameters
Parameter Name Type Validation Rules & Description
page Optional Integer default:1 - Page number
per_page Optional Integer default:15, max:100 - Number of items per page
blood_group Optional String Allowed: A+, A-, B+, B-, AB+, AB-, O+, O- - Filter by blood group
available Optional Boolean true,false Filter by availability status
status Optional String Allowed: pending, approved, rejected - Filter by donor status
✅ Success Response
📥 Response Example
{
    "success": true,
    "hasError": false,
    "status": 200,
    "message": "Donors by upazila fetched successfully",
    "data": {
        "current_page": 1,
        "per_page": 15,
        "total": 25,
        "last_page": 2,
        "from": 1,
        "to": 15,
        "next_page_url": "http://example.com/api/v1/donars/reques_list?page=2&blood_group=A+",
        "prev_page_url": null,
        "data": [
            {
                "id": 1,
                "name": "John Doe",
                "email": "john@example.com",
                "phone_number": "01712345678",
                "date_of_birth": "1990-01-01",
                "gender": "male",
                "is_donar_request": "yes",
                "zila": {
                    "id": 1,
                    "name": "Dhaka",
                    "bn_name": "\u09a2\u09be\u0995\u09be"
                },
                "upazila": {
                    "id": 5,
                    "name": "Dhanmondi",
                    "bn_name": "\u09a7\u09be\u09a8\u09ae\u09a8\u09cd\u09a1\u09bf"
                },
                "donar": {
                    "id": 1,
                    "user_id": 1,
                    "blood_group": "A+",
                    "available": true,
                    "last_donation_date": "2025-09-15",
                    "total_donations": 5,
                    "status": "approved",
                    "donar_profile_image": "donars/profile1.jpg",
                    "image_url": "http://example.com/storage/donars/profile1.jpg"
                }
            },
            {
                "id": 2,
                "name": "Jane Smith",
                "email": "jane@example.com",
                "phone_number": "01812345678",
                "date_of_birth": "1992-05-20",
                "gender": "female",
                "is_donar_request": "yes",
                "zila": {
                    "id": 1,
                    "name": "Dhaka",
                    "bn_name": "\u09a2\u09be\u0995\u09be"
                },
                "upazila": {
                    "id": 5,
                    "name": "Dhanmondi",
                    "bn_name": "\u09a7\u09be\u09a8\u09ae\u09a8\u09cd\u09a1\u09bf"
                },
                "donar": {
                    "id": 2,
                    "user_id": 2,
                    "blood_group": "B+",
                    "available": false,
                    "last_donation_date": null,
                    "total_donations": 0,
                    "status": "pending",
                    "donar_profile_image": null,
                    "image_url": null
                }
            }
        ]
    }
}
POST
api/v1/donars/update-status
Update donor status. Only admins can update donor status. If status is set to "approved", the user will be assigned the "donor" role.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
📦 Request Body Parameters
Field Name Type Validation Rules & Description
id Required String exists:donars,id The donor profile ID to update
status Optional String Allowed values: pending, approved, rejected - The new status for the donor profile
📄 JSON Request Example
{
    "id": "required|exists:donars,id|The donor profile ID to update",
    "status": "nullable|string|in:pending,approved,rejected|The new status for the donor profile"
}
✅ Success Response
📥 Response Example
{
    "success": true,
    "hasError": false,
    "status": 200,
    "message": "Donor profile updated successfully",
    "data": {
        "donar": {
            "id": 1,
            "user_id": 1,
            "blood_group": "A+",
            "available": true,
            "last_donation_date": "2025-09-15",
            "total_donations": 5,
            "status": "approved",
            "donar_profile_image": "donars/profile1.jpg"
        }
    }
}
Hero Sliders 1 endpoints
GET
api/v1/hero-sliders/images
Returns hero slider images based on authenticated user's location. Shows: upazila-specific (if user has upazila) + zila-specific + global sliders
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Hero slider images fetched successfully",
    "data": [
        {
            "id": 1,
            "image_url": "http://example.com/storage/hero-sliders/slider1.jpg",
            "order": 1,
            "zila": "Dhaka",
            "upazila": "Dhanmondi"
        },
        {
            "id": 2,
            "image_url": "http://example.com/storage/hero-sliders/slider2.jpg",
            "order": 2,
            "zila": "Dhaka",
            "upazila": null
        },
        {
            "id": 3,
            "image_url": "http://example.com/storage/hero-sliders/global-slider1.jpg",
            "order": 3,
            "zila": null,
            "upazila": null
        }
    ]
}
Notifications 5 endpoints
GET
api/v1/notifications
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
🔍 Query Parameters
Parameter Name Type Validation Rules & Description
per_page Optional Integer default:20
is_read Optional Boolean null=all, true=read only, false=unread only
type Optional String filter by notification type
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Notifications fetched successfully",
    "data": {
        "notifications": [
            {
                "id": 1,
                "user_id": 1,
                "title": "Blood Donation Reminder",
                "message": "It's time for your next blood donation. Your contribution saves lives!",
                "type": "reminder",
                "data": {
                    "category_id": 1,
                    "category_name": "Normal",
                    "send_type": "instant"
                },
                "is_read": false,
                "created_at": "2025-10-29T10:30:00.000000Z",
                "updated_at": "2025-10-29T10:30:00.000000Z"
            },
            {
                "id": 2,
                "user_id": 1,
                "title": "Monthly Reminder",
                "message": "Don't forget your monthly blood donation appointment.",
                "type": "reminder",
                "data": {
                    "scheduled_reminder_id": 5,
                    "category_id": 2,
                    "category_name": "Regular Donor",
                    "send_type": "scheduled",
                    "frequency": "monthly"
                },
                "is_read": true,
                "created_at": "2025-10-28T08:15:00.000000Z",
                "updated_at": "2025-10-28T09:20:00.000000Z"
            }
        ],
        "pagination": {
            "current_page": 1,
            "last_page": 3,
            "per_page": 20,
            "total": 45
        },
        "unread_count": 12
    }
}
PUT
api/v1/notifications/mark-all-read
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "All notifications marked as read",
    "data": null
}
GET
api/v1/notifications/unread-count
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Unread count fetched successfully",
    "data": {
        "unread_count": 12
    }
}
PUT
api/v1/notifications/{id}/read
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Notification marked as read",
    "data": {
        "notification": {
            "id": 1,
            "user_id": 1,
            "title": "Blood Donation Reminder",
            "message": "It's time for your next blood donation.",
            "type": "reminder",
            "is_read": true,
            "created_at": "2025-10-29T10:30:00.000000Z",
            "updated_at": "2025-10-29T11:15:00.000000Z"
        }
    }
}
POST
api/v1/send-notification-to-user
Send a push notification to a specific user. Requires authentication. The notification will be saved to the database and sent via Firebase Cloud Messaging to all registered devices of the user. Returns error if user has no registered device tokens. The notification data automatically includes route=notifications for mobile app navigation.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
📦 Request Body Parameters
Field Name Type Validation Rules & Description
user_id Required Integer exists:users,id The ID of the user to send notification to
title Required String Notification title
body Required String Notification body/message
data Optional Array optional Additional data to include in the notification payload
📄 JSON Request Example
{
    "user_id": "required|integer|exists:users,id|The ID of the user to send notification to",
    "title": "required|string|Notification title",
    "body": "required|string|Notification body/message",
    "data": "optional|array|Additional data to include in the notification payload"
}
Organization Management 3 endpoints
GET
api/v1/organizations
Returns list of organizations from the same upazila as the authenticated user. User must have upazila_id assigned in their profile. Response includes organization details with full image URL.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Organizations fetched successfully",
    "data": [
        {
            "id": 1,
            "name": "Red Crescent Society",
            "img": "organizations/image1.jpg",
            "img_url": "http://example.com/storage/organizations/image1.jpg",
            "details": "Organization description here",
            "zila_id": 1,
            "upazila_id": 5,
            "zila": {
                "id": 1,
                "name": "Dhaka",
                "bn_name": "\u09a2\u09be\u0995\u09be"
            },
            "upazila": {
                "id": 5,
                "name": "Dhanmondi",
                "bn_name": "\u09a7\u09be\u09a8\u09ae\u09a8\u09cd\u09a1\u09bf"
            }
        }
    ],
    "error_examples": {
        "no_upazila": {
            "success": false,
            "code": 200,
            "message": "User does not have an upazila set",
            "data": []
        }
    }
}
POST
api/v1/organizations/assign-admin
Assign the "admin" role to a specific user and link them to the authenticated organization admin's organization. Only users with the "organization-admin" role can perform this action. The target user will receive the "admin" role and their organization_id will be set to the requester's organization_id.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
📦 Request Body Parameters
Field Name Type Validation Rules & Description
user_id Required Integer exists:users,id The ID of the user to promote to admin
📄 JSON Request Example
{
    "user_id": "required|integer|exists:users,id|The ID of the user to promote to admin"
}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "User promoted to Admin and linked to Organization successfully.",
    "data": {
        "id": 10,
        "name": "New Admin",
        "email": "newadmin@example.com",
        "phone_number": "01700000000",
        "organization_id": 1,
        "roles": [
            {
                "id": 2,
                "name": "admin",
                "guard_name": "web"
            }
        ]
    },
    "error_examples": {
        "unauthorized": {
            "success": false,
            "code": 403,
            "message": "Unauthorized. Only Organization Admins can perform this action."
        },
        "no_organization": {
            "success": false,
            "code": 400,
            "message": "Current user does not belong to any organization."
        },
        "validation_failed": {
            "success": false,
            "code": 422,
            "message": "The user id field is required."
        }
    }
}
GET
api/v1/organizations/{id}
Returns details of a specific organization including zila, upazila, and associated users. Response includes full image URL.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Organization fetched successfully",
    "data": {
        "id": 1,
        "name": "Red Crescent Society",
        "img": "organizations/image1.jpg",
        "img_url": "http://example.com/storage/organizations/image1.jpg",
        "details": "Organization description here",
        "zila_id": 1,
        "upazila_id": 5,
        "zila": {
            "id": 1,
            "name": "Dhaka",
            "bn_name": "\u09a2\u09be\u0995\u09be"
        },
        "upazila": {
            "id": 5,
            "name": "Dhanmondi",
            "bn_name": "\u09a7\u09be\u09a8\u09ae\u09a8\u09cd\u09a1\u09bf"
        },
        "users": []
    },
    "error_examples": {
        "not_found": {
            "success": false,
            "code": 404,
            "message": "Organization not found"
        }
    }
}
Other 5 endpoints
GET
api/v1/emergencies
Returns emergency contact numbers (fire service, police, hospital) for the authenticated user's upazila. User must have upazila_id assigned in their profile.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Emergency contacts retrieved successfully",
    "data": {
        "id": 1,
        "upazila": {
            "id": 1,
            "name": "Savar",
            "bn_name": "\u09b8\u09be\u09ad\u09be\u09b0"
        },
        "fire_service_number": "999",
        "police_number": "999",
        "hospital_number": "01712345678"
    },
    "error_examples": {
        "user_upazila_not_found": {
            "success": false,
            "code": 404,
            "message": "User upazila not found.",
            "data": []
        },
        "emergency_not_found": {
            "success": false,
            "code": 404,
            "message": "Emergency contacts not found for your upazila.",
            "data": []
        }
    }
}
POST
api/v1/emergencies
Create emergency contact numbers for the authenticated admin's upazila. The upazila_id is automatically taken from the authenticated user's profile. Only admins and super-admins can create emergency contacts. User must have upazila_id assigned. At least one emergency number should be provided.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
📦 Request Body Parameters
Field Name Type Validation Rules & Description
fire_service_number Optional String max:20 - optional Fire service emergency number
police_number Optional String max:20 - optional Police emergency number
hospital_number Optional String max:20 - optional Hospital emergency number
📄 JSON Request Example
{
    "fire_service_number": "optional|string|max:20|Fire service emergency number",
    "police_number": "optional|string|max:20|Police emergency number",
    "hospital_number": "optional|string|max:20|Hospital emergency number"
}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 201,
    "message": "Emergency contact created successfully",
    "data": {
        "id": 1,
        "upazila": {
            "id": 1,
            "name": "Savar",
            "bn_name": "\u09b8\u09be\u09ad\u09be\u09b0"
        },
        "fire_service_number": "999",
        "police_number": "999",
        "hospital_number": "01712345678",
        "created_at": "2025-11-08T10:00:00.000000Z"
    },
    "error_examples": {
        "access_denied": {
            "success": false,
            "code": 403,
            "message": "Access denied. Only admins can create emergency contacts.",
            "data": []
        },
        "user_upazila_not_found": {
            "success": false,
            "code": 400,
            "message": "User upazila not found. Please update your profile with an upazila.",
            "data": []
        },
        "already_exists": {
            "success": false,
            "code": 409,
            "message": "Emergency contacts already exist for your upazila.",
            "data": []
        },
        "validation_error": {
            "success": false,
            "code": 422,
            "message": "Validation failed",
            "data": {
                "fire_service_number": [
                    "Fire service number must not exceed 20 characters."
                ],
                "police_number": [
                    "Police number must not exceed 20 characters."
                ]
            }
        }
    }
}
GET
api/v1/newsfeed
Get newsfeed showing all completed donations from users in the same district (zila) as the authenticated user. Returns donations with like counts, comment counts, recent likes, and recent comments. Includes user interaction status (whether current user liked/commented). To like or comment on donations, use the donation-specific endpoints: POST /api/v1/donations/{id}/like and POST /api/v1/donations/{id}/comment
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
🔍 Query Parameters
Parameter Name Type Validation Rules & Description
page Optional Integer min:1, default:1 - Page number for pagination
per_page Optional Integer min:1, max:100, default:15 - Number of items per page
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Newsfeed fetched successfully",
    "data": {
        "current_page": 1,
        "per_page": 15,
        "total": 30,
        "last_page": 2,
        "from": 1,
        "to": 15,
        "next_page_url": "http://example.com/api/v1/newsfeed?page=2",
        "prev_page_url": null,
        "data": [
            {
                "id": 1,
                "donar_id": 1,
                "blood_request_id": 1,
                "donation_date": "2025-10-25",
                "status": "completed",
                "location": "Dhaka Medical College",
                "hospital_name": "Dhaka Medical College",
                "notes": null,
                "image": "donations/donation_image1.jpg",
                "image_url": "http://example.com/storage/donations/donation_image1.jpg",
                "created_at": "2025-10-22T10:00:00.000000Z",
                "updated_at": "2025-10-22T10:00:00.000000Z",
                "likes_count": 15,
                "comments_count": 5,
                "user_liked": true,
                "user_reaction": "like",
                "recent_likes": [
                    {
                        "id": 1,
                        "user_id": 2,
                        "user_name": "Jane Smith",
                        "reaction": "like",
                        "created_at": "2025-10-22T11:00:00.000000Z"
                    },
                    {
                        "id": 2,
                        "user_id": 3,
                        "user_name": "Alice Johnson",
                        "reaction": "love",
                        "created_at": "2025-10-22T11:05:00.000000Z"
                    }
                ],
                "recent_comments": [
                    {
                        "id": 1,
                        "user_id": 2,
                        "user_name": "Jane Smith",
                        "comment": "Great work! Thank you for saving a life.",
                        "created_at": "2025-10-22T11:10:00.000000Z"
                    },
                    {
                        "id": 2,
                        "user_id": 3,
                        "user_name": "Alice Johnson",
                        "comment": "You are a hero!",
                        "created_at": "2025-10-22T11:15:00.000000Z"
                    }
                ],
                "donar": {
                    "id": 1,
                    "user_id": 1,
                    "blood_group": "A+",
                    "available": true,
                    "last_donation_date": "2025-10-25",
                    "total_donations": 5,
                    "status": "approved",
                    "image_url": "http://example.com/storage/donars/profile1.jpg",
                    "user_info": {
                        "id": 1,
                        "name": "John Doe",
                        "email": "john@example.com",
                        "phone_number": "01712345678"
                    }
                },
                "bloodRequest": {
                    "id": 1,
                    "patient_name": "John Doe",
                    "blood_group_needed": "A+",
                    "hospital_name": "Dhaka Medical College",
                    "status": "fulfilled"
                }
            }
        ]
    }
}
GET
api/v1/statistics
Returns overall statistics including total completed donations, total donors, and total upazilas. Requires authentication.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Statistics retrieved successfully",
    "data": {
        "total_completed_donations": 1250,
        "total_donors": 850,
        "total_upazilas": 64
    },
    "error_examples": {
        "server_error": {
            "success": false,
            "code": 500,
            "message": "Failed to retrieve statistics",
            "data": {
                "error": "Database connection error"
            }
        }
    }
}
PUT
api/v1/user/update
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Profile updated successfully",
    "data": {
        "user": {
            "id": 1,
            "name": "Updated Name",
            "email": "newemail@example.com",
            "phone_number": "01812345678",
            "gender": "female",
            "date_of_birth": "1995-05-15",
            "zila": {
                "id": 2,
                "name": "Chattogram",
                "bn_name": "\u099a\u099f\u09cd\u099f\u0997\u09cd\u09b0\u09be\u09ae"
            },
            "upazila": {
                "id": 5,
                "name": "Patiya",
                "bn_name": "\u09aa\u099f\u09bf\u09af\u09bc\u09be"
            }
        }
    }
}
Public API 4 endpoints
POST
api/public/app/check-update
Check for app updates. Public endpoint - no authentication required. Returns update information based on user location (if authenticated), Android version, and device ABI. Supports location-based updates (zila/upazila/global), Android version targeting, and device architecture targeting (arm64-v8a, armeabi-v7a, x86). If device_abi is not sent, only global versions (null ABI) are returned.
📦 Request Body Parameters
Field Name Type Validation Rules & Description
current_version_code Required Integer min:1 - Current app version code (build number)
platform Required String Allowed values: android, ios - Platform type
current_version Optional String optional Current app version name (e.g., "1.0.0")
android_version Optional Integer min:1, max:15 - optional Android OS version (e.g., 8, 9, 10, 11, 12, 13, 14, 15)
device_abi Optional String Allowed values: arm64-v8a, armeabi-v7a, x86 - optional Device ABI (Application Binary Interface). If provided, returns ABI-specific versions first, then global versions. If not provided, returns only global versions.
📄 JSON Request Example
{
    "current_version_code": "required|integer|min:1|Current app version code (build number)",
    "platform": "required|string|in:android,ios|Platform type",
    "current_version": "optional|string|Current app version name (e.g., \"1.0.0\")",
    "android_version": "optional|integer|min:1|max:15|Android OS version (e.g., 8, 9, 10, 11, 12, 13, 14, 15)",
    "device_abi": "optional|string|in:arm64-v8a,armeabi-v7a,x86|Device ABI (Application Binary Interface). If provided, returns ABI-specific versions first, then global versions. If not provided, returns only global versions."
}
✅ Success Response
📥 Response Example
{
    "success": true,
    "status": 200,
    "message": "Update check completed",
    "data": {
        "update_available": true,
        "force_update": false,
        "current_version_code": 1,
        "current_version": "1.0.0",
        "latest_version": {
            "version": "1.1.0",
            "version_code": 2,
            "platform": "android",
            "download_url": "https://yoursite.com/apps/app-v1.1.0.apk",
            "update_type": "optional",
            "changelog": "Bug fixes and performance improvements",
            "release_notes": "Detailed release notes here...",
            "file_size": 15728640,
            "file_size_mb": 15
        }
    },
    "error_examples": {
        "validation_failed": {
            "success": false,
            "status": 422,
            "message": "Validation failed",
            "data": {
                "errors": {
                    "current_version_code": [
                        "The current version code field is required."
                    ],
                    "platform": [
                        "The selected platform is invalid."
                    ]
                }
            }
        }
    }
}
GET
api/public/zilas
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Zilas retrieved successfully",
    "data": [
        {
            "id": 1,
            "name": "Dhaka",
            "bn_name": "\u09a2\u09be\u0995\u09be"
        },
        {
            "id": 2,
            "name": "Chattogram",
            "bn_name": "\u099a\u099f\u09cd\u099f\u0997\u09cd\u09b0\u09be\u09ae"
        }
    ]
}
GET
api/public/zilas/{id}/upazilas
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Upazilas retrieved successfully",
    "data": [
        {
            "id": 1,
            "zila_id": 1,
            "name": "Savar",
            "bn_name": "\u09b8\u09be\u09ad\u09be\u09b0"
        },
        {
            "id": 2,
            "zila_id": 1,
            "name": "Dhamrai",
            "bn_name": "\u09a7\u09be\u09ae\u09b0\u09be\u0987"
        }
    ]
}
POST
api/v1/public/reminder-categories
🔐 Request Headers
Header Name Value / Description
X-API-Key your-secret-key
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Reminder categories fetched successfully",
    "data": [
        {
            "id": 1,
            "name": "Normal",
            "description": "General reminders",
            "users_count": 10
        },
        {
            "id": 2,
            "name": "Diabetic",
            "description": "For diabetic users",
            "users_count": 5
        }
    ]
}
User Management 1 endpoints
GET
api/user-by-ip
📦 Request Body Parameters
Field Name Type Validation Rules & Description
device_ip Required String required|string
device_token Optional String nullable|string
📄 JSON Request Example
{
    "device_ip": "required|string",
    "device_token": "nullable|string"
}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 201,
    "message": "User created successfully",
    "data": {
        "access_token": "token",
        "token_type": "Bearer",
        "id": 1,
        "name": "John Doe",
        "email": "john@example.com",
        "phone_number": "01712345678",
        "zila_id": 1,
        "upazila_id": 2,
        "date_of_birth": "1990-01-01",
        "gender": "male"
    }
}
User Profile 3 endpoints
GET
api/v1/profile
Get complete user profile with all role-specific data (donor, admin, normal-user). Returns user info, reminder categories, device count, and role-specific profiles.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Profile retrieved successfully",
    "data": {
        "user": {
            "id": 1,
            "name": "John Doe",
            "email": "john@example.com",
            "phone_number": "01712345678",
            "gender": "male",
            "date_of_birth": "1990-01-01",
            "type": null,
            "roles": [
                "donor"
            ],
            "zila": {
                "id": 1,
                "name": "Dhaka",
                "bn_name": "\u09a2\u09be\u0995\u09be"
            },
            "upazila": {
                "id": 5,
                "name": "Dhanmondi",
                "bn_name": "\u09a7\u09be\u09a8\u09ae\u09a8\u09cd\u09a1\u09bf"
            },
            "created_at": "2024-01-01T00:00:00.000000Z",
            "updated_at": "2024-01-01T00:00:00.000000Z"
        },
        "reminder_categories": [
            {
                "id": 1,
                "name": "Blood Donation Reminder",
                "description": "Regular donation reminders"
            },
            {
                "id": 2,
                "name": "Monthly Checkup",
                "description": "Monthly health check reminders"
            }
        ],
        "devices_count": 2,
        "donor": {
            "id": 1,
            "blood_group": "A+",
            "available": true,
            "last_donation_date": "2023-12-01",
            "total_donations": 5,
            "status": "approved",
            "profile_complete": "yes",
            "profile_image": "http://domain.com/storage/donars/image.jpg"
        }
    },
    "notes": [
        "For admin users, the response includes an \"admin\" object instead of \"donor\" object.",
        "For normal users without donor/admin roles, only the \"user\" object and basic fields are returned.",
        "reminder_categories contains all categories the user is subscribed to.",
        "devices_count shows the number of registered device tokens (actual tokens are not returned for security)."
    ]
}
PUT
api/v1/profile/update
Unified profile update API for all user types (donor, admin, normal-user). Automatically detects user roles and updates appropriate fields. Supports password change, reminder categories, and device token updates. All fields are optional - only send the fields you want to update.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
📦 Request Body Parameters
Field Name Type Validation Rules & Description
name Optional String max:255 - optional Updated user name
email Optional Email optional unique User email address
phone_number Optional String optional unique User phone number
zila_id Optional Integer optional exists:zilas,id District ID
upazila_id Optional Integer optional exists:upazilas,id Sub-district ID
date_of_birth Optional Date optional before:today User date of birth
gender Optional String optional enum:male,female User gender
donor_blood_group Optional String Allowed values: A+, A-, B+, B-, AB+, AB-, O+, O- - optional Blood group for donor profile
is_available Optional Boolean optional Donor availability status
last_donation_date Optional Date optional before_or_equal:today Last donation date
donar_profile_image Optional String max:2048 - optional image mimes:jpg,jpeg,png,webp Donor profile image
profile_complete Optional String Allowed values: yes, no - optional Profile completion status (yes if profile is complete, no otherwise)
admin_blood_group Optional String Allowed values: A+, A-, B+, B-, AB+, AB-, O+, O- - optional Blood group for admin profile
admin_profile_image Optional String max:2048 - optional image mimes:jpg,jpeg,png,webp Admin profile image
current_password Required String min:8 - optional
new_password Required String min:8 - optional confirmed
new_password_confirmation Required String min:8 - optional
reminder_category_ids Optional Array optional Array of reminder category IDs
reminder_category_ids.* Optional String exists:reminder_categories,id Reminder category ID
device_token Optional String optional Firebase push notification device token
📄 JSON Request Example
{
    "name": "optional|string|max:255|Updated user name",
    "email": "optional|email|unique|User email address",
    "phone_number": "optional|string|unique|User phone number",
    "zila_id": "optional|integer|exists:zilas,id|District ID",
    "upazila_id": "optional|integer|exists:upazilas,id|Sub-district ID",
    "date_of_birth": "optional|date|before:today|User date of birth",
    "gender": "optional|enum:male,female|User gender",
    "donor_blood_group": "optional|string|in:A+,A-,B+,B-,AB+,AB-,O+,O-|Blood group for donor profile",
    "is_available": "optional|boolean|Donor availability status",
    "last_donation_date": "optional|date|before_or_equal:today|Last donation date",
    "donar_profile_image": "optional|image|mimes:jpg,jpeg,png,webp|max:2048|Donor profile image",
    "profile_complete": "optional|string|in:yes,no|Profile completion status (yes if profile is complete, no otherwise)",
    "admin_blood_group": "optional|string|in:A+,A-,B+,B-,AB+,AB-,O+,O-|Blood group for admin profile",
    "admin_profile_image": "optional|image|mimes:jpg,jpeg,png,webp|max:2048|Admin profile image",
    "current_password": "optional|required_with:new_password|string|min:8|Current password for verification (required only if changing password)",
    "new_password": "optional|required_with:current_password|string|min:8|confirmed|New password (required only if changing password)",
    "new_password_confirmation": "optional|string|min:8|New password confirmation (required when new_password is provided)",
    "reminder_category_ids": "optional|array|Array of reminder category IDs",
    "reminder_category_ids.*": "exists:reminder_categories,id|Reminder category ID",
    "device_token": "optional|string|Firebase push notification device token"
}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Profile updated successfully",
    "data": {
        "user": {
            "id": 1,
            "name": "John Doe",
            "email": "john@example.com",
            "phone_number": "01712345678",
            "gender": "male",
            "date_of_birth": "1990-01-01",
            "type": null,
            "roles": [
                "donor"
            ],
            "zila": {
                "id": 1,
                "name": "Dhaka",
                "bn_name": "\u09a2\u09be\u0995\u09be"
            },
            "upazila": {
                "id": 5,
                "name": "Dhanmondi",
                "bn_name": "\u09a7\u09be\u09a8\u09ae\u09a8\u09cd\u09a1\u09bf"
            },
            "created_at": "2024-01-01T00:00:00.000000Z",
            "updated_at": "2024-01-02T10:30:00.000000Z"
        },
        "reminder_categories": [
            {
                "id": 1,
                "name": "Blood Donation Reminder",
                "description": "Regular donation reminders"
            },
            {
                "id": 3,
                "name": "Emergency Alerts",
                "description": "Emergency blood request alerts"
            }
        ],
        "devices_count": 3,
        "donor": {
            "id": 1,
            "blood_group": "A+",
            "available": true,
            "last_donation_date": "2024-01-15",
            "total_donations": 5,
            "status": "approved",
            "profile_complete": "yes",
            "profile_image": "http://domain.com/storage/donars/image.jpg"
        }
    },
    "notes": [
        "Response structure is the same as GET api/v1/profile.",
        "Only updated fields are reflected in the response.",
        "If password is updated, all old tokens are automatically revoked for security.",
        "Reminder categories are synced (replaced) with the provided array.",
        "Device token updates are reflected in devices_count."
    ],
    "error_examples": {
        "validation_failed": {
            "success": false,
            "code": 422,
            "message": "Validation failed",
            "data": {
                "errors": {
                    "email": [
                        "The email has already been taken."
                    ],
                    "donor_blood_group": [
                        "The selected donor blood group is invalid."
                    ]
                }
            }
        },
        "incorrect_password": {
            "success": false,
            "code": 401,
            "message": "Current password is incorrect",
            "data": {
                "errors": {
                    "current_password": [
                        "The current password is incorrect."
                    ]
                }
            }
        },
        "unauthenticated": {
            "success": false,
            "code": 401,
            "message": "User not authenticated"
        }
    }
}
PATCH
api/v1/profile/update
Same as PUT api/v1/profile/update. PATCH method alternative.
🔐 Request Headers
Header Name Value / Description
Authorization Bearer {access_token}
📦 Request Body Parameters
Field Name Type Validation Rules & Description
name Optional String max:255 - optional Updated user name
email Optional Email optional unique User email address
phone_number Optional String optional unique User phone number
zila_id Optional Integer optional exists:zilas,id District ID
upazila_id Optional Integer optional exists:upazilas,id Sub-district ID
date_of_birth Optional Date optional before:today User date of birth
gender Optional String optional enum:male,female User gender
donor_blood_group Optional String Allowed values: A+, A-, B+, B-, AB+, AB-, O+, O- - optional Blood group for donor profile
is_available Optional Boolean optional Donor availability status
last_donation_date Optional Date optional before_or_equal:today Last donation date
donar_profile_image Optional String max:2048 - optional image mimes:jpg,jpeg,png,webp Donor profile image
profile_complete Optional String Allowed values: yes, no - optional Profile completion status (yes if profile is complete, no otherwise)
admin_blood_group Optional String Allowed values: A+, A-, B+, B-, AB+, AB-, O+, O- - optional Blood group for admin profile
admin_profile_image Optional String max:2048 - optional image mimes:jpg,jpeg,png,webp Admin profile image
current_password Required String min:8 - optional
new_password Required String min:8 - optional confirmed
new_password_confirmation Required String min:8 - optional
reminder_category_ids Optional Array optional Array of reminder category IDs
reminder_category_ids.* Optional String exists:reminder_categories,id Reminder category ID
device_token Optional String optional Firebase push notification device token
📄 JSON Request Example
{
    "name": "optional|string|max:255|Updated user name",
    "email": "optional|email|unique|User email address",
    "phone_number": "optional|string|unique|User phone number",
    "zila_id": "optional|integer|exists:zilas,id|District ID",
    "upazila_id": "optional|integer|exists:upazilas,id|Sub-district ID",
    "date_of_birth": "optional|date|before:today|User date of birth",
    "gender": "optional|enum:male,female|User gender",
    "donor_blood_group": "optional|string|in:A+,A-,B+,B-,AB+,AB-,O+,O-|Blood group for donor profile",
    "is_available": "optional|boolean|Donor availability status",
    "last_donation_date": "optional|date|before_or_equal:today|Last donation date",
    "donar_profile_image": "optional|image|mimes:jpg,jpeg,png,webp|max:2048|Donor profile image",
    "profile_complete": "optional|string|in:yes,no|Profile completion status (yes if profile is complete, no otherwise)",
    "admin_blood_group": "optional|string|in:A+,A-,B+,B-,AB+,AB-,O+,O-|Blood group for admin profile",
    "admin_profile_image": "optional|image|mimes:jpg,jpeg,png,webp|max:2048|Admin profile image",
    "current_password": "optional|required_with:new_password|string|min:8|Current password for verification (required only if changing password)",
    "new_password": "optional|required_with:current_password|string|min:8|confirmed|New password (required only if changing password)",
    "new_password_confirmation": "optional|string|min:8|New password confirmation (required when new_password is provided)",
    "reminder_category_ids": "optional|array|Array of reminder category IDs",
    "reminder_category_ids.*": "exists:reminder_categories,id|Reminder category ID",
    "device_token": "optional|string|Firebase push notification device token"
}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 200,
    "message": "Profile updated successfully",
    "data": {
        "user": {
            "id": 1,
            "name": "John Doe Updated",
            "email": "john@example.com",
            "phone_number": "01712345678",
            "gender": "male",
            "date_of_birth": "1990-01-01",
            "type": null,
            "roles": [
                "donor"
            ],
            "zila": {
                "id": 1,
                "name": "Dhaka",
                "bn_name": "\u09a2\u09be\u0995\u09be"
            },
            "upazila": {
                "id": 5,
                "name": "Dhanmondi",
                "bn_name": "\u09a7\u09be\u09a8\u09ae\u09a8\u09cd\u09a1\u09bf"
            },
            "created_at": "2024-01-01T00:00:00.000000Z",
            "updated_at": "2024-01-02T10:35:00.000000Z"
        },
        "reminder_categories": [
            {
                "id": 1,
                "name": "Blood Donation Reminder",
                "description": "Regular donation reminders"
            }
        ],
        "devices_count": 2,
        "donor": {
            "id": 1,
            "blood_group": "A+",
            "available": true,
            "last_donation_date": "2024-01-15",
            "total_donations": 5,
            "status": "approved",
            "profile_complete": "yes",
            "profile_image": "http://domain.com/storage/donars/image.jpg"
        }
    },
    "notes": [
        "Same response structure as PUT api/v1/profile/update."
    ]
}
User Registration 1 endpoints
POST
api/v1/register
📦 Request Body Parameters
Field Name Type Validation Rules & Description
name Optional String John Doe
email Optional String john@example.com
phone_number Optional String 01712345678
password Optional String secret123
zila_id Optional Integer Numeric value
upazila_id Optional Integer Numeric value
date_of_birth Optional String 1990-01-01
gender Optional String male
device_ip Optional String device_ip
device_token Optional String device_token_abc123
reminder_category_ids Optional Array Array of objects
📄 JSON Request Example
{
    "name": "John Doe",
    "email": "john@example.com",
    "phone_number": "01712345678",
    "password": "secret123",
    "zila_id": 1,
    "upazila_id": 2,
    "date_of_birth": "1990-01-01",
    "gender": "male",
    "device_ip": "device_ip",
    "device_token": "device_token_abc123",
    "reminder_category_ids": [
        1,
        2
    ]
}
✅ Success Response
📥 Response Example
{
    "success": true,
    "code": 201,
    "message": "User created successfully",
    "data": {
        "access_token": "token",
        "token_type": "Bearer",
        "id": 1,
        "name": "John Doe",
        "email": "john@example.com",
        "phone_number": "01712345678",
        "zila_id": 1,
        "upazila_id": 2,
        "date_of_birth": "1990-01-01",
        "gender": "male"
    }
}