API Documentation - bounswe/bounswe2025group8 GitHub Wiki
This document provides a comprehensive guide to the Neighborhood Assistance Board API, designed for integration with mobile and frontend applications. Below you'll find details on setting up the environment, running the service, and using all available endpoints.
To run the backend service, you'll need:
- Docker and Docker Compose installed on your machine
- Git to clone the repository
# Clone the repository (if you haven't already)
git clone https://github.com/bounswe/bounswe2025group8.git
cd bounswe2025group8/app/backend
# Build and start containers in detached mode
docker-compose up --build -d
# The API will be available at http://localhost:8000/api/
# View running containers
docker ps
# Stop and remove containers
docker-compose down
# Stop, remove containers, and delete volumes (this will delete the database)
docker-compose down -v
# View logs
docker-compose logs -f
The API uses a RESTful architecture and accepts/returns JSON data. Responses follow a standard format:
{
"status": "success" | "error",
"message": "Human-readable message",
"data": { /* Response data object */ }
}
Most endpoints require authentication using Token Authentication:
Authorization: Token <your_token>
-
Endpoint:
POST /api/auth/register/
- Auth Required: No
- Description: Register a new user
-
Request Body:
{ "name": "Maria", "surname": "Lopez", "username": "marialopez", "email": "[email protected]", "phone_number": "1234567890", "password": "SecurePass123!", "confirm_password": "SecurePass123!" }
-
Success Response: Status 201
{ "status": "success", "message": "Registration successful. Please log in to continue.", "data": { "user_id": 1, "name": "Maria", "email": "[email protected]" } }
-
Error Response: Status 400
{ "status": "error", "message": "Registration failed.", "data": { "email": ["This email is already taken."], "password": ["Password must include uppercase, lowercase, number, and special character."] } }
-
Endpoint:
GET /api/auth/check-availability/
- Auth Required: No
- Description: Check if email or phone number is available
-
Query Parameters:
-
email
: Email to check -
phone_number
: Phone number to check
-
-
Success Response: Status 200
{ "status": "success", "message": "This email is available for registration.", "data": {"available": true} }
-
Error Response: Status 200
{ "status": "error", "message": "This email is already associated with an existing account.", "data": {"available": false} }
-
Endpoint:
POST /api/auth/login/
- Auth Required: No
- Description: Login with user credentials
-
Request Body:
{ "email": "[email protected]", "password": "SecurePass123!" }
-
Success Response: Status 200
{ "status": "success", "message": "Login successful.", "data": { "token": "your-auth-token", "user_id": 1 } }
-
Error Response: Status 401
{ "status": "error", "message": "Invalid credentials." }
-
Endpoint:
POST /api/auth/logout/
- Auth Required: Yes
- Description: Logout current user
-
Success Response: Status 200
{ "status": "success", "message": "Logout successful." }
-
Endpoint:
POST /api/auth/request-reset/
- Auth Required: No
- Description: Request password reset link
-
Request Body:
{ "email": "[email protected]" }
-
Success Response: Status 200
{ "status": "success", "message": "If your email exists in our system, you will receive a password reset link shortly." }
-
Endpoint:
GET /api/auth/verify-token/<token>/
- Auth Required: No
- Description: Verify if a reset token is valid
-
Success Response: Status 200
{ "status": "success", "message": "Token is valid.", "data": { "email": "[email protected]", "token_expiry": "2025-05-16T14:00:00Z" } }
-
Error Response: Status 400
{ "status": "error", "message": "Invalid or expired token. Please request a new password reset link." }
-
Endpoint:
POST /api/auth/reset-password/
- Auth Required: No
- Description: Reset password using token
-
Request Body:
{ "token": "reset-token", "new_password": "NewSecurePass456!", "confirm_password": "NewSecurePass456!" }
-
Success Response: Status 200
{ "status": "success", "message": "Password has been reset successfully. You can now log in with your new password." }
-
Error Response: Status 400
{ "status": "error", "message": "Passwords do not match." }
-
Endpoint:
GET /api/users/<user_id>/
- Auth Required: Yes
- Description: Get user profile details
-
Success Response: Status 200
{ "status": "success", "data": { "id": 1, "name": "Maria", "surname": "Lopez", "username": "marialopez", "email": "[email protected]", "phone_number": "1234567890", "location": "Lisbon, Portugal", "rating": 4.5, "completed_task_count": 10, "is_active": true } }
-
Endpoint:
PATCH /api/users/<user_id>/
- Auth Required: Yes
- Description: Update user profile information
-
Request Body:
{ "name": "Maria Updated", "location": "Lisbon Downtown, Portugal", "phone_number": "1234567899" }
-
Success Response: Status 200
{ "status": "success", "message": "Profile updated successfully.", "data": { "id": 1, "name": "Maria Updated", "surname": "Lopez", "username": "marialopez", "email": "[email protected]", "phone_number": "1234567899", "location": "Lisbon Downtown, Portugal", "rating": 4.5, "completed_task_count": 10, "is_active": true } }
-
Endpoint:
POST /api/users/<user_id>/change-password/
- Auth Required: Yes
- Description: Change user password
-
Request Body:
{ "current_password": "SecurePass123!", "new_password": "NewSecurePass456!", "confirm_password": "NewSecurePass456!" }
-
Success Response: Status 200
{ "status": "success", "message": "Password changed successfully." }
-
Error Response: Status 400
{ "status": "error", "message": "Current password is incorrect." }
-
Endpoint:
POST /api/tasks/
- Auth Required: Yes
- Description: Create a new assistance request
-
Request Body:
{ "title": "Help with Mobile Payments", "description": "Need help learning how to make secure mobile payments using my smartphone", "category": "TUTORING", "location": "Lisbon, Portugal", "deadline": "2025-05-20T15:00:00Z", "requirements": "Patient person with knowledge of banking apps", "urgency_level": 3, "volunteer_number": 1, "is_recurring": false }
-
Success Response: Status 201
{ "status": "success", "message": "Task created successfully.", "data": { "id": 1, "title": "Help with Mobile Payments", "description": "Need help learning how to make secure mobile payments using my smartphone", "category": "TUTORING", "category_display": "Tutoring", "location": "Lisbon, Portugal", "deadline": "2025-05-20T15:00:00Z", "requirements": "Patient person with knowledge of banking apps", "urgency_level": 3, "volunteer_number": 1, "status": "POSTED", "status_display": "Posted", "is_recurring": false, "creator": { /* User object */ }, "assignee": null, "created_at": "2025-05-15T10:30:00Z", "updated_at": "2025-05-15T10:30:00Z" } }
-
Endpoint:
GET /api/tasks/<task_id>/
- Auth Required: Yes
- Description: Get details for a specific task
-
Success Response: Status 200
{ "status": "success", "data": { "id": 1, "title": "Help with Mobile Payments", "description": "Need help learning how to make secure mobile payments using my smartphone", "category": "TUTORING", "category_display": "Tutoring", "location": "Lisbon, Portugal", "deadline": "2025-05-20T15:00:00Z", "requirements": "Patient person with knowledge of banking apps", "urgency_level": 3, "volunteer_number": 1, "status": "POSTED", "status_display": "Posted", "is_recurring": false, "creator": { /* User object */ }, "assignee": null, "created_at": "2025-05-15T10:30:00Z", "updated_at": "2025-05-15T10:30:00Z" } }
-
Endpoint:
GET /api/tasks/
- Auth Required: Yes
- Description: List all available tasks
-
Query Parameters:
-
status
: Filter by task status (e.g., POSTED, ASSIGNED) -
category
: Filter by category -
location
: Filter by location -
search
: Search by keyword -
tag
: Filter by tag -
urgency
: Filter by min urgency level -
show_expired
: Whether to include expired tasks (default: false)
-
-
Success Response: Status 200
{ "status": "success", "data": [ { "id": 1, "title": "Help with Mobile Payments", "category": "TUTORING", "category_display": "Tutoring", "location": "Lisbon, Portugal", "deadline": "2025-05-20T15:00:00Z", "status": "POSTED", "status_display": "Posted", "creator": { /* User object */ } }, { "id": 2, "title": "Grocery Shopping Help", "category": "GROCERY_SHOPPING", "category_display": "Grocery Shopping", "location": "New York, USA", "deadline": "2025-05-18T14:00:00Z", "status": "POSTED", "status_display": "Posted", "creator": { /* User object */ } } ] }
-
Endpoint:
PATCH /api/tasks/<task_id>/
- Auth Required: Yes
- Description: Update task details
-
Request Body:
{ "title": "Help with Mobile Payments and Banking Apps", "requirements": "Patient person with knowledge of banking apps. Experience with seniors preferred." }
-
Success Response: Status 200
{ "status": "success", "message": "Task updated successfully.", "data": { "id": 1, "title": "Help with Mobile Payments and Banking Apps", "description": "Need help learning how to make secure mobile payments using my smartphone", "category": "TUTORING", "category_display": "Tutoring", "location": "Lisbon, Portugal", "deadline": "2025-05-20T15:00:00Z", "requirements": "Patient person with knowledge of banking apps. Experience with seniors preferred.", "urgency_level": 3, "volunteer_number": 1, "status": "POSTED", "status_display": "Posted", "is_recurring": false, "creator": { /* User object */ }, "assignee": null, "created_at": "2025-05-15T10:30:00Z", "updated_at": "2025-05-15T11:20:00Z" } }
-
Endpoint:
POST /api/tasks/<task_id>/update-status/
- Auth Required: Yes
- Description: Update the status of a task
-
Request Body:
{ "status": "CANCELLED" }
-
Success Response: Status 200
{ "status": "success", "message": "Task status updated to 'Cancelled'.", "data": { /* Updated task object */ } }
-
Endpoint:
POST /api/tasks/<task_id>/complete/
- Auth Required: Yes
- Description: Mark a task as completed
-
Success Response: Status 200
{ "status": "success", "message": "Task marked as completed.", "data": { "task_id": 1, "status": "COMPLETED", "completed_at": "2025-05-15T16:30:00Z" } }
-
Endpoint:
GET /api/users/<user_id>/tasks/
- Auth Required: Yes
- Description: List all tasks created by a user
-
Query Parameters:
-
status
: Filter by status, use 'active' for all active tasks
-
-
Success Response: Status 200
{ "status": "success", "data": { "tasks": [ { /* Task object */ }, { /* Task object */ } ], "pagination": { "total_records": 10, "current_page": 1, "total_pages": 1, "next_page": null, "prev_page": null } } }
-
Endpoint:
POST /api/volunteers/
- Auth Required: Yes
- Description: Volunteer for a task
-
Request Body:
{ "task_id": 1 }
-
Success Response: Status 201
{ "status": "success", "message": "Successfully volunteered for the task.", "data": { "id": 1, "user": { /* User object */ }, "task": { /* Task object */ }, "status": "PENDING", "status_display": "Pending", "volunteered_at": "2025-05-15T12:00:00Z" } }
-
Endpoint:
GET /api/tasks/<task_id>/volunteers/
- Auth Required: Yes
- Description: View volunteers for a task
-
Query Parameters:
-
status
: Filter by volunteer status
-
-
Success Response: Status 200
{ "status": "success", "data": { "volunteers": [ { "id": 1, "user": { /* User object */ }, "task": { /* Task object */ }, "status": "PENDING", "status_display": "Pending", "volunteered_at": "2025-05-15T12:00:00Z" }, { "id": 2, "user": { /* User object */ }, "task": { /* Task object */ }, "status": "PENDING", "status_display": "Pending", "volunteered_at": "2025-05-15T12:30:00Z" } ], "pagination": { "total_records": 2, "current_page": 1, "total_pages": 1, "next_page": null, "prev_page": null } } }
-
Endpoint:
POST /api/tasks/<task_id>/volunteers/
- Auth Required: Yes
- Description: Accept or reject a volunteer for a task
-
Request Body:
{ "volunteer_id": 1, "action": "accept" // or "reject" }
-
Success Response: Status 200
{ "status": "success", "message": "Volunteer accepted successfully.", "data": { "id": 1, "user": { /* User object */ }, "task": { /* Task object */ }, "status": "ACCEPTED", "status_display": "Accepted", "volunteered_at": "2025-05-15T12:00:00Z" } }
-
Endpoint:
DELETE /api/volunteers/<volunteer_id>/
- Auth Required: Yes
- Description: Withdraw volunteer application
-
Success Response: Status 200
{ "status": "success", "message": "Volunteer application withdrawn successfully." }
-
Endpoint:
POST /api/reviews/
- Auth Required: Yes
- Description: Submit a review for a completed task
-
Request Body:
{ "score": 4.5, "comment": "Beatriz was very patient and helped me understand mobile banking very well", "reviewee_id": 2, "task_id": 1 }
-
Success Response: Status 201
{ "status": "success", "message": "Review submitted successfully.", "data": { "id": 1, "score": 4.5, "comment": "Beatriz was very patient and helped me understand mobile banking very well", "timestamp": "2025-05-15T17:00:00Z", "reviewer": { /* User object */ }, "reviewee": { /* User object */ }, "task": { /* Task object */ } } }
-
Endpoint:
GET /api/tasks/<task_id>/reviews/
- Auth Required: Yes
- Description: View all reviews for a task
-
Success Response: Status 200
{ "status": "success", "data": { "reviews": [ { "id": 1, "score": 4.5, "comment": "Beatriz was very patient and helped me understand mobile banking very well", "timestamp": "2025-05-15T17:00:00Z", "reviewer": { /* User object */ }, "reviewee": { /* User object */ }, "task": { /* Task object */ } }, { "id": 2, "score": 5.0, "comment": "Maria was a great learner and very attentive", "timestamp": "2025-05-15T17:30:00Z", "reviewer": { /* User object */ }, "reviewee": { /* User object */ }, "task": { /* Task object */ } } ], "pagination": { "total_records": 2, "current_page": 1, "total_pages": 1, "next_page": null, "prev_page": null } } }
-
Endpoint:
GET /api/users/<user_id>/reviews/
- Auth Required: Yes
- Description: View all reviews for a user
-
Query Parameters:
-
sort
: Sort by field (createdAt, score) -
order
: Sort order (asc, desc)
-
-
Success Response: Status 200
{ "status": "success", "data": { "reviews": [ { "id": 1, "score": 4.5, "comment": "Beatriz was very patient and helped me understand mobile banking very well", "timestamp": "2025-05-15T17:00:00Z", "reviewer": { /* User object */ }, "reviewee": { /* User object */ }, "task": { /* Task object */ } } ], "pagination": { "total_records": 1, "current_page": 1, "total_pages": 1, "next_page": null, "prev_page": null } } }
-
Endpoint:
PATCH /api/reviews/<review_id>/
- Auth Required: Yes
- Description: Update an existing review
-
Request Body:
{ "score": 5.0, "comment": "Beatriz was excellent! Very patient and helped me understand mobile banking perfectly" }
-
Success Response: Status 200
{ "status": "success", "message": "Review updated successfully.", "data": { "id": 1, "score": 5.0, "comment": "Beatriz was excellent! Very patient and helped me understand mobile banking perfectly", "timestamp": "2025-05-15T17:00:00Z", "reviewer": { /* User object */ }, "reviewee": { /* User object */ }, "task": { /* Task object */ } } }
-
Endpoint:
POST /api/tasks/<task_id>/photo/
- Auth Required: Yes
- Description: Attach a photo to a task
-
Request Body:
multipart/form-data
photo: <file>
-
Success Response: Status 201
{ "status": "success", "message": "Photo attached successfully.", "data": { "task_id": 1, "photo_id": 1, "photo_url": "http://localhost:8000/media/task_photos/1/photo.jpg", "uploaded_at": "2025-05-15T14:00:00Z" } }
-
Endpoint:
GET /api/tasks/<task_id>/photo/
- Auth Required: Yes
- Description: Get all photos for a task
-
Success Response: Status 200
{ "status": "success", "data": { "photos": [ { "id": 1, "url": "http://localhost:8000/media/task_photos/1/photo.jpg", "uploaded_at": "2025-05-15T14:00:00Z", "task": { /* Task object */ } } ] } }
-
Endpoint:
DELETE /api/tasks/<task_id>/photo/?photo_id=1
- Auth Required: Yes
- Description: Delete a photo from a task
-
Query Parameters:
-
photo_id
: ID of the photo to delete
-
-
Success Response: Status 204
{ "status": "success", "message": "Photo deleted successfully." }
-
Endpoint:
POST /api/bookmarks/
- Auth Required: Yes
- Description: Create a bookmark for a task
-
Request Body:
{ "task_id": 1, "tag_names": ["home_repair", "weekend"] }
-
Success Response: Status 201
{ "status": "success", "message": "Task bookmarked successfully.", "data": { "id": 1, "user": { /* User object */ }, "task": { /* Task object */ }, "timestamp": "2025-05-15T15:00:00Z", "tags": ["home_repair", "weekend"] } }
-
Endpoint:
GET /api/bookmarks/
- Auth Required: Yes
- Description: List all bookmarks for a user
-
Query Parameters:
-
tag
: Filter by tag
-
-
Success Response: Status 200
{ "status": "success", "data": { "bookmarks": [ { "id": 1, "user": { /* User object */ }, "task": { /* Task object */ }, "timestamp": "2025-05-15T15:00:00Z", "tags": ["home_repair", "weekend"] } ], "pagination": { "total_records": 1, "current_page": 1, "total_pages": 1, "next_page": null, "prev_page": null } } }
-
Endpoint:
PATCH /api/bookmarks/<bookmark_id>/
- Auth Required: Yes
- Description: Update tags for a bookmark
-
Request Body:
{ "add_tags": ["urgent"], "remove_tags": ["weekend"] }
-
Success Response: Status 200
{ "status": "success", "message": "Bookmark tags updated successfully.", "data": { "id": 1, "user": { /* User object */ }, "task": { /* Task object */ }, "timestamp": "2025-05-15T15:00:00Z", "tags": ["home_repair", "urgent"] } }
-
Endpoint:
DELETE /api/bookmarks/<bookmark_id>/
- Auth Required: Yes
- Description: Delete a bookmark
-
Success Response: Status 204
{ "status": "success", "message": "Bookmark removed successfully." }
-
Endpoint:
POST /api/comments/
- Auth Required: Yes
- Description: Add a comment to a task
-
Request Body:
{ "content": "Is this task still available?", "task_id": 1 }
-
Success Response: Status 201
{ "status": "success", "message": "Comment posted successfully.", "data": { "id": 1, "content": "Is this task still available?", "timestamp": "2025-05-15T16:00:00Z", "user": { /* User object */ }, "task": { /* Task object */ } } }
-
Endpoint:
GET /api/tasks/<task_id>/comments/
- Auth Required: Yes
- Description: View all comments for a task
-
Success Response: Status 200
{ "status": "success", "data": { "comments": [ { "id": 1, "content": "Is this task still available?", "timestamp": "2025-05-15T16:00:00Z", "user": { /* User object */ }, "task": { /* Task object */ } }, { "id": 2, "content": "Yes, the task is still available!", "timestamp": "2025-05-15T16:15:00Z", "user": { /* User object */ }, "task": { /* Task object */ } } ], "pagination": { "total_records": 2, "current_page": 1, "total_pages": 1, "next_page": null, "prev_page": null } } }
-
Endpoint:
PATCH /api/comments/<comment_id>/
- Auth Required: Yes
- Description: Update a comment
-
Request Body:
{ "content": "Yes, the task is still available and I'm looking for someone with experience!" }
-
Success Response: Status 200
{ "status": "success", "message": "Comment updated successfully.", "data": { "id": 2, "content": "Yes, the task is still available and I'm looking for someone with experience!", "timestamp": "2025-05-15T16:15:00Z", "user": { /* User object */ }, "task": { /* Task object */ } } }
-
Endpoint:
DELETE /api/comments/<comment_id>/
- Auth Required: Yes
- Description: Delete a comment
-
Success Response: Status 204
{ "status": "success", "message": "Comment deleted successfully." }
-
Endpoint:
GET /api/notifications/
- Auth Required: Yes
- Description: Get all notifications for a user
-
Query Parameters:
-
unread
: Set to 'true' to only get unread notifications
-
-
Success Response: Status 200
{ "status": "success", "data": { "notifications": [ { "id": 1, "content": "A new volunteer has applied for your task 'Help with Mobile Payments'", "timestamp": "2025-05-15T12:05:00Z", "type": "VOLUNTEER_APPLIED", "type_display": "Volunteer Applied", "is_read": false, "user": { /* User object */ }, "related_task": { /* Task object */ } } ], "pagination": { "total_records": 1, "current_page": 1, "total_pages": 1, "next_page": null, "prev_page": null }, "unread_count": 1 } }
-
Endpoint:
PATCH /api/notifications/<notification_id>/
- Auth Required: Yes
- Description: Mark a notification as read
-
Request Body:
{ "is_read": true }
-
Success Response: Status 200
{ "status": "success", "message": "Notification marked as read.", "data": { "id": 1, "content": "A new volunteer has applied for your task 'Help with Mobile Payments'", "timestamp": "2025-05-15T12:05:00Z", "type": "VOLUNTEER_APPLIED", "type_display": "Volunteer Applied", "is_read": true, "user": { /* User object */ }, "related_task": { /* Task object */ } } }
-
Endpoint:
POST /api/notifications/mark-all-read/
- Auth Required: Yes
- Description: Mark all notifications as read
-
Success Response: Status 200
{ "status": "success", "message": "5 notifications marked as read." }
-
Endpoint:
GET /api/admin/reported-users/
- Auth Required: Yes (Admin only)
- Description: Get a list of reported users
-
Success Response: Status 200
{ "status": "success", "data": { "users": [ { "user_id": 3, "username": "reporteduser", "reports": 2, "last_reported_at": "2025-05-14T09:30:00Z" } ], "pagination": { "total_records": 1, "current_page": 1, "total_pages": 1, "next_page": null, "prev_page": null } } }
-
Endpoint:
GET /api/admin/users/<user_id>/
- Auth Required: Yes (Admin only)
- Description: Get detailed information about a user
-
Success Response: Status 200
{ "status": "success", "data": { "user_id": 3, "username": "reporteduser", "email": "[email protected]", "status": "active", "reports": 2, "flagged_posts": [ { "task_id": 5, "created_at": "2025-05-14T08:00:00Z", "reason": "Inappropriate content" } ] } }
-
Endpoint:
PATCH /api/admin/users/<user_id>/ban/
- Auth Required: Yes (Admin only)
- Description: Ban a user
-
Request Body:
{ "reason": "Repeated violations of community guidelines" }
-
Success Response: Status 200
{ "status": "success", "message": "User banned successfully.", "data": { "user_id": 3, "new_status": "banned", "banned_at": "2025-05-15T18:00:00Z" } }
All endpoints follow a consistent error response format:
{
"status": "error",
"message": "Human-readable error message",
"data": {
// Optional error details or validation errors
}
}
Common HTTP status codes:
- 200: Success
- 201: Created
- 204: No Content (successful deletion)
- 400: Bad Request (validation error)
- 401: Unauthorized (authentication required)
- 403: Forbidden (insufficient permissions)
- 404: Not Found (resource doesn't exist)
- 500: Internal Server Error
You can use Postman to test the API. We have included several collections in the repository:
app/backend/core/tests/postman/
├── auth_task_tests.json
├── volunteer_review_tests.json
├── photo_bookmark_tests.json
└── profile_comment_manage_tests.json
These collections can be imported into Postman to test different aspects of the API functionality.