diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/AnnotationController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/AnnotationController.cs
new file mode 100644
index 00000000..34c255fc
--- /dev/null
+++ b/EnvelopeGenerator.GeneratorAPI/Controllers/AnnotationController.cs
@@ -0,0 +1,130 @@
+using DigitalData.Core.Abstraction.Application.DTO;
+using DigitalData.Core.Exceptions;
+using EnvelopeGenerator.Application.Common.Extensions;
+using EnvelopeGenerator.Application.Common.Interfaces.Services;
+using EnvelopeGenerator.Application.Common.Notifications.DocSigned;
+using EnvelopeGenerator.Application.EnvelopeReceivers.Queries;
+using EnvelopeGenerator.Application.Histories.Queries;
+using EnvelopeGenerator.Domain.Constants;
+using EnvelopeGenerator.GeneratorAPI.Extensions;
+using MediatR;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Authentication.Cookies;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace EnvelopeGenerator.GeneratorAPI.Controllers;
+
+///
+/// Manages annotations and signature lifecycle for envelopes.
+///
+[Authorize(Roles = ReceiverRole.FullyAuth)]
+[ApiController]
+[Route("api/[controller]")]
+public class AnnotationController : ControllerBase
+{
+ [Obsolete("Use MediatR")]
+ private readonly IEnvelopeHistoryService _historyService;
+
+ [Obsolete("Use MediatR")]
+ private readonly IEnvelopeReceiverService _envelopeReceiverService;
+
+ private readonly IMediator _mediator;
+
+ private readonly ILogger _logger;
+
+ ///
+ /// Initializes a new instance of .
+ ///
+ [Obsolete("Use MediatR")]
+ public AnnotationController(
+ ILogger logger,
+ IEnvelopeHistoryService envelopeHistoryService,
+ IEnvelopeReceiverService envelopeReceiverService,
+ IMediator mediator)
+ {
+ _historyService = envelopeHistoryService;
+ _envelopeReceiverService = envelopeReceiverService;
+ _mediator = mediator;
+ _logger = logger;
+ }
+
+ ///
+ /// Creates or updates annotations for the authenticated envelope receiver.
+ ///
+ /// Annotation payload.
+ /// Cancellation token.
+ [Authorize(Roles = ReceiverRole.FullyAuth)]
+ [HttpPost]
+ [Obsolete("This endpoint is for PSPDF Kit.")]
+ public async Task CreateOrUpdate([FromBody] PsPdfKitAnnotation? psPdfKitAnnotation = null, CancellationToken cancel = default)
+ {
+ var signature = User.GetAuthReceiverSignature();
+ var uuid = User.GetAuthEnvelopeUuid();
+
+ if (signature is null || uuid is null)
+ {
+ _logger.LogError("Authorization failed: authenticated user does not have a valid signature or envelope UUID.");
+ return Unauthorized("User authentication is incomplete. Missing required claims for processing this request.");
+ }
+
+ var envelopeReceiver = await _mediator.ReadEnvelopeReceiverAsync(uuid, signature, cancel).ThrowIfNull(Exceptions.NotFound);
+
+ if (!envelopeReceiver.Envelope!.ReadOnly && psPdfKitAnnotation is null)
+ return BadRequest();
+
+ if (await _mediator.IsSignedAsync(uuid, signature, cancel))
+ return Problem(statusCode: StatusCodes.Status409Conflict);
+ else if (await _mediator.AnyHistoryAsync(uuid, new[] { EnvelopeStatus.EnvelopeRejected, EnvelopeStatus.DocumentRejected }, cancel))
+ return Problem(statusCode: StatusCodes.Status423Locked);
+
+ var docSignedNotification = await _mediator
+ .ReadEnvelopeReceiverAsync(uuid, signature, cancel)
+ .ToDocSignedNotification(psPdfKitAnnotation)
+ ?? throw new NotFoundException("Envelope receiver is not found.");
+
+ await _mediator.PublishSafely(docSignedNotification, cancel);
+ await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
+
+ return Ok();
+ }
+
+ ///
+ /// Rejects the document for the current receiver.
+ ///
+ /// Optional rejection reason.
+ [Authorize(Roles = ReceiverRole.FullyAuth)]
+ [HttpPost("reject")]
+ [Obsolete("Use MediatR")]
+ public async Task Reject([FromBody] string? reason = null)
+ {
+ var signature = User.GetAuthReceiverSignature();
+ var uuid = User.GetAuthEnvelopeUuid();
+ var mail = User.GetAuthReceiverMail();
+ if (uuid is null || signature is null || mail is null)
+ {
+ _logger.LogEnvelopeError(uuid: uuid, signature: signature,
+ message: @$"Unauthorized POST request in api\\envelope\\reject. One of claims, Envelope, signature or mail ({mail}) is null.");
+ return Unauthorized();
+ }
+
+ var envRcvRes = await _envelopeReceiverService.ReadByUuidSignatureAsync(uuid: uuid, signature: signature);
+
+ if (envRcvRes.IsFailed)
+ {
+ _logger.LogNotice(envRcvRes.Notices);
+ return Unauthorized("you are not authorized");
+ }
+
+ var histRes = await _historyService.RecordAsync(envRcvRes.Data.EnvelopeId, userReference: mail, EnvelopeStatus.DocumentRejected, comment: reason);
+ if (histRes.IsSuccess)
+ {
+ await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
+ return NoContent();
+ }
+
+ _logger.LogEnvelopeError(uuid: uuid, signature: signature, message: "Unexpected error happened in api/envelope/reject");
+ _logger.LogNotice(histRes.Notices);
+ return StatusCode(500, histRes.Messages);
+ }
+}