diff --git a/EnvelopeGenerator.ReceiverUI/Services/SignatureCacheService.cs b/EnvelopeGenerator.ReceiverUI/Services/SignatureCacheService.cs
new file mode 100644
index 00000000..04fe4a57
--- /dev/null
+++ b/EnvelopeGenerator.ReceiverUI/Services/SignatureCacheService.cs
@@ -0,0 +1,67 @@
+using System.Net.Http.Json;
+using Microsoft.Extensions.Options;
+using EnvelopeGenerator.ReceiverUI.Options;
+using EnvelopeGenerator.ReceiverUI.Models;
+
+namespace EnvelopeGenerator.ReceiverUI.Services;
+
+///
+/// Client service for managing cached signatures via API.
+///
+public class SignatureCacheService(HttpClient http, IOptions apiOptions)
+{
+ private readonly ApiOptions _api = apiOptions.Value;
+
+ public async Task SaveSignatureAsync(
+ string envelopeKey,
+ SignatureCaptureDto signature,
+ CancellationToken cancel = default)
+ {
+ var response = await http.PostAsJsonAsync(
+ $"{_api.BaseUrl}/api/Cache/SignatureCapture/{Uri.EscapeDataString(envelopeKey)}",
+ signature,
+ cancel);
+
+ if (!response.IsSuccessStatusCode)
+ {
+ var error = await response.Content.ReadAsStringAsync(cancel);
+ throw new HttpRequestException($"Failed to cache signature: {response.StatusCode} - {error}");
+ }
+ }
+
+ public async Task GetSignatureAsync(
+ string envelopeKey,
+ CancellationToken cancel = default)
+ {
+ var response = await http.GetAsync(
+ $"{_api.BaseUrl}/api/Cache/SignatureCapture/{Uri.EscapeDataString(envelopeKey)}",
+ cancel);
+
+ if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
+ return null;
+
+ if (!response.IsSuccessStatusCode)
+ {
+ var error = await response.Content.ReadAsStringAsync(cancel);
+ throw new HttpRequestException($"Failed to retrieve signature: {response.StatusCode} - {error}");
+ }
+
+ return await response.Content.ReadFromJsonAsync(cancellationToken: cancel);
+ }
+
+ public async Task DeleteSignatureAsync(
+ string envelopeKey,
+ CancellationToken cancel = default)
+ {
+ var response = await http.DeleteAsync(
+ $"{_api.BaseUrl}/api/Cache/SignatureCapture/{Uri.EscapeDataString(envelopeKey)}",
+ cancel);
+
+ if (!response.IsSuccessStatusCode)
+ {
+ var error = await response.Content.ReadAsStringAsync(cancel);
+ throw new HttpRequestException($"Failed to delete signature: {response.StatusCode} - {error}");
+ }
+ }
+}
+