Lolzteam.Api.DependencyInjection 0.3.0

dotnet add package Lolzteam.Api.DependencyInjection --version 0.3.0
                    
NuGet\Install-Package Lolzteam.Api.DependencyInjection -Version 0.3.0
                    
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="Lolzteam.Api.DependencyInjection" Version="0.3.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Lolzteam.Api.DependencyInjection" Version="0.3.0" />
                    
Directory.Packages.props
<PackageReference Include="Lolzteam.Api.DependencyInjection" />
                    
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 Lolzteam.Api.DependencyInjection --version 0.3.0
                    
#r "nuget: Lolzteam.Api.DependencyInjection, 0.3.0"
                    
#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 Lolzteam.Api.DependencyInjection@0.3.0
                    
#: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=Lolzteam.Api.DependencyInjection&version=0.3.0
                    
Install as a Cake Addin
#tool nuget:?package=Lolzteam.Api.DependencyInjection&version=0.3.0
                    
Install as a Cake Tool

Lolzteam.Api

Build Coverage NuGet NuGet

Production-grade C# client for the Lolzteam Forum and Market APIs.

  • Code-generated from official OpenAPI schemas — 151 Forum and 115 Market operations, all strongly typed
  • AOT-safe deserialization — each response record reads itself directly from a binary stream, zero runtime reflection
  • Low allocation HTTP — ArrayPool<byte> response buffering with a static pooled HttpMessageHandler
  • Automatic retry on 429 / 502 / 503 with Retry-After header respect and configurable back-off
  • Client-side rate limiting — proactively throttles requests before the server ever returns 429
  • Proxy support — HTTP, HTTPS, and SOCKS5 with optional per-proxy credentials
  • Multi-targetnetstandard2.0, netstandard2.1, net6.0, net8.0 (.NET Framework 4.6.1+, Unity, Xamarin)
  • Optional DI packageIHttpClientFactory integration for ASP.NET Core / Generic Host
  • Well tested — 80%+ line coverage across all handwritten code (generated types excluded)

Table of Contents

Installation

Install the core package from NuGet:

dotnet add package Lolzteam.Api

For ASP.NET Core / Generic Host with IHttpClientFactory, also install the optional DI package:

dotnet add package Lolzteam.Api.DependencyInjection

Getting Started

Create a ClientConfig with your bearer token and instantiate a client:

using Lolzteam.Api.Generated.Forum;
using Lolzteam.Api.Runtime;

var config = new ClientConfig
{
    Token   = "your-bearer-token",
    BaseUrl = "https://prod-api.lolz.live",
};

using var forum = new ForumClient(config);

var thread = await forum.Threads.GetAsync(12345);
Console.WriteLine(thread.Thread.ThreadTitle);

var list = await forum.Threads.ListAsync(new() { ForumId = 7 });
foreach (var t in list.Threads)
    Console.WriteLine($"{t.ThreadId}: {t.ThreadTitle}");

Market client works the same way:

using Lolzteam.Api.Runtime;
using Lolzteam.Api.Generated.Market;

using var market = new MarketClient(new ClientConfig
{
    Token   = "your-bearer-token",
    BaseUrl = "https://prod-api.lzt.market",
});

// Browse account listings
var listing = await market.List.UserAsync(new() { CategoryId = CategoryId.V10, Page = 1 });

Both clients implement IDisposable. using or using var is recommended when lifetime is scoped; for singleton use omit the using.

Configuration

ClientConfig is an immutable C# record. All properties except Token are optional.

using Lolzteam.Api.Runtime;

var config = new ClientConfig
{
    // Required
    Token = "your-bearer-token",

    // Override base URL (defaults to the official endpoint per client)
    BaseUrl = "https://prod-api.lolz.live",

    // Proxy (HTTP, HTTPS, or SOCKS5)
    Proxy = new ProxyConfig("socks5://user:pass@proxy.example.com:1080"),

    // Retry policy (default: 3 retries, 500 ms base, 30 s max)
    Retry = new RetryConfig
    {
        MaxRetries = 5,
        BaseDelay  = TimeSpan.FromMilliseconds(300),
        MaxDelay   = TimeSpan.FromSeconds(60),
    },

    // Client-side rate limiting (per-minute budget)
    RateLimit       = new RateLimitConfig(RequestsPerMinute: 300),
    SearchRateLimit = new RateLimitConfig(RequestsPerMinute: 20),

    // Per-request timeout
    Timeout = TimeSpan.FromSeconds(30),

    // Callback invoked before each retry attempt (for logging, metrics, etc.)
    OnRetry = ctx => Console.WriteLine($"Retry — {ctx.Exception.Message}"),
};

Retry

The default policy retries on 429 Too Many Requests, 502 Bad Gateway, and 503 Service Unavailable. On 429 the Retry-After response header is respected; on 5xx a configurable exponential back-off with jitter is used.

// Disable retries entirely
var config = new ClientConfig { Token = "...", Retry = null };

// Custom policy
var config = new ClientConfig
{
    Token = "...",
    Retry = new RetryConfig
    {
        MaxRetries = 3,
        BaseDelay  = TimeSpan.FromMilliseconds(500),
        MaxDelay   = TimeSpan.FromSeconds(30),
    },
    OnRetry = ctx => logger.LogWarning("Retry {Attempt} after {Delay:g}: {Message}", ctx.Attempt, ctx.Delay, ctx.Exception.Message),
};

When all retries are exhausted a RetryExhaustedException is thrown, with the last underlying exception as InnerException.

Rate Limiting

Client-side rate limiting is disabled by default. When configured, a sliding-window token bucket ensures the request rate never exceeds the specified budget, preventing the server from returning 429 in the first place.

var config = new ClientConfig
{
    Token = "...",

    // General-purpose endpoints: 300 req/min (Forum default)
    RateLimit = new RateLimitConfig(300),

    // Search endpoints are counted separately (stricter limit)
    SearchRateLimit = new RateLimitConfig(20),
};

Search requests are automatically identified by the client and consume the SearchRateLimit bucket when set.

Proxy

Pass a ProxyConfig with a URI. Supported schemes: http://, https://, socks5://. Credentials are embedded in the URI.

// HTTP proxy, no auth
Proxy = new ProxyConfig("http://proxy.example.com:8080")

// SOCKS5 proxy with credentials
Proxy = new ProxyConfig("socks5://user:secret@10.0.0.1:1080")

Handlers are cached per proxy URL at the process level, so creating multiple clients with the same proxy reuses the underlying socket pool.

Dependency Injection

Install Lolzteam.Api.DependencyInjection and call AddLolzteamClient<TClient> in your Program.cs. This registers a named HttpClient via IHttpClientFactory for proper socket lifecycle management in hosted applications.

You can configure the client either with a pre-built ClientConfig:

// Program.cs
builder.Services.AddLolzteamClient<ForumClient>(new ClientConfig
{
    Token   = builder.Configuration["Lolzteam:Token"]!,
    Retry   = new RetryConfig { MaxRetries = 3 },
});

Or with the fluent builder, which is more convenient when reading values from configuration:

builder.Services.AddLolzteamClient<ForumClient>(b => b
    .WithToken(builder.Configuration["Lolzteam:Token"]!)
    .WithProxy("socks5://proxy:1080")
    .WithRateLimit(300)
    .WithTimeout(TimeSpan.FromSeconds(60))
);

Resolve the client in your services via constructor injection:

public class ThreadService(ForumClient forum)
{
    public Task<ThreadsResponse> GetLatestAsync()
        => forum.Threads.ListAsync(new() { ForumId = 7 });
}

When using IHttpClientFactory the HttpClient lifetime is managed by the factory. Do not dispose the injected client in this case.

Error Handling

All client-facing exceptions derive from LolzteamException.

Exception HTTP status Notes
HttpApiException 4xx (except 429) StatusCode, ResponseBody
RateLimitException 429 RetryAfter (parsed from header)
ServerException 5xx StatusCode, ResponseBody
NetworkException Connection-level failure, IsTransient
RetryExhaustedException After all retries fail, wraps last exception
ConfigException Invalid proxy URL or unsupported scheme
try
{
    var thread = await forum.Threads.GetAsync(12345);
}
catch (RateLimitException ex)
{
    // Honour the server's hint even when client-side limiting is enabled
    await Task.Delay(ex.RetryAfter ?? TimeSpan.FromSeconds(5));
}
catch (HttpApiException ex) when (ex.StatusCode == 404)
{
    Console.WriteLine("Thread not found.");
}
catch (ServerException ex)
{
    Console.WriteLine($"Server error {ex.StatusCode}: {ex.ResponseBody}");
}

Forum API Groups

ForumClient exposes 151 operations across 18 endpoint groups:

Property Description
Assets Static asset URLs (CSS, styles)
Batch Execute multiple API calls in one request
Categories Browse forum categories
Chatbox Chatbox messages
Conversations Private conversations
Forms Form definitions
Forums Forum node listings and subscriptions
Links Short-link resolution
Navigation Navigation elements
Notifications User notifications
OAuth OAuth token management
Pages Static pages
Posts Thread posts (create, edit, delete, react)
ProfilePosts Profile wall posts
Search Full-text thread and user search
Tags Thread tags
Threads Threads (list, create, edit, delete, vote)
Users User profiles, followers, fields, avatar

Market API Groups

MarketClient exposes 115 operations across 14 endpoint groups:

Property Description
AutoPayments Autopayment rules
Batch Batch request execution
Cart Shopping cart
Category Account categories and search
CustomDiscounts Coupon / discount management
Imap IMAP verification for accounts
List Account listing and browsing
Managing Seller account management
Payments Wallet operations and transfer
Profile Buyer/seller profile
Proxy Proxy operations on listed accounts
Publishing Create and edit listings
Purchasing Buy, reserve, and confirm accounts
Tags Listing tags

Regenerating Code

The clients in src/Lolzteam.Api/Generated/ are produced from the OpenAPI schemas in schemas/. To regenerate after updating a schema, run:

dotnet run --project codegen/Lolzteam.Codegen

The generator will:

  1. Parse schemas/forum.json and schemas/market.json
  2. Delete existing .cs files in each Generated/ subdirectory and its Types/ sub-directory
  3. Emit per-type files into Generated/<Api>/Types/<Class>.cs (enums, schemas, and per-group input DTOs as separate files)
  4. Emit ForumClient.cs / MarketClient.cs and IForumClient.cs / IMarketClient.cs

Splitting types across multiple files keeps IDE analysers responsive on large schemas. Generated files are committed to the repository so the library builds without running the codegen.

License

This library is licensed under the MIT License.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  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 was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.3.0 104 4/27/2026
0.2.0 117 4/1/2026
0.1.0 101 3/25/2026