diff --git a/src/PostIt/PostIt/PostIt.csproj b/src/PostIt/PostIt/PostIt.csproj
index d9cf96d3..e4d51a88 100644
--- a/src/PostIt/PostIt/PostIt.csproj
+++ b/src/PostIt/PostIt/PostIt.csproj
@@ -25,6 +25,7 @@
+
diff --git a/src/PostIt/PostIt/Services/YavscApiClient.cs b/src/PostIt/PostIt/Services/YavscApiClient.cs
index 9ae1453b..b611fe02 100644
--- a/src/PostIt/PostIt/Services/YavscApiClient.cs
+++ b/src/PostIt/PostIt/Services/YavscApiClient.cs
@@ -9,6 +9,7 @@ using System.Threading;
using System.Threading.Tasks;
using IdentityModel.OidcClient;
using PostIt.ViewModels;
+using Yavsc.Api.Client;
namespace PostIt.Services;
@@ -24,7 +25,7 @@ namespace PostIt.Services;
/// only refreshes once even if many
/// concurrent requests are in flight.
///
-public class YavscApiClient : IAsyncDisposable
+public class YavscApiClient : IYavscApiClient, IAsyncDisposable
{
// 60s of slack before the access_token's nominal expiry. Covers
// network latency + JWT validation on the server side.
diff --git a/src/Yavsc.Api.Client/IYavscApiClient.cs b/src/Yavsc.Api.Client/IYavscApiClient.cs
new file mode 100644
index 00000000..209ec07d
--- /dev/null
+++ b/src/Yavsc.Api.Client/IYavscApiClient.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Net.Http;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Yavsc.Api.Client;
+
+///
+/// Transport surface that the high-level clients
+/// (, ,
+/// ) need to do their work.
+///
+/// This is intentionally a thin, transport-only contract. It
+/// does not include the OIDC login / refresh / logout surface —
+/// that lives on the concrete YavscApiClient in the
+/// consuming application and is wired by the application
+/// composition root. Splitting the two keeps Yavsc.Api.Client
+/// usable from any host (a CLI, a unit test, a future iOS
+/// client) without dragging OIDC, identity, and a Settings
+/// POMVO everywhere.
+///
+/// Implementations are expected to:
+///
+/// - Attach a Bearer access token to every outbound request.
+/// - Silently refresh the token on a 401 and retry once.
+/// - Serialise the request body as JSON and deserialise the
+/// response body with case-insensitive property matching.
+///
+///
+/// The exception contract on non-2xx responses is
+/// with a message that includes
+/// the response body (capped), so callers can surface the
+/// server-side validation problem to the UI without losing
+/// context.
+///
+public interface IYavscApiClient : IAsyncDisposable
+{
+ ///
+ /// The configured . Clients set its
+ /// BaseAddress in their constructors to point at the
+ /// API host they target.
+ ///
+ HttpClient Http { get; }
+
+ /// Call a JSON endpoint with a typed return value.
+ /// HTTP verb.
+ /// Path relative to .
+ /// Optional request body, serialised as JSON.
+ /// Cancellation token.
+ Task CallAsync(
+ HttpMethod method,
+ string path,
+ object? body = null,
+ CancellationToken ct = default);
+
+ /// Call a JSON endpoint that returns no useful body (DELETE, 204, etc.).
+ Task CallAsync(
+ HttpMethod method,
+ string path,
+ object? body = null,
+ CancellationToken ct = default);
+}
diff --git a/src/Yavsc.Api.Client/Yavsc.Api.Client.csproj b/src/Yavsc.Api.Client/Yavsc.Api.Client.csproj
new file mode 100644
index 00000000..5376856d
--- /dev/null
+++ b/src/Yavsc.Api.Client/Yavsc.Api.Client.csproj
@@ -0,0 +1,29 @@
+
+
+ net10.0
+ enable
+ Yavsc.Api.Client
+ Yavsc.Api.Client
+ enable
+ latest
+ true
+
+ Thin HTTP clients for the Yavsc API. Each client is a DTO↔path
+ mapper; all transport concerns (base URL, JSON, Bearer auth,
+ silent refresh on 401) are delegated to YavscApiClient, which
+ lives in the consuming application (PostIt).
+
+ https://github.com/pazof/yavsc
+ true
+ 1.0.1.0
+ 1.0.1.0
+ 1.0.1-5+Branch.main.Sha.0617fc6bda7151c70559d87177e2dcfb1b60995f
+ 1.0.1-5
+
+
+
+
+
+
+
+