Base URL
https://api.forum.gutsylab.com/api
Authentication
This API uses Laravel Sanctum for authentication. After login/register, include the token in the header:
Authorization: Bearer {your_token}
Total Endpoints
🔐 Authentication
Register a new user account
Request Body:
{
"name": "John Doe",
"username": "johndoe",
"email": "john@example.com",
"password": "password123",
"password_confirmation": "password123",
"phone": "+6281234567890",
"address": "Jakarta, Indonesia"
}
📌 Note
phoneandaddressare optional fields
Response (201) - Success:
{
"success": true,
"message": "User registered successfully",
"data": {
"user": {
"id": 1,
"name": "John Doe",
"username": "johndoe",
"email": "john@example.com",
"emailVerifiedAt": null,
"profilePhoto": null,
"phone": null,
"address": null,
"createdAtFormatted": "26 Mar 2026, 10:00",
"createdAtAgo": "just now",
"updatedAtFormatted": "26 Mar 2026, 10:00",
"updatedAtAgo": "just now"
},
"accessToken": "1|abc123...",
"tokenType": "Bearer"
}
}
Response (200) - Validation Failed:
{
"success": false,
"message": "Registration validation failed",
"errors": {
"email": ["The email has already been taken."],
"username": ["The username has already been taken."]
}
}
Login to existing account
Request Body:
{
"email": "john@example.com",
"password": "password123"
}
Response (200) - Success:
{
"success": true,
"message": "Login successful",
"data": {
"user": {
"id": 1,
"name": "John Doe",
"username": "johndoe",
"email": "john@example.com",
"emailVerifiedAt": null,
"profilePhoto": "profile_photos/johndoe.jpg",
"createdAtFormatted": "01 Jan 2026, 00:00",
"createdAtAgo": "2 months ago",
"updatedAtFormatted": "26 Mar 2026, 10:00",
"updatedAtAgo": "just now"
},
"accessToken": "2|xyz789...",
"tokenType": "Bearer"
}
}
Response (200) - User Not Found:
{
"success": false,
"message": "User not found with this email."
}
Response (200) - Wrong Password:
{
"success": false,
"message": "Incorrect password."
}
Response (200) - Validation Failed:
{
"success": false,
"message": "Login validation failed",
"errors": {
"email": ["Email is required"]
}
}
Logout from current session
Headers:
Authorization: Bearer {token}
Response (200):
{
"success": true,
"message": "Logged out successfully"
}
Request password reset link to be sent to user's email
Request Body:
{
"email": "john@example.com"
}
Response (200) - Success:
{
"success": true,
"message": "Password reset link sent to your email"
}
Response (200) - Validation Failed:
{
"success": false,
"message": "Forgot password validation failed",
"errors": {
"email": ["No user found with this email address"]
}
}
📌 Note
- User will receive an email with password reset link
- Reset link contains a token that expires after a certain time
- Email must exist in the system
Reset user password using the token from email
Request Body:
{
"token": "reset_token_from_email",
"email": "john@example.com",
"password": "newpassword123",
"password_confirmation": "newpassword123"
}
Validation Rules:
token: required email: required, must be valid email password: required, minimum 8 characters, must match confirmation password_confirmation: required, must match password
Response (200) - Success:
{
"success": true,
"message": "Password reset successfully"
}
Response (422) - Validation Error:
{
"message": "The given data was invalid.",
"errors": {
"email": ["This password reset token is invalid."]
}
}
📌 Note
- Token must be valid and not expired
- Password must be at least 8 characters
- Password confirmation must match
- After successful reset, user must login with new password
📝 Topics
Get topics from users you follow and your own topics with pagination
Query Parameters:
page (optional): Page number for pagination
📌 Note
- Shows only topics from users you follow
- Also includes your own topics
- Use /topics/trending to see all trending topics
Response (200):
{
"success": true,
"data": {
"currentPage": 1,
"data": [
{
"id": 1,
"title": "Laravel Best Practices",
"body": "What are the best practices...",
"userId": 1,
"topicCategoryId": 1,
"createdAtFormatted": "26 Mar 2026, 10:00",
"createdAtAgo": "2 hours ago",
"updatedAtFormatted": "26 Mar 2026, 12:00",
"updatedAtAgo": "just now",
"commentsCount": 5,
"likesCount": 10,
"isLike": false,
"user": {
"id": 1,
"name": "John Doe",
"username": "johndoe",
"email": "john@example.com",
"emailVerifiedAt": null,
"profilePhoto": "profile_photos/johndoe.jpg",
"createdAtFormatted": "01 Jan 2026, 00:00",
"createdAtAgo": "2 months ago",
"updatedAtFormatted": "26 Mar 2026, 10:00",
"updatedAtAgo": "just now",
"profilePhotoUrl": "https://domain.com/storage/profile_photos/johndoe.jpg"
},
"category": {
"id": 1,
"name": "Laravel"
},
"comments": [...],
"likes": [...]
}
],
"perPage": 20,
"total": 50,
"lastPage": 3
}
}
Get top 10 trending topics with most comments
Response (200):
{
"success": true,
"data": [
{
"id": 1,
"title": "Laravel Best Practices",
"body": "What are the best practices...",
"userId": 1,
"topicCategoryId": 1,
"createdAtFormatted": "26 Mar 2026, 10:00",
"createdAtAgo": "2 hours ago",
"updatedAtFormatted": "26 Mar 2026, 12:00",
"updatedAtAgo": "just now",
"commentsCount": 25,
"likesCount": 10,
"isLiked": false,
"user": {
"id": 1,
"name": "John Doe",
"username": "johndoe",
"email": "john@example.com",
"emailVerifiedAt": null,
"profilePhoto": "profile_photos/johndoe.jpg",
"createdAtFormatted": "01 Jan 2026, 00:00",
"createdAtAgo": "2 months ago",
"updatedAtFormatted": "26 Mar 2026, 10:00",
"updatedAtAgo": "just now",
"profilePhotoUrl": "https://domain.com/storage/profile_photos/johndoe.jpg"
},
"category": {
"id": 1,
"name": "Laravel"
},
"likes": [...]
}
]
}
📌 Note
- Returns maximum 10 topics
- Sorted by comments count (descending)
- Includes all topic details with relationships
Get all distinct categories that have at least one topic, sorted alphabetically
Response (200) - Success:
{
"success": true,
"data": [
{
"id": 1,
"name": "JavaScript",
"topics_count": 8
},
{
"id": 2,
"name": "Laravel",
"topics_count": 12
},
{
"id": 3,
"name": "PHP",
"topics_count": 5
}
]
}
📌 Note
- Only returns categories that have at least one topic
- Sorted alphabetically by category name
- Includes
topics_countfor each category
Get paginated topics filtered by a specific category name
URL Parameters:
categoryName (required): The name of the category (e.g. Laravel, PHP, JavaScript)
Query Parameters:
page (optional): Page number for pagination
Example:
GET /topics/category/Laravel?page=1
Response (200) - Success:
{
"success": true,
"category": "Laravel",
"data": {
"currentPage": 1,
"data": [
{
"id": 1,
"title": "Laravel Best Practices",
"body": "What are the best practices...",
"userId": 1,
"topicCategoryId": 1,
"createdAtFormatted": "26 Mar 2026, 10:00",
"createdAtAgo": "2 hours ago",
"updatedAtFormatted": "26 Mar 2026, 12:00",
"updatedAtAgo": "just now",
"commentsCount": 5,
"likesCount": 10,
"isLiked": false,
"user": {
"id": 1,
"name": "John Doe",
"username": "johndoe",
"email": "john@example.com",
"profilePhotoUrl": "https://domain.com/storage/profile_photos/johndoe.jpg"
},
"category": {
"id": 1,
"name": "Laravel"
},
"comments": [...],
"likes": [...]
}
],
"perPage": 20,
"total": 30,
"lastPage": 2
}
}
Response (404) - Category Not Found:
{
"success": false,
"message": "Category not found"
}
📌 Note
- Category name is case-sensitive
- Returns 20 topics per page, sorted by latest
- Includes full topic details with user, category, comments, and likes
Create a new topic. Category will be created automatically if not exists.
Request Body:
{
"title": "Laravel Best Practices",
"body": "What are the best practices when using Laravel?",
"category_name": "Laravel"
}
Response (201) - Success:
{
"success": true,
"message": "Topic created successfully",
"data": {
"id": 1,
"title": "Laravel Best Practices",
"body": "What are the best practices when using Laravel?",
"userId": 1,
"topicCategoryId": 1,
"createdAt": "2026-03-26T10:00:00.000000Z",
"updatedAt": "2026-03-26T10:00:00.000000Z",
"user": {
"id": 1,
"name": "John Doe",
"username": "johndoe",
"email": "john@example.com"
},
"category": {
"id": 1,
"name": "Laravel"
}
}
}
Response (200) - Validation Error:
{
"success": false,
"message": "Validation error",
"errors": {
"title": ["The title field is required."],
"categoryName": ["The category name field is required."]
}
}
Get detailed information about a specific topic
Response (200) - Success:
{
"success": true,
"data": {
"id": 1,
"title": "Laravel Best Practices",
"body": "What are the best practices...",
"userId": 1,
"topicCategoryId": 1,
"createdAtFormatted": "26 Mar 2026, 10:00",
"createdAtAgo": "2 hours ago",
"updatedAtFormatted": "26 Mar 2026, 12:00",
"updatedAtAgo": "just now",
"commentsCount": 5,
"likesCount": 10,
"isLiked": false,
"user": {
"id": 1,
"name": "John Doe",
"username": "johndoe",
"email": "john@example.com",
"emailVerifiedAt": null,
"profilePhoto": "profile_photos/johndoe.jpg",
"createdAtFormatted": "01 Jan 2026, 00:00",
"createdAtAgo": "2 months ago",
"updatedAtFormatted": "26 Mar 2026, 10:00",
"updatedAtAgo": "just now",
"profilePhotoUrl": "https://domain.com/storage/profile_photos/johndoe.jpg"
},
"category": {
"id": 1,
"name": "Laravel"
},
"comments": [
{
"id": 1,
"topicId": 1,
"userId": 2,
"body": "Great question!",
"createdAtFormatted": "26 Mar 2026, 10:30",
"createdAtAgo": "30 minutes ago",
"updatedAtFormatted": "26 Mar 2026, 10:30",
"updatedAtAgo": "30 minutes ago",
"user": {
"id": 2,
"name": "Jane Doe",
"username": "janedoe",
"email": "jane@example.com",
"profilePhotoUrl": "https://domain.com/storage/profile_photos/janedoe.jpg"
}
}
],
"likes": [...]
}
}
Response (404) - Not Found:
{
"success": false,
"message": "Topic not found"
}
Update a topic. Only the owner can update their topic.
Request Body (all fields optional):
{
"title": "Updated Title",
"body": "Updated body content",
"category_name": "PHP"
}
Response (200) - Success:
{
"success": true,
"message": "Topic updated successfully",
"data": {
"id": 1,
"title": "Updated Title",
"body": "Updated body content",
"userId": 1,
"topicCategoryId": 2,
"createdAt": "2026-03-26T10:00:00.000000Z",
"updatedAt": "2026-03-26T12:00:00.000000Z",
"user": {
"id": 1,
"name": "John Doe",
"username": "johndoe",
"email": "john@example.com"
},
"category": {
"id": 2,
"name": "PHP"
}
}
}
Response (403) - Unauthorized:
{
"success": false,
"message": "Unauthorized to update this topic"
}
Response (404) - Not Found:
{
"success": false,
"message": "Topic not found"
}
Delete a topic. Only the owner can delete their topic.
Response (200) - Success:
{
"success": true,
"message": "Topic deleted successfully"
}
Response (403) - Unauthorized:
{
"success": false,
"message": "Unauthorized to delete this topic"
}
Response (404) - Not Found:
{
"success": false,
"message": "Topic not found"
}
💬 Comments
Get all comments for a specific topic
Response (200) - Success:
{
"success": true,
"data": {
"currentPage": 1,
"data": [
{
"id": 1,
"topicId": 1,
"userId": 2,
"body": "Great question!",
"createdAtAgo": "30 minutes ago",
"createdAtFormatted": "26 Mar 2026, 10:30",
"updatedAtAgo": "30 minutes ago",
"updatedAtFormatted": "26 Mar 2026, 10:30",
"user": {
"id": 2,
"name": "Jane Doe",
"email": "jane@example.com",
"username": "janedoe",
"profilePhotoUrl": "https://domain.com/storage/profile_photos/janedoe.jpg"
}
}
],
"perPage": 20,
"total": 10,
"lastPage": 1
}
}
Response (404) - Topic Not Found:
{
"success": false,
"message": "Topic not found"
}
Create a new comment on a topic
Request Body:
{
"body": "This is a great topic!"
}
Response (201) - Success:
{
"success": true,
"message": "Comment created successfully",
"data": {
"id": 1,
"topicId": 1,
"userId": 2,
"body": "This is a great topic!",
"createdAt": "2026-03-26T10:00:00.000000Z",
"updatedAt": "2026-03-26T10:00:00.000000Z",
"user": {
"id": 2,
"name": "Jane Doe",
"username": "janedoe",
"email": "jane@example.com",
"profilePhotoUrl": "https://domain.com/storage/profile_photos/janedoe.jpg"
}
}
}
Response (404) - Topic Not Found:
{
"success": false,
"message": "Topic not found"
}
Update a comment. Only the owner can update their comment.
Request Body:
{
"body": "Updated comment text"
}
Response (200) - Success:
{
"success": true,
"message": "Comment updated successfully",
"data": {
"id": 1,
"topicId": 1,
"userId": 2,
"body": "Updated comment text",
"createdAt": "2026-03-26T10:00:00.000000Z",
"updatedAt": "2026-03-26T12:00:00.000000Z",
"user": {
"id": 2,
"name": "Jane Doe",
"username": "janedoe",
"email": "jane@example.com",
"profilePhotoUrl": "https://domain.com/storage/profile_photos/janedoe.jpg"
}
}
}
Response (403) - Unauthorized:
{
"success": false,
"message": "Unauthorized to update this comment"
}
Response (404) - Not Found:
{
"success": false,
"message": "Comment not found"
}
Delete a comment. Only the owner can delete their comment.
Response (200) - Success:
{
"success": true,
"message": "Comment deleted successfully"
}
Response (403) - Unauthorized:
{
"success": false,
"message": "Unauthorized to delete this comment"
}
Response (404) - Not Found:
{
"success": false,
"message": "Comment not found"
}
❤️ Likes
Toggle like/unlike on a topic
Response (200) - Liked:
{
"success": true,
"message": "Topic liked successfully",
"data": {
"liked": true,
"likesCount": 11
}
}
Response (200) - Unliked:
{
"success": true,
"message": "Topic unliked successfully",
"data": {
"liked": false,
"likesCount": 10
}
}
Response (404) - Topic Not Found:
{
"success": false,
"message": "Topic not found"
}
Get list of users who liked a topic
Response (200) - Success:
{
"success": true,
"data": {
"currentPage": 1,
"data": [
{
"id": 2,
"name": "Jane Doe",
"username": "janedoe",
"email": "jane@example.com",
"createdAtFormatted": "01 Feb 2026, 14:30",
"createdAtAgo": "1 month ago",
"updatedAtFormatted": "10 Mar 2026, 09:15",
"updatedAtAgo": "3 days ago",
"profilePhotoUrl": "https://domain.com/storage/profile_photos/janedoe.jpg"
}
],
"perPage": 20,
"total": 11,
"lastPage": 1
}
}
Response (404) - Topic Not Found:
{
"success": false,
"message": "Topic not found"
}
👥 Users
Search users by username, email, or name
Query Parameters:
query (required): Search term page (optional): Page number
Example:
GET /users/search?query=john&page=1
Response (200) - Success:
{
"success": true,
"data": {
"currentPage": 1,
"data": [
{
"id": 2,
"name": "John Smith",
"username": "johnsmith",
"email": "johnsmith@example.com",
"createdAtFormatted": "15 Feb 2026, 10:00",
"createdAtAgo": "1 month ago",
"updatedAtFormatted": "12 Mar 2026, 14:20",
"updatedAtAgo": "1 day ago",
"isFollow": false,
"profilePhotoUrl": "https://domain.com/storage/profile_photos/johnsmith.jpg"
}
],
"perPage": 20,
"total": 5,
"lastPage": 1
}
}
Response (422) - Validation Error:
{
"success": false,
"message": "Query parameter is required"
}
📌 Note
- Searches in username, email, and name fields
- Results exclude the currently authenticated user
isFollowindicates if you're following that user- Returns 20 results per page
Get user profile with stats
Response (200):
{
"success": true,
"data": {
"id": 1,
"name": "John Doe",
"username": "johndoe",
"email": "john@example.com",
"emailVerifiedAt": null,
"profilePhoto": "profile_photos/johndoe.jpg",
"createdAtFormatted": "01 Jan 2026, 00:00",
"createdAtAgo": "2 months ago",
"updatedAtFormatted": "10 Mar 2026, 15:30",
"updatedAtAgo": "3 days ago",
"topicsCount": 15,
"followersCount": 20,
"followingCount": 10,
"isFollow": false,
"isYou": false,
"profilePhotoUrl": "https://domain.com/storage/profile_photos/johndoe.jpg"
}
}
Response (404) - User Not Found:
{
"success": false,
"message": "User not found"
}
📌 Note
isFollow: indicates if the authenticated user is following this profileisYou: true if viewing your own profile- Includes counts for topics, followers, and following
Follow a user
Response (200) - Success:
{
"success": true,
"message": "User followed successfully"
}
Response (422) - Already Following:
{
"success": false,
"message": "You are already following this user"
}
Response (422) - Cannot Follow Self:
{
"success": false,
"message": "You cannot follow yourself"
}
Response (404) - User Not Found:
{
"success": false,
"message": "User not found"
}
Unfollow a user
Response (200):
{
"success": true,
"message": "User unfollowed successfully"
}
Response (422) - Not Following:
{
"success": false,
"message": "You are not following this user"
}
Response (404) - User Not Found:
{
"success": false,
"message": "User not found"
}
Get list of user's followers with pagination
Query Parameters:
page (optional): Page number for pagination
Response (200):
{
"success": true,
"data": {
"currentPage": 1,
"data": [
{
"id": 2,
"name": "Jane Doe",
"username": "janedoe",
"email": "jane@example.com",
"createdAtFormatted": "01 Feb 2026, 14:30",
"createdAtAgo": "1 month ago",
"updatedAtFormatted": "10 Mar 2026, 09:15",
"updatedAtAgo": "3 days ago",
"isFollow": true,
"profilePhotoUrl": "https://domain.com/storage/profile_photos/janedoe.jpg"
}
],
"perPage": 20,
"total": 100,
"lastPage": 5
}
}
Response (404) - User Not Found:
{
"success": false,
"message": "User not found"
}
📌 Note
- Returns paginated list of followers (20 per page)
- Includes
isFollowfield indicating if you follow them back - Timestamps are formatted in both human-readable and relative formats
Get list of users that this user is following with pagination
Query Parameters:
page (optional): Page number for pagination
Response (200):
{
"success": true,
"data": {
"currentPage": 1,
"data": [
{
"id": 3,
"name": "Bob Smith",
"username": "bobsmith",
"email": "bob@example.com",
"createdAtFormatted": "15 Jan 2026, 08:00",
"createdAtAgo": "2 months ago",
"updatedAtFormatted": "12 Mar 2026, 16:45",
"updatedAtAgo": "1 day ago",
"isFollow": false,
"profilePhotoUrl": null
}
],
"perPage": 20,
"total": 50,
"lastPage": 3
}
}
Response (404) - User Not Found:
{
"success": false,
"message": "User not found"
}
📌 Note
- Returns paginated list of following (20 per page)
- Includes
isFollowfield indicating if you also follow them - Can view following list of any user
Get all topics created by a specific user with pagination
Query Parameters:
page (optional): Page number for pagination
📌 Note
- Shows all topics created by the specified user
- Can view topics from any user (not limited to following)
- Includes full topic details with user, category, comments, and likes
- Returns 20 topics per page
Response (200):
{
"success": true,
"data": {
"currentPage": 1,
"data": [
{
"id": 1,
"title": "Laravel Best Practices",
"body": "What are the best practices...",
"userId": 1,
"topicCategoryId": 1,
"createdAtFormatted": "13 Mar 2026, 10:30",
"createdAtAgo": "2 hours ago",
"updatedAtFormatted": "13 Mar 2026, 10:30",
"updatedAtAgo": "2 hours ago",
"commentsCount": 5,
"likesCount": 10,
"isLike": false,
"user": {
"id": 1,
"name": "John Doe",
"username": "johndoe",
"email": "john@example.com",
"createdAtFormatted": "01 Jan 2026, 00:00",
"createdAtAgo": "2 months ago",
"updatedAtFormatted": "13 Mar 2026, 10:30",
"updatedAtAgo": "2 hours ago",
"profilePhotoUrl": "https://domain.com/storage/profile_photos/johndoe.jpg"
},
"category": {
"id": 1,
"name": "Laravel"
},
"comments": [...],
"likes": [...]
}
],
"perPage": 20,
"total": 50,
"lastPage": 3
}
}
Response (404) - User Not Found:
{
"success": false,
"message": "User not found"
}
🖼️ Profile
Get the authenticated user's own profile with stats
Response (200):
{
"success": true,
"data": {
"id": 1,
"name": "John Doe",
"username": "johndoe",
"email": "john@example.com",
"emailVerifiedAt": null,
"profilePhoto": "profile_photos/johndoe.jpg",
"createdAtFormatted": "01 Jan 2026, 00:00",
"createdAtAgo": "2 months ago",
"updatedAtFormatted": "27 Mar 2026, 10:00",
"updatedAtAgo": "just now",
"topicsCount": 15,
"followersCount": 20,
"followingCount": 10,
"isFollow": false,
"isYou": true,
"profilePhotoUrl": "https://domain.com/storage/profile_photos/johndoe.jpg"
}
}
📌 Note
isYouwill always betruefor this endpoint- Response is identical to
GET /users/{id}for the authenticated user
Get the authenticated user's own followers list with pagination
Query Parameters:
page (optional): Page number for pagination
Response (200):
{
"success": true,
"data": {
"currentPage": 1,
"data": [
{
"id": 2,
"name": "Jane Doe",
"username": "janedoe",
"email": "jane@example.com",
"createdAtFormatted": "01 Feb 2026, 14:30",
"createdAtAgo": "1 month ago",
"updatedAtFormatted": "10 Mar 2026, 09:15",
"updatedAtAgo": "3 days ago",
"isFollow": true,
"profilePhotoUrl": "https://domain.com/storage/profile_photos/janedoe.jpg"
}
],
"perPage": 20,
"total": 100,
"lastPage": 5
}
}
📌 Note
- Response is identical to
GET /users/{id}/followersfor the authenticated user - Includes
isFollowfield indicating if you follow them back
Get the list of users that the authenticated user is following with pagination
Query Parameters:
page (optional): Page number for pagination
Response (200):
{
"success": true,
"data": {
"currentPage": 1,
"data": [
{
"id": 3,
"name": "Bob Smith",
"username": "bobsmith",
"email": "bob@example.com",
"createdAtFormatted": "15 Jan 2026, 08:00",
"createdAtAgo": "2 months ago",
"updatedAtFormatted": "12 Mar 2026, 16:45",
"updatedAtAgo": "1 day ago",
"isFollow": false,
"profilePhotoUrl": null
}
],
"perPage": 20,
"total": 50,
"lastPage": 3
}
}
📌 Note
- Response is identical to
GET /users/{id}/followingfor the authenticated user - Includes
isFollowfield indicating if you also follow them
Get all topics created by the authenticated user with pagination
Query Parameters:
page (optional): Page number for pagination
Response (200):
{
"success": true,
"data": {
"currentPage": 1,
"data": [
{
"id": 1,
"title": "Laravel Best Practices",
"body": "What are the best practices...",
"userId": 1,
"topicCategoryId": 1,
"createdAtFormatted": "13 Mar 2026, 10:30",
"createdAtAgo": "2 hours ago",
"updatedAtFormatted": "13 Mar 2026, 10:30",
"updatedAtAgo": "2 hours ago",
"commentsCount": 5,
"likesCount": 10,
"isLike": false,
"user": {
"id": 1,
"name": "John Doe",
"username": "johndoe",
"email": "john@example.com",
"createdAtFormatted": "01 Jan 2026, 00:00",
"createdAtAgo": "2 months ago",
"updatedAtFormatted": "13 Mar 2026, 10:30",
"updatedAtAgo": "2 hours ago",
"profilePhotoUrl": "https://domain.com/storage/profile_photos/johndoe.jpg"
},
"category": {
"id": 1,
"name": "Laravel"
},
"comments": [...],
"likes": [...]
}
],
"perPage": 20,
"total": 50,
"lastPage": 3
}
}
📌 Note
- Response is identical to
GET /users/{id}/topicsfor the authenticated user - Includes full topic details with user, category, comments, and likes
- Returns 20 topics per page
Upload or replace the authenticated user's profile photo
Request Body (multipart/form-data):
photo: (file) jpeg/png/jpg/gif, max 2MB
Response (200) - Success:
{
"success": true,
"message": "Profile photo uploaded successfully",
"data": {
"profilePhoto": "profile_photos/johndoe.jpg",
"profilePhotoUrl": "https://domain.com/storage/profile_photos/johndoe.jpg"
}
}
Response (422) - Validation Error:
{
"message": "The photo field is required.",
"errors": {
"photo": ["The photo must be an image.", "The photo must not be greater than 2048 kilobytes."]
}
}
📌 Note
- Accepted formats: jpeg, png, jpg, gif
- Maximum file size: 2MB
- Previous photo is automatically deleted when a new one is uploaded
- Filename is set to
{username}.{extension}
📌 Important Notes
- All endpoints requiring authentication must include
Authorization: Bearer {token}header - Default pagination is 20 items per page
- Only topic/comment owners can update or delete their content
- Categories are automatically created when creating a topic
- Like endpoint uses toggle mechanism (same endpoint for like/unlike)
- Users cannot follow themselves
- Search excludes the currently logged-in user
- All response keys are in camelCase
profilePhotoUrlis the full URL to the profile photo,profilePhotois the raw storage path- GET /topics only shows topics from users you follow and your own topics
- GET /topics/trending shows top 10 topics with most comments from all users
- GET /users/{id}/topics shows all topics created by a specific user (any user, not limited to following)