diff --git a/Tsi1.Api/Tsi1.Api/Controllers/CommunicationController.cs b/Tsi1.Api/Tsi1.Api/Controllers/CommunicationController.cs
new file mode 100644
index 0000000000000000000000000000000000000000..7cdda5f21891cb2f1727dc66ec91cfe8e1b486a3
--- /dev/null
+++ b/Tsi1.Api/Tsi1.Api/Controllers/CommunicationController.cs
@@ -0,0 +1,99 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Claims;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Tsi1.BusinessLayer.Dtos;
+using Tsi1.BusinessLayer.Helpers;
+using Tsi1.BusinessLayer.Interfaces;
+
+namespace Tsi1.Api.Controllers
+{
+    [Route("api/[controller]")]
+    [ApiController]
+    public class CommunicationController : ControllerBase
+    {
+        private readonly ICommunicationService _communicationService;
+
+        public CommunicationController(ICommunicationService communicationService)
+        {
+            _communicationService = communicationService;
+        }
+
+        [Authorize(Roles = UserTypes.FacultyAdmin + ", " + UserTypes.UdelarAdmin)]
+        [HttpPost("CreateCourseCommunication/{courseId}")]
+        public async Task<IActionResult> CreateCourseCommunication(CommunicationCreateDto newCommunication, int courseId)
+        {
+            var tenantId = int.Parse(HttpContext.User.Claims.FirstOrDefault(x => x.Type == "TenantId").Value);
+            var validationResult = await _communicationService.TenantValidation(tenantId, courseId);
+
+            if (validationResult.HasError)
+            {
+                return BadRequest(validationResult.Message);
+            }
+
+            var result = await _communicationService.Create(newCommunication, courseId);
+
+            if (result.HasError)
+            {
+                return BadRequest(result.Message);
+            }
+
+            return Ok();
+        }
+
+        [Authorize(Roles = UserTypes.FacultyAdmin + ", " + UserTypes.UdelarAdmin)]
+        [HttpPost("CreateTenantCommunication")]
+        public async Task<IActionResult> CreateTenantCommunication(CommunicationCreateDto newCommunication, int tenantId)
+        {
+            var userType = HttpContext.User.Claims.FirstOrDefault(x => x.Type == ClaimTypes.Role).Value;
+            if (userType == UserTypes.FacultyAdmin)
+            {
+                tenantId = int.Parse(HttpContext.User.Claims.FirstOrDefault(x => x.Type == "TenantId").Value);
+            }
+
+            newCommunication.IsGlobal = true;
+            var result = await _communicationService.Create(newCommunication, tenantId);
+
+            if (result.HasError)
+            {
+                return BadRequest(result.Message);
+            }
+
+            return Ok();
+        }
+
+        [Authorize(Roles = UserTypes.Student)]
+        [HttpGet("GetMyCommunications")]
+        public async Task<IActionResult> GetMyCommunications()
+        {
+            var userId = int.Parse(HttpContext.User.Claims.FirstOrDefault(x => x.Type == "Id").Value);
+
+            var result = await _communicationService.GetMyCommunications(userId);
+
+            if (result.HasError)
+            {
+                return BadRequest(result.Message);
+            }
+
+            return Ok(result.Data);
+        }
+
+        [Authorize(Roles = UserTypes.FacultyAdmin + ", " + UserTypes.UdelarAdmin)]
+        [HttpDelete("Delete/{communicationId}")]
+        public async Task<IActionResult> Delete(int communicationId)
+        {
+            var result = await _communicationService.Delete(communicationId);
+
+            if (result.HasError)
+            {
+                return BadRequest(result.Message);
+            }
+
+            return Ok();
+        }
+    }
+}
diff --git a/Tsi1.Api/Tsi1.Api/Startup.cs b/Tsi1.Api/Tsi1.Api/Startup.cs
index 369da763de4eb9e1b36021dafd89bb2e15651955..d6ded58781ccb783a67987c34c64e5e00e7247b8 100644
--- a/Tsi1.Api/Tsi1.Api/Startup.cs
+++ b/Tsi1.Api/Tsi1.Api/Startup.cs
@@ -92,6 +92,7 @@ namespace Tsi1.Api
             services.AddScoped<ISectionItemTypeService, SectionItemTypeService>();
             services.AddScoped<IDataLoad, DataLoad>();
             services.AddScoped<ISurveyService, SurveyService>();
+            services.AddScoped<ICommunicationService, CommunicationService>();
 
             services.Configure<MailSettings>(Configuration.GetSection("MailSettings"));
             services.AddScoped<IEmailService, EmailService>();
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Dtos/CommunicationCreateDto.cs b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/CommunicationCreateDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..24f82ce35ee326a372b7ed5ac182fa25c546816b
--- /dev/null
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/CommunicationCreateDto.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Text.Json.Serialization;
+
+namespace Tsi1.BusinessLayer.Dtos
+{
+    public class CommunicationCreateDto
+    {
+        public string Text { get; set; }
+
+        [JsonIgnore]
+        public bool IsGlobal { get; set; }
+
+        public DateTime ValidUntil { get; set; }
+    }
+}
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Dtos/CommunicationPreviewDto.cs b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/CommunicationPreviewDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..6945046e32173939c506438bacf7e0d706e293ef
--- /dev/null
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/CommunicationPreviewDto.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tsi1.BusinessLayer.Dtos
+{
+    public class CommunicationPreviewDto
+    {
+        public int Id { get; set; }
+
+        public string Text { get; set; }
+    }
+}
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ErrorMessages.cs b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ErrorMessages.cs
index c61742af40d30ff6d921347d857a16d4487272e6..b049c0244d6ec63c379544c1c0da7f90a475a6ad 100644
--- a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ErrorMessages.cs
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ErrorMessages.cs
@@ -61,5 +61,8 @@ namespace Tsi1.BusinessLayer.Helpers
         public const string SurveyHasNoQuestions = "La encuesta no tiene preguntas";
         public const string InvalidSurvey = "La encuesta no pertenece a la facultad con id '{0}'";
         public const string SurveyResponseAlreadyExist = "El usuario '{0}' ya completo la encuesta '{1}'";
+
+        public const string CommunicationDoesNotExist = "La comunicación con id '{0}' no existe";
+        public const string InvalidTenant = "El usuario no pertenece a la facultad con id '{0}'";
     }
 }
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/MappingProfile.cs b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/MappingProfile.cs
index d7f378c5c8514fd0686903f929573bc0ccf71795..2793c823175e8474e98d39514c7789927d23a2a0 100644
--- a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/MappingProfile.cs
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/MappingProfile.cs
@@ -49,6 +49,8 @@ namespace Tsi1.BusinessLayer.Helpers
             CreateMap<SurveyResponse, SurveyResponseDetailDto>();
             CreateMap<SurveyAnswer, SurveyAnswerDetailDto>();
             CreateMap<SurveyAnswer, SurveyAnswerCreateDto>();
+            CreateMap<Communication, CommunicationCreateDto>();
+            CreateMap<Communication, CommunicationPreviewDto>();
 
             CreateMap<ForumCreateDto, Forum>();
             CreateMap<ForumPreviewDto, Forum>();
@@ -87,6 +89,8 @@ namespace Tsi1.BusinessLayer.Helpers
             CreateMap<SurveyResponseDetailDto, SurveyResponse>();
             CreateMap<SurveyAnswerDetailDto, SurveyAnswer>();
             CreateMap<SurveyAnswerCreateDto, SurveyAnswer>();
+            CreateMap<CommunicationCreateDto, Communication>();
+            CreateMap<CommunicationPreviewDto, Communication>();
         }
     }
 }
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/ICommunicationService.cs b/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/ICommunicationService.cs
new file mode 100644
index 0000000000000000000000000000000000000000..ce39e10fe3c8219d4b17d1316779a3b066027cdc
--- /dev/null
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/ICommunicationService.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using Tsi1.BusinessLayer.Dtos;
+using Tsi1.BusinessLayer.Helpers;
+
+namespace Tsi1.BusinessLayer.Interfaces
+{
+    public interface ICommunicationService
+    {
+        Task<ServiceResult<bool>> Create(CommunicationCreateDto newCommunication, int id);
+
+        Task<ServiceResult<bool>> Delete(int communicationId);
+
+        Task<ServiceResult<List<CommunicationPreviewDto>>> GetMyCommunications(int userId);
+
+        Task<ServiceResult<bool>> TenantValidation(int tenantId, int courseId);
+    }
+}
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Services/CommunicationService.cs b/Tsi1.Api/Tsi1.BusinessLayer/Services/CommunicationService.cs
new file mode 100644
index 0000000000000000000000000000000000000000..9f7e31be67ce597fbf52dd4a9af7ff9dfcb616a1
--- /dev/null
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Services/CommunicationService.cs
@@ -0,0 +1,139 @@
+using AutoMapper;
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tsi1.BusinessLayer.Dtos;
+using Tsi1.BusinessLayer.Helpers;
+using Tsi1.BusinessLayer.Interfaces;
+using Tsi1.DataLayer;
+using Tsi1.DataLayer.Entities;
+
+namespace Tsi1.BusinessLayer.Services
+{
+    public class CommunicationService : ICommunicationService
+    {
+        private readonly Tsi1Context _context;
+        private readonly IMapper _mapper;
+
+        public CommunicationService(Tsi1Context context, IMapper mapper)
+        {
+            _context = context;
+            _mapper = mapper;
+        }
+
+        public async Task<ServiceResult<bool>> Create(CommunicationCreateDto newCommunication, int id)
+        {
+            var result = new ServiceResult<bool>();
+            var isGlobal = newCommunication.IsGlobal;
+            var commmunication = _mapper.Map<Communication>(newCommunication);
+
+            var validationResult = await this.CreateValidation(id, isGlobal, commmunication);
+
+            if (validationResult.HasError)
+            {
+                return validationResult;
+            }
+
+            _context.Communications.Add(commmunication);
+
+            await _context.SaveChangesAsync();
+
+            return result;
+        }
+
+        public async Task<ServiceResult<bool>> Delete(int communicationId)
+        {
+            var result = new ServiceResult<bool>();
+            var commmunication = await _context.Communications.FirstOrDefaultAsync(x => x.Id == communicationId);
+
+            if (commmunication == null)
+            {
+                result.HasError = true;
+                result.AddMessage(string.Format(ErrorMessages.CommunicationDoesNotExist, communicationId));
+                return result;
+            }
+
+            _context.Communications.Remove(commmunication);
+            await _context.SaveChangesAsync();
+
+            return result;
+        }
+
+        public async Task<ServiceResult<List<CommunicationPreviewDto>>> GetMyCommunications(int userId)
+        {
+            var result = new ServiceResult<List<CommunicationPreviewDto>>();
+            var user = await _context.Users.AsNoTracking().FirstOrDefaultAsync(x => x.Id == userId);
+
+            var courseIds = await _context.StudentCourses
+                .AsNoTracking()
+                .Where(x => x.StudentId == user.StudentId)
+                .Select(x => x.CourseId)
+                .ToListAsync();
+
+            var communications = await _context.Communications
+                .AsNoTracking()
+                .Include(x => x.Tenant)
+                .Include(x => x.Course)
+                .Where(x => (x.Tenant.Id == userId || courseIds.Contains(x.Course.Id))
+                    && x.ValidUntil >= DateTime.Now)
+                .ToListAsync();
+
+            result.Data = _mapper.Map<List<CommunicationPreviewDto>>(communications);
+
+            return result;
+        }
+
+        public async Task<ServiceResult<bool>> TenantValidation(int tenantId, int courseId)
+        {
+            var result = new ServiceResult<bool>();
+
+            var tenantAdmin = await _context.Tenants.AsNoTracking().FirstOrDefaultAsync(x => x.Name == TenantAdmin.Name);
+            var course = await _context.Courses.AsNoTracking().FirstOrDefaultAsync(x => x.Id == courseId);
+
+            if (tenantAdmin.Id != tenantId)
+            {
+                result.HasError = course.TenantId != tenantId;
+                result.AddMessage(string.Format(ErrorMessages.InvalidTenant, course.TenantId));
+            }
+
+            return result;
+        }
+
+        private async Task<ServiceResult<bool>> CreateValidation(int id, bool isGlobal, Communication commmunication)
+        {
+            var result = new ServiceResult<bool>();
+
+            if (isGlobal)
+            {
+                var tenant = await _context.Tenants.FirstOrDefaultAsync(x => x.Id == id && x.Name != TenantAdmin.Name);
+
+                if (tenant == null)
+                {
+                    result.HasError = true;
+                    result.AddMessage(string.Format(ErrorMessages.TenantDoesNotExist, id));
+                    return result;
+                }
+
+                commmunication.Tenant = tenant;
+            }
+            else
+            {
+                var course = await _context.Courses.FirstOrDefaultAsync(x => x.Id == id);
+
+                if (course == null)
+                {
+                    result.HasError = true;
+                    result.AddMessage(string.Format(ErrorMessages.CourseDoesNotExist, id));
+                    return result;
+                }
+
+                commmunication.Course = course;
+            }           
+
+            return result;
+        }
+    }
+}