Yllibed.TenantCloudClient 3.0.20-dev

This is a prerelease version of Yllibed.TenantCloudClient.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package Yllibed.TenantCloudClient --version 3.0.20-dev
                    
NuGet\Install-Package Yllibed.TenantCloudClient -Version 3.0.20-dev
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Yllibed.TenantCloudClient" Version="3.0.20-dev" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Yllibed.TenantCloudClient" Version="3.0.20-dev" />
                    
Directory.Packages.props
<PackageReference Include="Yllibed.TenantCloudClient" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Yllibed.TenantCloudClient --version 3.0.20-dev
                    
#r "nuget: Yllibed.TenantCloudClient, 3.0.20-dev"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Yllibed.TenantCloudClient@3.0.20-dev
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Yllibed.TenantCloudClient&version=3.0.20-dev&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Yllibed.TenantCloudClient&version=3.0.20-dev&prerelease
                    
Install as a Cake Tool

Yllibed.TenantCloudClient

Unofficial .NET client library for TenantCloud, a rental property management platform.

Build Status Nuget

This is not an official TenantCloud product. TenantCloud does not provide a public API; this library works against their internal endpoints.

Packages

Package Description
Yllibed.TenantCloudClient Core library: API client, token store abstractions, and OS-native secure storage
Yllibed.TenantCloudClient.Cdp Chrome DevTools Protocol token provider (extracts tokens from a running browser)

Both packages target net8.0 and net10.0 with no external runtime dependencies beyond System.Text.Json and Microsoft.Extensions.DependencyInjection.Abstractions.

Quick start

With dependency injection

services
    .AddSecureTokenStore()      // ITcTokenStore → OS credential store
    .AddCdpTokenProvider()      // ITcAuthTokenProvider → browser extraction + auto-refresh
    .AddTenantCloudClient();    // ITcClient → TcClient

Then inject ITcClient wherever you need it:

public class MyService(ITcClient tc)
{
    public async Task<TcUserInfo?> WhoAmI(CancellationToken ct)
        => await tc.GetUserInfo(ct);
}

Without dependency injection

var tokenStore = new SecureTokenStore();
var tokenProvider = new CdpTokenProvider(new CdpTokenProviderOptions
{
    TokenStore = tokenStore,
    AllowInteractiveLogin = true,
});

using var client = new TcClient(tokenProvider);
var user = await client.GetUserInfo(ct);

Authentication

TcClient requires an ITcAuthTokenProvider to supply Bearer tokens. The library does not store or manage credentials directly.

public interface ITcAuthTokenProvider
{
    Task<string?> GetToken(CancellationToken ct);
    Task OnTokenRejected(CancellationToken ct, string rejectedToken);
}

Built-in: CdpTokenProvider

Provided by the Yllibed.TenantCloudClient.Cdp package. Extracts auth tokens from a running Chromium browser via the Chrome DevTools Protocol, with automatic JWT refresh.

services.AddCdpTokenProvider(options =>
{
    options.DebugPort = 9222;               // CDP debug port (default)
    options.AllowInteractiveLogin = true;   // launch a browser if no session found
});

The provider follows a multi-step strategy:

  1. In-memory cache (if the JWT is still valid)
  2. Token store (load + refresh if expired)
  3. CDP extraction from an existing browser tab on app.tenantcloud.com
  4. Interactive login (if AllowInteractiveLogin is enabled) — launches a browser window and waits for the user to sign in

Custom provider

Implement ITcAuthTokenProvider and register it before calling AddTenantCloudClient():

services.AddSingleton<ITcAuthTokenProvider, MyCustomTokenProvider>();
services.AddTenantCloudClient();

Token persistence

ITcTokenStore allows tokens to survive across process restarts. Both the core library and the CDP provider can use it.

public interface ITcTokenStore
{
    Task<TcTokenSet?> LoadAsync(CancellationToken ct);
    Task SaveAsync(TcTokenSet tokens, CancellationToken ct);
}

Built-in stores

Store Package Description
SecureTokenStore Core OS-native credential storage: DPAPI (Windows), Keychain (macOS), Secret Service (Linux)
FileTokenStore Cdp Plain JSON file with atomic writes (useful for headless/CI scenarios)
// OS-native secure storage (recommended)
services.AddSecureTokenStore();

// With custom options
services.AddSecureTokenStore(options =>
{
    options.ServiceName = "MyApp";
    options.AccountKey = "production";
});

// Or file-based (from the Cdp package, register manually)
services.AddSingleton<ITcTokenStore>(new FileTokenStore("/path/to/tokens.json"));

Custom store

Implement ITcTokenStore to persist tokens wherever you need (database, Azure Key Vault, etc.):

services.AddSingleton<ITcTokenStore, MyDatabaseTokenStore>();

API reference

ITcClient

Member Type Description
GetUserInfo(ct) Task<TcUserInfo?> Current signed-in user info
Contacts IPaginatedSource<TcContact> Contacts (tenants, professionals)
Properties IPaginatedSource<TcProperty> Properties
Units IPaginatedSource<TcUnit> Rental units
Transactions IPaginatedSource<TcTransaction> Financial transactions
Leases IPaginatedSource<TcLease> Leases

Paginated sources

Each collection is an IPaginatedSource<T>. Call .GetAll(ct) to fetch all pages, or .GetAll(ct, maxResults: n) to cap the fetch:

var contacts = await client.Contacts.OnlyMovedIn().GetAll(ct);

The result is a ReadOnlySequence<T> (one segment per API page). Use .AsEnumerable() to bridge to LINQ:

var names = (await client.Contacts.GetAll(ct))
    .AsEnumerable()
    .Select(c => c.Name)
    .ToArray();

Filters

Filters are chainable extension methods that narrow the API query before fetching.

Contacts

  • .OnlyTenants() — tenant contacts only
  • .OnlyMovedIn() — tenants with active leases
  • .OnlyProfessionals() — professional contacts only
  • .OnlyArchived() — archived contacts

Leases

  • .OnlyActive() — active leases
  • .ForProperty(propertyId) — filter by property
  • .ForUnit(unitId) — filter by unit

Units

  • .OnlyOccuped() — units with active leases
  • .OnlyVacant() — vacant units
  • .ForProperty(propertyId) — filter by property

Transactions

  • .ForTenant(tenantId) — filter by tenant
  • .ForProperty(propertyId) — filter by property
  • .ForUnit(unitId) — filter by unit
  • .ForStatus(TcTransactionStatus) — filter by status (Due, Paid, Partial, Pending, Void, WithBalance, Overdue, Waive)
  • .ForCategory(TcTransactionCategory) — filter by category (Income, Expense, Refund, Credits, Liability)
  • .SortByDateDescending() — reverse chronological order

Example: overdue income per property

var balancePerProperty = (await client.Transactions
        .ForCategory(TcTransactionCategory.Income)
        .ForStatus(TcTransactionStatus.WithBalance)
        .GetAll(ct))
    .AsEnumerable()
    .Where(t => t.PropertyId != null)
    .GroupBy(t => (long)t.PropertyId!, t => t.Balance)
    .Select(g => new { PropertyId = g.Key, Balance = g.Sum() })
    .ToArray();

License

MIT

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Yllibed.TenantCloudClient:

Package Downloads
Yllibed.TenantCloudClient.Cdp

Chrome DevTools Protocol (CDP) based token provider for Yllibed.TenantCloudClient. Extracts auth tokens from an existing browser session — no external NuGet dependencies.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.0.41-dev 87 2/16/2026
3.0.40-dev 84 2/16/2026
3.0.39-dev 90 2/16/2026
3.0.20-dev 82 2/16/2026
3.0.19-dev 82 2/16/2026
3.0.18-dev 86 2/16/2026
2.1.0 715 12/7/2020
2.1.0-dev.6 425 11/16/2020
2.1.0-dev.4 371 12/7/2020
2.1.0-dev.3 362 11/21/2020
2.1.0-dev.1 397 11/16/2020
2.0.0 696 11/16/2020
2.0.0-dev.36 363 11/16/2020
2.0.0-dev.35 353 11/16/2020
2.0.0-dev.33 405 11/5/2020
1.0.0-dev.21 483 6/5/2019
1.0.0-dev.20 484 6/5/2019
1.0.0-dev.18 472 6/3/2019
1.0.0-dev.16 483 6/2/2019
1.0.0-dev.15 476 6/2/2019
Loading failed