A .NET client for the public TVMaze API, built on IHttpClientFactory.
The package targets .NET 10 and .NET 8 and provides:
- Clients grouped by TVMaze endpoint area.
- Dependency injection and
IHttpClientFactoryintegration. - Shared client-side rate limiting.
- The standard .NET HTTP resilience pipeline, including retries, timeouts, rate
limiting, circuit breaking, and
Retry-Aftersupport. ActivitySource, metrics, and structured logging instrumentation.
dotnet add package TrackSeries.TVMaze.ClientRegister the client and provide a User-Agent that identifies your application:
services.AddTVMazeClient(options =>
{
options.UserAgent = "MyApplication/1.0 (+https://example.com)";
});Options can also be loaded from configuration:
{
"TVMaze": {
"BaseAddress": "https://api.tvmaze.com/",
"UserAgent": "MyApplication/1.0 (+https://example.com)",
"MaxRequestsPerWindow": 20,
"RateLimitWindow": "00:00:10"
}
}services.AddTVMazeClientFromConfiguration(configuration.GetSection("TVMaze"));Inject ITVMazeClient and use the grouped endpoint clients:
public sealed class ShowService(ITVMazeClient tvMaze)
{
public async Task<Show?> FindAsync(string imdbId, CancellationToken cancellationToken)
{
return await tvMaze.Lookup.GetShowByImdbAsync(imdbId, cancellationToken);
}
}var results = await tvMaze.Search.SearchShowsAsync("The Expanse", cancellationToken);
var episodes = await tvMaze.Shows.GetEpisodesAsync(showId, cancellationToken: cancellationToken);
var recentUpdates = await tvMaze.Updates.GetShowUpdatesSinceAsync(
TVMazeUpdatePeriod.Day,
cancellationToken);Single-resource endpoints return null for HTTP 404. Collection endpoints return an empty list for HTTP 404. Other unsuccessful responses throw HttpRequestException after the resilience pipeline is exhausted.
For some global or web-channel episodes, TVMaze returns an empty airtime while
still providing a synthetic or default airstamp. Treat an episode timestamp as
precise only when both Airtime is nonblank and Airstamp is non-null.
Otherwise, preserve the date-only Airdate semantics; do not infer precision
from Airstamp alone or by checking for a particular time of day.
TVMaze guarantees at least 20 requests every 10 seconds per IP address. The package applies that limit across all endpoint clients created by the same dependency injection container.
Defaults can be changed during registration:
services.AddTVMazeClient(options =>
{
options.UserAgent = "MyApplication/1.0";
options.MaxRequestsPerWindow = 20;
options.RateLimitWindow = TimeSpan.FromSeconds(10);
});The returned IHttpClientBuilder can be used for additional HttpClient
configuration and handlers. Handlers appended to the default registration run
inside the resilience pipeline and therefore execute once per attempt:
services
.AddTVMazeClient(options => options.UserAgent = "MyApplication/1.0")
.AddHttpMessageHandler<MyHandler>();To own the complete resilience pipeline, disable the library default and add exactly one application pipeline:
services
.AddTVMazeClient(
TVMazeResilienceMode.None,
options => options.UserAgent = "MyApplication/1.0")
.AddHttpMessageHandler<MyHandler>()
.AddStandardResilienceHandler(options =>
{
options.Retry.MaxRetryAttempts = 2;
});TVMazeResilienceMode.None also disables the library's TVMaze-specific rate
limiter. Use this mode when resilience is configured globally or when adding a
custom resilience handler; stacking resilience pipelines multiplies attempts
and delays.
The client emits activities and metrics under TrackSeries.TVMaze.Client.
| Instrument | Type |
|---|---|
tvmaze.client.requests |
Counter |
tvmaze.client.failures |
Counter |
tvmaze.client.duration |
Histogram (seconds) |
Expected HTTP 404 responses and caller cancellations are not recorded as failures.
Install the optional integration package to register the instrumentation with OpenTelemetry:
dotnet add package TrackSeries.TVMaze.Client.OpenTelemetryservices
.AddOpenTelemetry()
.AddTVMazeClientInstrumentation();Configure exporters, resources, and sampling in the application as usual. The
standard HttpClient instrumentation can be enabled alongside this integration
to observe individual HTTP attempts, while the TVMaze activity represents the
logical request across retries.
Services that only need the stable source and meter names can reference the
lightweight TrackSeries.TVMaze.Client.Diagnostics package without pulling in
the client or OpenTelemetry dependencies.
This client library is licensed under the MIT license.
Data returned by the TVMaze API is made available under CC BY-SA 4.0. Applications using TVMaze data are responsible for complying with its attribution and ShareAlike requirements. TVMaze resource URLs returned by the API can be used for attribution.