diff --git a/Constants.cs b/Constants.cs
index 76bfeffc2dfb729690df6defb13280c0ff65e8e5..9c5d77e5f03d0576292852ed32d6ea59983e5ab9 100644
--- a/Constants.cs
+++ b/Constants.cs
@@ -21,6 +21,7 @@ public class Constants
 
     public static class AzureBlobContainer
     {
+        public const string ProfilePictures = "profile-pictures";
         public const string BannerPictures = "banner-pictures";
     }
 
diff --git a/Controllers/ProfileController.cs b/Controllers/ProfileController.cs
index 7247d8fbffaf4a4b8b83e871086c077960d13dd2..ab7bb128f04d2275cd39f3cafb53c568f080e78f 100644
--- a/Controllers/ProfileController.cs
+++ b/Controllers/ProfileController.cs
@@ -1,5 +1,6 @@
 namespace Group17profile.Controllers;
 
+using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Mvc;
 using Middleware;
 using Models.DTOs;
@@ -24,7 +25,7 @@ public class ProfileController : DefaultAuthenticationController
     {
         try
         {
-            return Ok(await _profileService.GetProfileForUser(1));
+            return Ok(await _profileService.GetProfileForUser(UserId));
         }
         catch (Exception ex)
         {
@@ -48,12 +49,53 @@ public class ProfileController : DefaultAuthenticationController
         }
     }
 
-    [HttpPost("UploadBannerPicture")]
+    [HttpPost("UploadProfilePicture")]
     [Consumes("multipart/form-data")]
-    public async Task<ActionResult<ResponseEnvelope<ProfileDTO>>> UploadBannerPicture(IFormFile? profilePicture)
+    public async Task<ActionResult<ResponseEnvelope<ProfileDTO>>> UploadProfilePicture(IFormFile? profilePicture)
     {
         if (profilePicture == null)
             return BadRequest("Please upload a file.");
-        return Ok(await _profileService.UploadBannerPicture(UserId, profilePicture));
+        return Ok(await _profileService.UploadProfilePicture(UserId, profilePicture));
+    }
+
+    [HttpPost("UploadBannerPicture")]
+    [Consumes("multipart/form-data")]
+    public async Task<ActionResult<ResponseEnvelope<ProfileDTO>>> UploadBannerPicture(IFormFile? bannerPicture)
+    {
+        if (bannerPicture == null)
+            return BadRequest("Please upload a file.");
+        return Ok(await _profileService.UploadBannerPicture(UserId, bannerPicture));
+    }
+
+    [HttpGet("GetProfileByUserId")]
+    [SwaggerResponse(200, Type = typeof(ResponseEnvelope<ProfileDTO>))]
+    [SwaggerResponse(400, Type = typeof(ResponseEnvelope<BadRequestObjectResult>))]
+    [AllowAnonymous]
+    public async Task<ActionResult<ResponseEnvelope<ProfileDTO>>> GetProfileByUserId(int userId)
+    {
+        try
+        {
+            return Ok(await _profileService.GetProfileForUser(userId));
+        }
+        catch (Exception ex)
+        {
+            return BadRequest(ex.Message);
+        }
+    }
+
+    [HttpPost("GetProfilesByUserIds")]
+    [SwaggerResponse(200, Type = typeof(ResponseEnvelope<List<ProfileDTO>>))]
+    [SwaggerResponse(400, Type = typeof(ResponseEnvelope<BadRequestObjectResult>))]
+    [AllowAnonymous]
+    public async Task<ActionResult<ResponseEnvelope<List<ProfileDTO>>>> GetProfilesByUserIds(List<int> userIds)
+    {
+        try
+        {
+            return Ok(await _profileService.GetProfilesByUserIds(userIds));
+        }
+        catch (Exception ex)
+        {
+            return BadRequest(ex.Message);
+        }
     }
 }
\ No newline at end of file
diff --git a/Models/DTOs/ProfileDTO.cs b/Models/DTOs/ProfileDTO.cs
index cc4627e6320b7a4bf96a596ece65667e6081e77f..a50dac3c2101f15c37c49d1be9ef0fba34bc92ca 100644
--- a/Models/DTOs/ProfileDTO.cs
+++ b/Models/DTOs/ProfileDTO.cs
@@ -7,6 +7,7 @@ public class ProfileDTO : DefaultGuidDTO
     public int? UserId { get; set; }
     public string? Biography { get; set; }
 
+    public string? ProfilePictureUrl { get; set; }
     public string? BannerUrl { get; set; }
 
     public string? Gender { get; set; }
diff --git a/Models/Entities/Profile.cs b/Models/Entities/Profile.cs
index d49e7cd9f04640b41088533a766e9ab2a88b6d84..f9723365352a776fbd2d968f05c3ffe5d4883956 100644
--- a/Models/Entities/Profile.cs
+++ b/Models/Entities/Profile.cs
@@ -7,6 +7,7 @@ public class Profile : DefaultGuidEntity
     public int? UserId { get; set; }
     public string? Biography { get; set; }
 
+    public string? ProfilePictureUrl { get; set; }
     public string? BannerUrl { get; set; }
 
     public string? Gender { get; set; }
diff --git a/Repositories/ProfileRepository.cs b/Repositories/ProfileRepository.cs
index 52ddf97be8406c2e602b6825f95dfaed8fec6b57..f62ae8a7abbb55c2de5dd18501d2e7f9eedc8143 100644
--- a/Repositories/ProfileRepository.cs
+++ b/Repositories/ProfileRepository.cs
@@ -9,24 +9,24 @@ public interface IProfileRepository
 {
     Task<Profile> CreateProfileAsync(Profile profile);
     Task<Profile?> GetProfileAsync(int userId);
+    Task<List<Profile>> GetProfilesByUserIds(List<int> userIds);
     Task<Profile> UpdateProfileAsync(int userId, string profileId, Profile profile);
     Task DeleteProfileAsync(int userId, string profileId);
-    Task<IEnumerable<Profile?>> GetProfilesByMoodAsync(string mood);
 }
 
 public class ProfileRepository : IProfileRepository
 {
-    private readonly Container? _profileDetailsContainer;
+    private readonly Container? _profileContainer;
 
     public ProfileRepository(ProfileDbContext context)
     {
-        _profileDetailsContainer = context.Profile;
+        _profileContainer = context.Profile;
     }
 
     public async Task<Profile> CreateProfileAsync(Profile profile)
     {
         var response =
-            await _profileDetailsContainer?.CreateItemAsync(profile,
+            await _profileContainer?.CreateItemAsync(profile,
                 new PartitionKey(profile.UserId.GetValueOrDefault()))!;
         return response.Resource;
     }
@@ -38,7 +38,7 @@ public class ProfileRepository : IProfileRepository
             var query = new QueryDefinition("SELECT * FROM c WHERE c.UserId = @UserId")
                 .WithParameter("@UserId", userId);
 
-            var iterator = _profileDetailsContainer?.GetItemQueryIterator<Profile>(query);
+            var iterator = _profileContainer?.GetItemQueryIterator<Profile>(query);
 
             if (iterator is {HasMoreResults: false}) return null;
             var response = await iterator.ReadNextAsync();
@@ -50,31 +50,41 @@ public class ProfileRepository : IProfileRepository
         }
     }
 
-    public async Task<Profile> UpdateProfileAsync(int userId, string profileId, Profile profile)
+    public async Task<List<Profile>> GetProfilesByUserIds(List<int> userIds)
     {
-        var response = await _profileDetailsContainer.ReplaceItemAsync(profile, profileId, new PartitionKey(userId));
-        return response.Resource;
-    }
+        try
+        {
+            var userIdsString = string.Join(",", userIds);
+            var queryString = $"SELECT * FROM c WHERE c.UserId IN ({userIdsString})";
+            var query = new QueryDefinition(queryString);
 
-    public async Task DeleteProfileAsync(int userId, string profileId)
-    {
-        await _profileDetailsContainer.DeleteItemAsync<Profile>(profileId, new PartitionKey(userId));
-    }
+            var iterator = _profileContainer?.GetItemQueryIterator<Profile>(query);
 
-    public async Task<IEnumerable<Profile?>> GetProfilesByMoodAsync(string mood)
-    {
-        var query = new QueryDefinition("SELECT * FROM c WHERE c.Mood = @mood")
-            .WithParameter("@mood", mood);
+            if (iterator is {HasMoreResults: false}) return new List<Profile>();
+            var profiles = new List<Profile>();
 
-        var iterator = _profileDetailsContainer?.GetItemQueryIterator<Profile>(query);
+            while (iterator is {HasMoreResults: true})
+            {
+                var response = await iterator.ReadNextAsync();
+                profiles.AddRange(response);
+            }
 
-        var profiles = new List<Profile>();
-        while (iterator.HasMoreResults)
+            return profiles;
+        }
+        catch (CosmosException ex) when (ex.StatusCode == HttpStatusCode.NotFound)
         {
-            var response = await iterator.ReadNextAsync();
-            profiles.AddRange(response);
+            return new List<Profile>();
         }
+    }
+
+    public async Task<Profile> UpdateProfileAsync(int userId, string profileId, Profile profile)
+    {
+        var response = await _profileContainer.ReplaceItemAsync(profile, profileId, new PartitionKey(userId));
+        return response.Resource;
+    }
 
-        return profiles;
+    public async Task DeleteProfileAsync(int userId, string profileId)
+    {
+        await _profileContainer.DeleteItemAsync<Profile>(profileId, new PartitionKey(userId));
     }
 }
\ No newline at end of file
diff --git a/Services/ProfileService.cs b/Services/ProfileService.cs
index 3c741e3b524cf6ebb8a678fa2b63109c3077fe5a..9a21ec05f7ffabe7273961c306d78d6ef530dd22 100644
--- a/Services/ProfileService.cs
+++ b/Services/ProfileService.cs
@@ -10,7 +10,9 @@ using Profile = Models.Entities.Profile;
 public interface IProfileService
 {
     Task<ProfileDTO> GetProfileForUser(int userId);
+    Task<List<ProfileDTO>> GetProfilesByUserIds(List<int> userIds);
     Task<ProfileDTO> CreateOrUpdateProfile(ProfileDTO profile, int userId);
+    Task<ProfileDTO> UploadProfilePicture(int userId, IFormFile profilePicture);
     Task<ProfileDTO> UploadBannerPicture(int userId, IFormFile bannerPicture);
 }
 
@@ -32,6 +34,9 @@ public class ProfileService : IProfileService
         var profile = await _profileRepository.GetProfileAsync(userId);
         if (profile == null)
             throw new ProfileException("Profile does not exist.");
+        if (!string.IsNullOrWhiteSpace(profile.ProfilePictureUrl))
+            profile.ProfilePictureUrl +=
+                _storageService.GetSasForFile(Constants.AzureBlobContainer.ProfilePictures, profile.ProfilePictureUrl);
         if (!string.IsNullOrWhiteSpace(profile.BannerUrl))
             profile.BannerUrl +=
                 _storageService.GetSasForFile(Constants.AzureBlobContainer.BannerPictures, profile.BannerUrl);
@@ -47,6 +52,13 @@ public class ProfileService : IProfileService
         var age = DateTimeOffset.Now.Year - profile.DoB.GetValueOrDefault().Year;
         if (age is <= 16 or >= 100)
             throw new ProfileException("Please enter valid age.");
+        if (!string.IsNullOrWhiteSpace(profile.ProfilePictureUrl))
+        {
+            var profilePictureUri = new Uri(profile.ProfilePictureUrl);
+            if (!string.IsNullOrWhiteSpace(profilePictureUri.Query))
+                profile.ProfilePictureUrl = profile.ProfilePictureUrl.Replace(profilePictureUri.Query, "");
+        }
+
         if (!string.IsNullOrWhiteSpace(profile.BannerUrl))
         {
             var bannerUri = new Uri(profile.BannerUrl);
@@ -55,6 +67,15 @@ public class ProfileService : IProfileService
         }
 
         var record = _mapper.Map<Profile>(profile);
+        if (profile.FavouriteShows != null && profile.FavouriteShows.Count != 0)
+        {
+            var builder = new StringBuilder();
+            foreach (var show in profile.FavouriteShows)
+                builder.Append($"{show},");
+
+            record.FavouriteShows = builder.ToString();
+        }
+
         var existing = await _profileRepository.GetProfileAsync(userId);
         if (existing == null)
         {
@@ -68,14 +89,9 @@ public class ProfileService : IProfileService
             record = await _profileRepository.UpdateProfileAsync(userId, record.Id.ToString(), record);
         }
 
-        if (profile.FavouriteShows != null && profile.FavouriteShows.Count != 0)
-        {
-            var builder = new StringBuilder();
-            foreach (var show in profile.FavouriteShows)
-                builder.Append($"{show},");
-
-            record.FavouriteShows = builder.ToString();
-        }
+        if (!string.IsNullOrWhiteSpace(record.ProfilePictureUrl))
+            record.ProfilePictureUrl +=
+                _storageService.GetSasForFile(Constants.AzureBlobContainer.ProfilePictures, record.ProfilePictureUrl);
 
         if (!string.IsNullOrWhiteSpace(record.BannerUrl))
             record.BannerUrl +=
@@ -84,6 +100,31 @@ public class ProfileService : IProfileService
         return _mapper.Map<ProfileDTO>(record);
     }
 
+    public async Task<ProfileDTO> UploadProfilePicture(int userId, IFormFile profilePicture)
+    {
+        var profile = await _profileRepository.GetProfileAsync(userId);
+        using var ms = new MemoryStream();
+        await profilePicture.CopyToAsync(ms);
+        ms.Position = 0;
+        var fileName = $"{userId}/{profilePicture.Name}";
+        var image = await _storageService.SaveImageAsJpgBlob(Constants.AzureBlobContainer.ProfilePictures, fileName,
+            ms);
+        if (profile == null)
+        {
+            profile = new Profile {ProfilePictureUrl = image.ToString(), Id = Guid.NewGuid(), UserId = userId};
+            profile = await _profileRepository.CreateProfileAsync(profile);
+        }
+        else
+        {
+            profile.ProfilePictureUrl = image.ToString();
+            profile = await _profileRepository.UpdateProfileAsync(userId, profile.Id.ToString(), profile);
+        }
+
+        profile.ProfilePictureUrl +=
+            _storageService.GetSasForFile(Constants.AzureBlobContainer.ProfilePictures, image.ToString());
+        return _mapper.Map<ProfileDTO>(profile);
+    }
+
     public async Task<ProfileDTO> UploadBannerPicture(int userId, IFormFile bannerPicture)
     {
         var profile = await _profileRepository.GetProfileAsync(userId);
@@ -94,7 +135,7 @@ public class ProfileService : IProfileService
         var image = await _storageService.SaveImageAsJpgBlob(Constants.AzureBlobContainer.BannerPictures, fileName, ms);
         if (profile == null)
         {
-            profile = new Profile {BannerUrl = image.ToString(), UserId = userId};
+            profile = new Profile {BannerUrl = image.ToString(), Id = Guid.NewGuid(), UserId = userId};
             profile = await _profileRepository.CreateProfileAsync(profile);
         }
         else
@@ -107,4 +148,23 @@ public class ProfileService : IProfileService
             _storageService.GetSasForFile(Constants.AzureBlobContainer.BannerPictures, image.ToString());
         return _mapper.Map<ProfileDTO>(profile);
     }
+
+    public async Task<List<ProfileDTO>> GetProfilesByUserIds(List<int> userIds)
+    {
+        var profiles = await _profileRepository.GetProfilesByUserIds(userIds);
+        var mapped = _mapper.ProjectTo<ProfileDTO>(profiles.AsQueryable()).ToList();
+        if (profiles.Count == 0) return mapped;
+        foreach (var profile in mapped)
+        {
+            if (!string.IsNullOrWhiteSpace(profile.ProfilePictureUrl))
+                profile.ProfilePictureUrl +=
+                    _storageService.GetSasForFile(Constants.AzureBlobContainer.ProfilePictures,
+                        profile.ProfilePictureUrl);
+            if (!string.IsNullOrWhiteSpace(profile.BannerUrl))
+                profile.BannerUrl +=
+                    _storageService.GetSasForFile(Constants.AzureBlobContainer.BannerPictures, profile.BannerUrl);
+        }
+
+        return mapped;
+    }
 }
\ No newline at end of file