📚 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 | 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 | 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 | 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 | 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"
}
}