diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/DocumentController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/DocumentController.cs
new file mode 100644
index 00000000..d0adb90f
--- /dev/null
+++ b/EnvelopeGenerator.GeneratorAPI/Controllers/DocumentController.cs
@@ -0,0 +1,43 @@
+using DigitalData.Core.Exceptions;
+using EnvelopeGenerator.Application.Common.Extensions;
+using EnvelopeGenerator.Application.EnvelopeReceivers.Queries;
+using EnvelopeGenerator.Domain.Constants;
+using MediatR;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace EnvelopeGenerator.GeneratorAPI.Controllers;
+
+///
+/// Provides access to envelope documents for authenticated receivers.
+///
+///
+/// Initializes a new instance of the class.
+///
+[Authorize(Roles = ReceiverRole.FullyAuth)]
+[ApiController]
+[Route("api/[controller]")]
+public class DocumentController(IMediator mediator, ILogger logger) : ControllerBase
+{
+ ///
+ /// Returns the document bytes for the specified envelope receiver key.
+ ///
+ /// Encoded envelope key.
+ /// Cancellation token.
+ [HttpGet]
+ public async Task GetDocument(ReadEnvelopeReceiverQuery query, CancellationToken cancel)
+ {
+ var envRcv = await mediator.Send(query, cancel).FirstAsync(Exceptions.NotFound);
+
+ var byteData = envRcv.Envelope?.Documents?.FirstOrDefault()?.ByteData;
+
+ if (byteData is null || byteData.Length == 0)
+ {
+ logger.LogError("Document byte data is null or empty for envelope-receiver entity:\n{envelopeKey}.",
+ envRcv.ToJson(Format.Json.ForDiagnostics));
+ throw new NotFoundException("Document is empty.");
+ }
+
+ return File(byteData, "application/octet-stream");
+ }
+}