### Install Aydsko iRacing Data API NuGet Package Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/src/Aydsko.iRacingData/Package README.md Install the library using the .NET CLI. This is the first step to integrating the API into your project. ```pwsh dotnet add package Aydsko.iRacingData ``` -------------------------------- ### Get Race Guide Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Finds upcoming sessions starting or ending after a specified time. Can optionally include sessions ending after the specified time. ```csharp Task> GetRaceGuideAsync(DateTimeOffset? from = null, bool? includeEndAfterFrom = null, CancellationToken cancellationToken = default) ``` -------------------------------- ### Minimal Setup with Dependency Injection Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/quick-reference.md Configure and build the IDataClient using Microsoft.Extensions.DependencyInjection. Use the UseProductUserAgent and UsePasswordLimitedOAuth methods for authentication. ```csharp using Aydsko.iRacingData; using Microsoft.Extensions.DependencyInjection; var services = new ServiceCollection(); services.AddIRacingDataApi(options => { options.UseProductUserAgent("MyApp", new Version(1, 0)); options.UsePasswordLimitedOAuth("user", "pass", "client-id", "client-secret"); }); var dataClient = services.BuildServiceProvider().GetRequiredService(); var info = await dataClient.GetMyInfoAsync(); Console.WriteLine($"Hello {info.Data.DisplayName}!"); ``` -------------------------------- ### Generated User-Agent Example Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/service-registration.md Illustrates the format of a user-agent header automatically generated by the library, combining application and library version information. ```text MyApp/1.0 Aydsko.iRacingDataClient/2401.2 ``` -------------------------------- ### Usage of EventType Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/types.md Examples demonstrating how to use the EventType enumeration when fetching member division or season results. ```csharp var division = await dataClient.GetMemberDivisionAsync(seasonId, Common.EventType.Race); var results = await dataClient.GetSeasonResultsAsync(seasonId, Common.EventType.Race, weekNumber); ``` -------------------------------- ### Get My Info Async Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves account information for the currently authenticated user. Ensure the client is authenticated before calling this method. ```csharp var dataClient = serviceProvider.GetRequiredService(); var response = await dataClient.GetMyInfoAsync(); Console.WriteLine($"Customer ID: {response.Data.CustomerId}"); Console.WriteLine($"Display Name: {response.Data.DisplayName}"); Console.WriteLine($"Email: {response.Data.Email}"); ``` -------------------------------- ### Get Season and Series Information Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/quick-reference.md Retrieve season schedules, series details, and season driver standings. Use includeSeries: true to get series data with seasons. ```csharp var seasons = await dataClient.GetSeasonsAsync(includeSeries: true); var schedule = await dataClient.GetSeasonScheduleAsync(seasonId); var series = await dataClient.GetSeriesAsync(); var standings = await dataClient.GetSeasonDriverStandingsAsync(seasonId, carClassId); ``` -------------------------------- ### Configure HttpClientBuilder for iRacingDataApi Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/service-registration.md This example shows how to further configure the IHttpClientBuilder returned by the registration methods. You can set timeouts, add default headers, or apply resilience policies. ```csharp var httpClientBuilder = services.AddIRacingDataApi(options => { /* ... */ }); httpClientBuilder.ConfigureHttpClient(client => { client.Timeout = TimeSpan.FromSeconds(30); client.DefaultRequestHeaders.Add("Custom-Header", "value"); }); httpClientBuilder.AddTransientHttpErrorPolicy(policy => { policy.WaitAndRetryAsync(/* ... */); }); ``` -------------------------------- ### GetCarsAsync Example Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves details about all available cars and iterates through them to print their IDs and names. This is useful for displaying a list of selectable cars. ```csharp var response = await dataClient.GetCarsAsync(); foreach (var car in response.Data) { Console.WriteLine($"{car.CarId}: {car.CarName}"); } ``` -------------------------------- ### Implementing IOAuthTokenSource Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/types.md Provides an example of how to implement the IOAuthTokenSource interface to retrieve and manage OAuth tokens. This involves fetching a token from an external source and calculating its expiration time. ```csharp public class MyTokenSource : IOAuthTokenSource { public async Task GetTokenAsync(CancellationToken cancellationToken = default) { var token = await GetTokenFromIRacingAsync(); var expiresAt = DateTimeOffset.UtcNow.AddSeconds(token.ExpiresInSeconds); return new OAuthTokenValue(token.AccessToken, expiresAt); } } ``` -------------------------------- ### Get Current Season Lookup Async Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves lookup information for the currently running season. Use this to get season quarter and year details. ```csharp Task> GetCurrentSeasonLookupAsync(CancellationToken cancellationToken = default) ``` -------------------------------- ### Get SubSession Result Async Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves detailed results for a completed subsession. Can optionally include license information. ```csharp Task> GetSubSessionResultAsync(int subSessionId, bool includeLicenses, CancellationToken cancellationToken = default) ``` -------------------------------- ### Get Vehicle and Track Data Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/quick-reference.md Fetch lists of available cars, car classes, tracks, and their associated assets using the IDataClient. ```csharp var cars = await dataClient.GetCarsAsync(); var carClasses = await dataClient.GetCarClassesAsync(); var tracks = await dataClient.GetTracksAsync(); var carAssets = await dataClient.GetCarAssetDetailsAsync(); var trackAssets = await dataClient.GetTrackAssetsAsync(); ``` -------------------------------- ### Get League Season Sessions Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves sessions for a league season. Use resultsOnly to include only sessions with available results. ```csharp Task> GetLeagueSeasonSessionsAsync(int leagueId, int seasonId, bool resultsOnly = false, CancellationToken cancellationToken = default) ``` -------------------------------- ### Get Member Recap Async Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves a summary of activity for a specified period (year/quarter) for a customer. Defaults to the current calendar year and quarter if not provided. ```csharp Task> GetMemberRecapAsync(int? customerId = null, int? seasonYear = null, int? seasonQuarter = null, CancellationToken cancellationToken = default) ``` -------------------------------- ### Get Customer League Sessions Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves league sessions created by or available to the authenticated user. Filter by mine or packageId. ```csharp Task> GetCustomerLeagueSessionsAsync(bool mine = false, int? packageId = null, CancellationToken cancellationToken = default) ``` -------------------------------- ### Load Multiple iRacing Data Sets in Parallel Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/quick-reference.md Load multiple data sets concurrently using `Task.WhenAll` for improved performance. This example fetches car, track, car class, and series data simultaneously. ```csharp var tasks = new[] { dataClient.GetCarsAsync(), dataClient.GetTracksAsync(), dataClient.GetCarClassesAsync(), dataClient.GetSeriesAsync() }; await Task.WhenAll(tasks); var cars = ((Task>)tasks[0]).Result.Data; var tracks = ((Task>)tasks[1]).Result.Data; var classes = ((Task>)tasks[2]).Result.Data; var series = ((Task>)tasks[3]).Result.Data; ``` -------------------------------- ### Get Member Information Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/quick-reference.md Retrieve current user information, member profiles, summary statistics, and career statistics using the IDataClient. ```csharp var info = await dataClient.GetMyInfoAsync(); // Current user var profile = await dataClient.GetMemberProfileAsync(customerId); // Member profile var summary = await dataClient.GetMemberSummaryAsync(customerId); // Summary stats var career = await dataClient.GetCareerStatisticsAsync(customerId); // Career stats ``` -------------------------------- ### Get Seasons Async (By Year/Quarter) Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves season information for a specific year and quarter asynchronously. Supports cancellation. ```csharp Task> GetSeasonsAsync(int seasonYear, int seasonQuarter, bool includeSeries, CancellationToken cancellationToken = default) ``` -------------------------------- ### Get Registered Drivers List Async Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves a list of drivers in a currently-running subsession. Returns an empty array if the subsession has finished. ```csharp Task> GetRegisteredDriversListAsync(int subSessionId, CancellationToken cancellationToken = default) ``` -------------------------------- ### Get Weather Forecast From URL Async Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves weather forecast data from a provided URL. Accepts either a string or a Uri object for the URL. ```csharp Task> GetWeatherForecastFromUrlAsync(string url, CancellationToken cancellationToken = default) ``` ```csharp Task> GetWeatherForecastFromUrlAsync(Uri url, CancellationToken cancellationToken = default) ``` -------------------------------- ### ASP.NET Core Integration with Caching Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/service-registration.md Integrate the iRacing Data API into an ASP.NET Core application using AddIRacingDataApiWithCaching. This example demonstrates setting up controllers and using the IDataClient for API calls. ```csharp // Startup.cs or Program.cs public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddControllers(); // Add memory cache services.AddMemoryCache(); // Register iRacing Data API with caching services.AddIRacingDataApiWithCaching(options => { options.UseProductUserAgent("MyWebService", new Version(3, 0)); options.UsePasswordLimitedOAuth( Configuration["iRacing:Username"], Configuration["iRacing:Password"], Configuration["iRacing:ClientId"], Configuration["iRacing:ClientSecret"]); }); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } // In a controller [ApiController] [Route("api/[controller]")] public class RacingController : ControllerBase { private readonly IDataClient _dataClient; public RacingController(IDataClient dataClient) { _dataClient = dataClient; } [HttpGet("cars")] public async Task GetCars() { try { var response = await _dataClient.GetCarsAsync(); return Ok(new { cars = response.Data, remaining = response.RateLimitRemaining }); } catch (iRacingDataClientException ex) { return StatusCode(500, new { error = ex.Message }); } } } ``` -------------------------------- ### Get Track Asset Screenshot URIs (Sync) Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Builds a collection of URIs for track screenshots using track and track asset details. This is a synchronous operation. ```csharp IEnumerable GetTrackAssetScreenshotUris(Tracks.Track track, TrackAssets trackAssets) ``` -------------------------------- ### Get League Points Systems Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves points systems available to a league. An optional seasonId can be provided for custom points inclusion. ```csharp Task> GetLeaguePointsSystemsAsync(int leagueId, int? seasonId = null, CancellationToken cancellationToken = default) ``` -------------------------------- ### Console App Configuration with Password Limited Grant Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/configuration.md Example of configuring the iRacing Data Client for a console application using the Password Limited Grant OAuth flow. Retrieves credentials from environment variables. ```csharp using Microsoft.Extensions.DependencyInjection; using Aydsko.iRacingData; var services = new ServiceCollection(); services.AddIRacingDataApi(options => { options.UseProductUserAgent("MyConsoleApp", new Version(1, 0)); options.UsePasswordLimitedOAuth( userName: Environment.GetEnvironmentVariable("IRACING_USERNAME")!, password: Environment.GetEnvironmentVariable("IRACING_PASSWORD")!, clientId: Environment.GetEnvironmentVariable("IRACING_CLIENT_ID")!, clientSecret: Environment.GetEnvironmentVariable("IRACING_CLIENT_SECRET")!); }); var serviceProvider = services.BuildServiceProvider(); var dataClient = serviceProvider.GetRequiredService(); var info = await dataClient.GetMyInfoAsync(); Console.WriteLine($"Hello {info.Data.DisplayName}!"); ``` -------------------------------- ### Implement Graceful Fallback for Rate Limit Errors Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/quick-reference.md Provide a fallback response when a rate limit is exceeded. This example returns an empty array if the `iRacingRateLimitExceededException` is caught. ```csharp try { return await dataClient.GetCarsAsync(); } catch (iRacingRateLimitExceededException) { return Array.Empty(); } ``` -------------------------------- ### Get Results and Standings Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/quick-reference.md Fetch sub-session results, season driver standings, qualifying results, and world records for specific cars and tracks. ```csharp var results = await dataClient.GetSubSessionResultAsync(subSessionId, includeLicenses: true); var standings = await dataClient.GetSeasonDriverStandingsAsync(seasonId, carClassId); var qualifying = await dataClient.GetSeasonQualifyResultsAsync(seasonId, carClassId); var worldRecords = await dataClient.GetWorldRecordsAsync(carId, trackId); ``` -------------------------------- ### Custom OAuth Token Source Implementation Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/service-registration.md Implement a custom IOAuthTokenSource to manage token retrieval and caching. This example uses IDistributedCache for storing tokens and HttpClient for fetching them from iRacing. ```csharp public class CustomTokenSource : IOAuthTokenSource { private readonly IDistributedCache _cache; private readonly HttpClient _httpClient; public CustomTokenSource(IDistributedCache cache, HttpClient httpClient) { _cache = cache; _httpClient = httpClient; } public async Task GetTokenAsync(CancellationToken cancellationToken = default) { // Check cache var cached = await _cache.GetStringAsync("iracing_token", cancellationToken); if (cached != null) { var data = JsonSerializer.Deserialize(cached); if (data!.ExpiresAt > DateTimeOffset.UtcNow.AddSeconds(60)) return data.Token; } // Fetch new token from iRacing var response = await _httpClient.PostAsJsonAsync( "https://oauth.iracing.com/oauth/token", new { /* OAuth parameters */ }, cancellationToken); var oauthResponse = await response.Content.ReadAsAsync(); var expiresAt = DateTimeOffset.UtcNow.AddSeconds(oauthResponse.ExpiresInSeconds - 60); var token = new OAuthTokenValue(oauthResponse.AccessToken, expiresAt); // Cache the token var cacheData = new CachedToken { Token = token, ExpiresAt = expiresAt }; await _cache.SetStringAsync( "iracing_token", JsonSerializer.Serialize(cacheData), new DistributedCacheEntryOptions { AbsoluteExpiration = expiresAt }, cancellationToken); return token; } private class CachedToken { public OAuthTokenValue Token { get; set; } public DateTimeOffset ExpiresAt { get; set; } } } var services = new ServiceCollection(); services.AddDistributedMemoryCache(); services.AddHttpClient(); services.AddScoped(sp => sp.GetRequiredService()); services.AddIRacingDataApi(options => { options.UseProductUserAgent("OAuthApp", new Version(1, 0)); options.UseOAuthTokenSource(sp => sp.GetRequiredService()); }); var provider = services.BuildServiceProvider(); ``` -------------------------------- ### iRacingDataClient Registration with Caching Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/service-registration.md Registers the iRacingDataClient along with memory caching capabilities. This example demonstrates adding the necessary memory cache services and then registering the API client with caching enabled, including user-agent and authentication configuration. ```csharp var services = new ServiceCollection(); // Add memory cache (required for caching client) services.AddMemoryCache(options => { options.SizeLimit = 100_000_000; // 100MB limit }); // Register API with caching services.AddIRacingDataApiWithCaching(options => { options.UseProductUserAgent("CachedApp", new Version(1, 0)); options.UsePasswordLimitedOAuth("user", "pass", "id", "secret"); }); var provider = services.BuildServiceProvider(); var client = provider.GetRequiredService(); ``` -------------------------------- ### Get Driver Statistics By Category CSV Async Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves driver statistics as a CSV file for a specified category. Requires a category identifier. ```csharp Task GetDriverStatisticsByCategoryCsvAsync(int categoryId, CancellationToken cancellationToken = default) ``` -------------------------------- ### Add Microsoft Memory Caching Package Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/src/Aydsko.iRacingData/Package README.md Install the necessary package for enabling in-memory caching for API results. This improves performance by reducing redundant data requests. ```powershell dotnet add package Microsoft.Extensions.Caching.Memory ``` -------------------------------- ### Handle iRacing Login Failed Exception Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/exceptions.md Catch `iRacingLoginFailedException` to manage authentication failures. Check `VerificationRequired` and `LegacyAuthenticationRequired` properties to guide the user on necessary actions. ```csharp try { // This would typically happen during token source initialization var token = await tokenSource.GetTokenAsync(); } catch (iRacingLoginFailedException ex) { if (ex.VerificationRequired == true) { Console.WriteLine("CAPTCHA verification required - authenticate via browser"); // Redirect user to browser-based authentication } else if (ex.LegacyAuthenticationRequired == true) { Console.WriteLine("Account requires legacy authentication configuration"); // Inform user to update their iRacing account settings } else { Console.WriteLine($"Login failed: {ex.Message}"); } } ``` -------------------------------- ### Get Member Participation Credits Async Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves the authenticated member's participation credit status. This method always returns information for the currently authenticated member. ```csharp Task> GetMemberParticipationCreditsAsync(CancellationToken cancellationToken = default) ``` -------------------------------- ### Use iRacing Data Client to Get Account Information Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/src/Aydsko.iRacingData/Package README.md Retrieve and display basic information about your iRacing account using the IDataClient. Ensure the client is registered with the service provider. ```csharp // Retrieve an instance from the service provider. var dataClient = serviceProvider.GetRequiredService(); // Retrieve information about our own account. var infoResponse = await dataClient.GetMyInfoAsync(cancellationToken); // Write that information to the console. Console.WriteLine($"Driver name: {infoResponse.Data.DisplayName}"); Console.WriteLine($"Customer ID: {infoResponse.Data.CustomerId}"); Console.WriteLine($"Club: {infoResponse.Data.ClubName}"); ``` -------------------------------- ### Get Season Schedule Async Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves the schedule for a specific season ID asynchronously. Supports cancellation. ```csharp Task> GetSeasonScheduleAsync(int seasonId, CancellationToken cancellationToken = default) ``` -------------------------------- ### Get Season List Async (Current) Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves a list of current seasons asynchronously. Supports cancellation. ```csharp Task> GetSeasonListAsync(bool includeSeries, CancellationToken cancellationToken = default) ``` -------------------------------- ### GetRaceGuideAsync Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Finds sessions beginning or ending after a specified time. ```APIDOC ## GetRaceGuideAsync ### Description Finds sessions beginning or ending after a given time. ### Method GET (Assumed based on SDK method name) ### Endpoint /api/raceguide (Assumed based on SDK method name) ### Parameters #### Query Parameters - **from** (DateTimeOffset?) - Optional - Future time to search from (defaults to now) - **includeEndAfterFrom** (bool?) - Optional - Include sessions that begin before but end after `from` time - **cancellationToken** (CancellationToken) - Optional - Token to allow operation cancellation ### Response #### Success Response (200) - **Data** (DataResponse) - Contains upcoming sessions ``` -------------------------------- ### Get Spectator Subsession Identifiers Async Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves available spectator subsession identifiers. Can be filtered by event types. ```csharp Task> GetSpectatorSubsessionIdentifiersAsync(Common.EventType[]? eventTypes = null, CancellationToken cancellationToken = default) ``` -------------------------------- ### List Hosted Sessions (All Joinable) Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Lists all joinable hosted sessions, including spectator sessions. Can filter by package ID. ```csharp Task> ListHostedSessionsCombinedAsync(int? packageId = null, CancellationToken cancellationToken = default) ``` -------------------------------- ### Web App Authentication with appsettings.json Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/common-patterns.md This pattern is suitable for web applications, loading authentication details from the appsettings.json configuration file. It also demonstrates adding caching for API responses. ```json // appsettings.json { "iRacing": { "Username": "user@example.com", "Password": "password", "ClientId": "your-client-id", "ClientSecret": "your-client-secret" } } ``` ```csharp // Startup.cs public class Startup { private readonly IConfiguration _config; public Startup(IConfiguration config) { _config = config; } public void ConfigureServices(IServiceCollection services) { services.AddMemoryCache(); services.AddIRacingDataApiWithCaching(options => { var iracingConfig = _config.GetSection("iRacing"); options.UseProductUserAgent("MyWebApp", new Version(1, 0)); options.UsePasswordLimitedOAuth( iracingConfig["Username"]!, iracingConfig["Password"]!, iracingConfig["ClientId"]!, iracingConfig["ClientSecret"]!); }); } } ``` -------------------------------- ### Get Team Information Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves detailed information about a specific iRacing team using its unique team identifier. ```csharp Task> GetTeamAsync(int teamId, CancellationToken cancellationToken = default) ``` -------------------------------- ### Get Driver Information Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves information about one or more drivers by their customer IDs, with an option to include license details. ```csharp Task> GetDriverInfoAsync(int[] customerIds, bool includeLicenses, CancellationToken cancellationToken = default) ``` -------------------------------- ### List Hosted Sessions (Driver Joinable) Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Lists driver-joinable hosted sessions. Excludes spectator and non-league pending sessions. ```csharp Task> ListHostedSessionsAsync(CancellationToken cancellationToken = default) ``` -------------------------------- ### Configure User Agent and OAuth Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/quick-reference.md Set a custom user agent for your application and configure authentication using Password Limited OAuth. ```csharp // Set user agent options.UseProductUserAgent("AppName", new Version(1, 0)); // Password Limited OAuth options.UsePasswordLimitedOAuth(username, password, clientId, clientSecret); ``` -------------------------------- ### Configure OAuth Token Source Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/quick-reference.md Provide a custom token source for OAuth (Authorization Code Grant) flow. ```csharp // Custom token source (Authorization Code Grant) options.UseOAuthTokenSource(sp => tokenSource); ``` -------------------------------- ### Get Season Standings Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves season standings for a league. Standings can be filtered by car class or specific car. ```csharp Task> GetSeasonStandingsAsync(int leagueId, int seasonId, int? carClassId = null, int? carId = null, CancellationToken cancellationToken = default) ``` -------------------------------- ### Fake IDataClient Implementation Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/common-patterns.md Implement this pattern to create a concrete, albeit simplified, version of IDataClient for testing. This is useful when you need a functional, in-memory data source. ```csharp public class FakeDataClient : IDataClient { public Task> GetMyInfoAsync(CancellationToken cancellationToken = default) { return Task.FromResult(new DataResponse { Data = new MemberInfo { CustomerId = 12345, DisplayName = "Fake User", Email = "fake@example.com" } }); } public Task> GetCarsAsync(CancellationToken cancellationToken = default) { return Task.FromResult(new DataResponse { Data = new[] { new Cars.CarInfo { CarId = 1, CarName = "Fake Car 1" }, new Cars.CarInfo { CarId = 2, CarName = "Fake Car 2" } } }); } // ... implement remaining methods as needed ... } ``` ```csharp [Fact] public async Task MyService_WithFakeClient_Works() { var fakeClient = new FakeDataClient(); var service = new MyService(fakeClient); var result = await service.GetUserInfoAsync(); Assert.Equal("Fake User", result.DisplayName); } ``` -------------------------------- ### Get Season List Async (By Year/Quarter) Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves seasons for a specific year and quarter asynchronously. Supports cancellation. ```csharp Task> GetSeasonListAsync(int seasonYear, int seasonQuarter, bool includeSeries, CancellationToken cancellationToken = default) ``` -------------------------------- ### Get Seasons Async (Current) Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves current season and optionally series information asynchronously. Supports cancellation. ```csharp Task> GetSeasonsAsync(bool includeSeries, CancellationToken cancellationToken = default) ``` -------------------------------- ### Console App Authentication with Environment Variables Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/common-patterns.md Use this pattern for console applications where sensitive credentials should not be hardcoded. Ensure environment variables for username, password, client ID, and client secret are set. ```csharp using System; using Microsoft.Extensions.DependencyInjection; using Aydsko.iRacingData; var services = new ServiceCollection(); services.AddIRacingDataApi(options => { options.UseProductUserAgent("MyRacingTool", new Version(1, 0)); options.UsePasswordLimitedOAuth( userName: Environment.GetEnvironmentVariable("IRACING_USERNAME") ?? throw new InvalidOperationException("IRACING_USERNAME not set"), password: Environment.GetEnvironmentVariable("IRACING_PASSWORD") ?? throw new InvalidOperationException("IRACING_PASSWORD not set"), clientId: Environment.GetEnvironmentVariable("IRACING_CLIENT_ID") ?? throw new InvalidOperationException("IRACING_CLIENT_ID not set"), clientSecret: Environment.GetEnvironmentVariable("IRACING_CLIENT_SECRET") ?? throw new InvalidOperationException("IRACING_CLIENT_SECRET not set")); }); var serviceProvider = services.BuildServiceProvider(); var dataClient = serviceProvider.GetRequiredService(); var info = await dataClient.GetMyInfoAsync(); Console.WriteLine($"Authenticated as: {info.Data.DisplayName}"); ``` -------------------------------- ### Get Member Division Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves the authenticated member's division for a given season and event type. Divisions are 0-based. ```csharp Task> GetMemberDivisionAsync(int seasonId, Common.EventType eventType, CancellationToken cancellationToken = default) ``` -------------------------------- ### Search Drivers Async Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Searches for drivers by customer ID or partial name. Optionally limit results to a specific league. ```csharp Task> SearchDriversAsync(string searchTerm, int? leagueId = null, CancellationToken cancellationToken = default) ``` -------------------------------- ### Search League Directory Async Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Searches the league directory based on provided parameters. Returns a paginated result set. ```csharp Task> SearchLeagueDirectoryAsync(SearchLeagueDirectoryParameters searchParameters, CancellationToken cancellationToken = default) ``` -------------------------------- ### GetStatisticsSeriesAsync C# Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves a list of series that have available standings. Filter results where 'Official' is 'true' to get series with standings. ```csharp Task> GetStatisticsSeriesAsync(CancellationToken cancellationToken = default) ``` -------------------------------- ### Further HTTP Client Configuration Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/configuration.md Illustrates how to obtain the IHttpClientBuilder returned by AddIRacingDataApi and use it for additional HTTP client customizations, such as setting timeouts. ```csharp var httpClientBuilder = services.AddIRacingDataApi(options => { // Configure options }); // Further customize the HTTP client if needed httpClientBuilder.ConfigureHttpClient(client => { client.Timeout = TimeSpan.FromSeconds(60); }); ``` -------------------------------- ### Using CancellationToken with API Calls Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/getting-started.md Pass a CancellationToken to asynchronous methods to support cancellation of API requests, for example, with a timeout. ```csharp using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30)); var result = await dataClient.GetCarsAsync(cts.Token); ``` -------------------------------- ### Full iRacingDataClient Registration with HTTP Client Configuration Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/service-registration.md Provides comprehensive registration for the iRacingDataClient, including setting custom product user-agent, authentication details, API base URL, and configuring the underlying HTTP client with custom timeouts and resilience policies. ```csharp var services = new ServiceCollection(); var builder = services.AddIRacingDataApi(options => { // Set product information options.UseProductUserAgent("MyRacingApp", new Version(2, 1, 0)); // Configure authentication options.UsePasswordLimitedOAuth( "user@example.com", "password123", "client-id", "client-secret"); // Use custom API endpoints (optional) options.ApiBaseUrl = "https://api.example.com"; }); // Configure HTTP client builder.ConfigureHttpClient(client => { client.Timeout = TimeSpan.FromSeconds(30); }); // Add resilience policies builder.AddTransientHttpErrorPolicy(p => p.WaitAndRetryAsync(3, _ => TimeSpan.FromSeconds(2))); var provider = services.BuildServiceProvider(); ``` -------------------------------- ### Project File Structure Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/INDEX.md Overview of the directory and file structure for the Aydsko.iRacingData project. This helps in understanding the organization of the library's components. ```text Aydsko.iRacingData/ ├── IDataClient.cs # Main interface (77+ methods) ├── DataClient.cs # Implementation ├── iRacingDataClientOptions.cs # Configuration ├── DataClientOptionsExtensions.cs # Extension methods ├── ServicesExtensions.cs # DI registration ├── Exceptions/ # Custom exceptions (8 types) ├── Member/ # Member data types ├── Leagues/ # League data types ├── Results/ # Results & standings types ├── Series/ # Season & series types ├── Cars/ # Car information types ├── Tracks/ # Track information types ├── Searches/ # Search parameter types ├── Common/ # Shared types ├── Lookups/ # Reference data types ├── Hosted/ # Hosted session types ├── TimeAttack/ # Time Attack types └── Constants/ # Enums and constants ``` -------------------------------- ### Implement Custom OAuth Token Source Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/quick-reference.md Create a custom token source by implementing the IOAuthTokenSource interface. This is useful for managing token refresh logic, such as fetching from secure storage or an OAuth endpoint. ```csharp public class MyTokenSource : IOAuthTokenSource { public async Task GetTokenAsync(CancellationToken ct = default) { // Get token from secure storage or OAuth endpoint var token = await FetchTokenFromSecureStorageAsync(); if (token?.ExpiresAt <= DateTimeOffset.UtcNow) { // Token expired, refresh it token = await RefreshTokenAsync(); } return new OAuthTokenValue(token.AccessToken, token.ExpiresAt); } } // Register options.UseOAuthTokenSource(sp => sp.GetRequiredService()); ``` -------------------------------- ### Get Spectator Subsession Details Async Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves detailed spectator subsession information. Can be filtered by event types and season IDs. ```csharp Task> GetSpectatorSubsessionDetailsAsync(Common.EventType[]? eventTypes = null, int[]? seasonIds = null, CancellationToken cancellationToken = default) ``` -------------------------------- ### Get Flairs Async Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves available driver flair (country flag) items. Use this to access system-wide flair information. ```csharp Task> GetFlairsAsync(CancellationToken cancellationToken = default) ``` -------------------------------- ### Mock IDataClient for Unit Tests Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/common-patterns.md Use this pattern to isolate your service logic during unit testing. It requires the Moq library and sets up specific return values for mocked methods. ```csharp public class MockDataClientTests { [Fact] public async Task GetUserProfileAsync_ReturnsExpectedData() { // Arrange var mockDataClient = new Mock(); var expectedProfile = new MemberProfile { DisplayName = "Test User" }; var response = new DataResponse { Data = expectedProfile }; mockDataClient .Setup(x => x.GetMemberProfileAsync(It.IsAny(), It.IsAny())) .ReturnsAsync(response); var service = new MyService(mockDataClient.Object); // Act var result = await service.GetUserProfileAsync(); // Assert Assert.Equal("Test User", result.DisplayName); mockDataClient.Verify(x => x.GetMemberProfileAsync(null, It.IsAny()), Times.Once); } } ``` -------------------------------- ### Render Sponsor Decals Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/reference/Local API Reference.txt Renders sponsor decals. ```APIDOC ## GET /pk_sponsor.png ### Description Renders sponsor decals. ### Method GET ### Endpoint /pk_sponsor.png ### Parameters #### Query Parameters - **sponsors** (string) - Required - Identifier for the sponsor decal to render. - **view** (string) - Optional - Alternate rendered view of the image. ### Request Example ``` http://localhost:32034/pk_sponsor.png?sponsors=3&view=1 ``` ### Response #### Success Response (200) - Image data for the rendered sponsor decal. ``` -------------------------------- ### Configure Product User Agent Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/getting-started.md Set a custom User-Agent header to identify your application when making requests to the iRacing Data API. ```csharp options.UseProductUserAgent("MyApp", new Version(2, 1, 0)); ``` -------------------------------- ### Get Time Attack Seasons Async Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves a list of available Time Attack series. This method returns an array of TimeAttackSeason objects. ```csharp Task GetTimeAttackSeasonsAsync(CancellationToken cancellationToken = default) ``` -------------------------------- ### Search Hosted Results Async Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Searches for hosted session results over a maximum 90-day period. Requires specific search parameters and returns header and item data. ```csharp Task> SearchHostedResultsAsync(HostedSearchParameters searchParameters, CancellationToken cancellationToken = default) ``` -------------------------------- ### Get Service Status Async Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves the current iRacing service status. This method is useful for checking the availability and health of iRacing services. ```csharp Task GetServiceStatusAsync(CancellationToken cancellationToken = default) ``` -------------------------------- ### Basic Usage: Inject and Use IDataClient Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/getting-started.md Inject the IDataClient interface and use it to make API calls, such as retrieving user information, car lists, and season data. ```csharp var dataClient = serviceProvider.GetRequiredService(); // Get authenticated user's information var infoResponse = await dataClient.GetMyInfoAsync(); Console.WriteLine($"Driver: {infoResponse.Data.DisplayName}"); Console.WriteLine($"Customer ID: {infoResponse.Data.CustomerId}"); // Get list of cars in the system var carsResponse = await dataClient.GetCarsAsync(); foreach (var car in carsResponse.Data) { Console.WriteLine($"{car.CarId}: {car.CarName}"); } // Get season information var seasonsResponse = await dataClient.GetSeasonsAsync(includeSeries: true); foreach (var season in seasonsResponse.Data) { Console.WriteLine($"Season {season.SeasonId}: {season.SeasonName}"); } ``` -------------------------------- ### Get Past Seasons For Series Async Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves all seasons for a given series identifier. Results can be filtered for seasons with standings by checking the 'Official' property. ```csharp Task> GetPastSeasonsForSeriesAsync(int seriesId, CancellationToken cancellationToken = default) ``` -------------------------------- ### GetTrackAssetScreenshotUris (Sync) Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Builds a collection of URIs resolving to track screenshots using track and track asset details. ```APIDOC ## GetTrackAssetScreenshotUris (Sync) ### Description Builds a collection of URIs resolving to track screenshots. ### Method Sync (Implied) ### Parameters #### Path Parameters - **track** (Tracks.Track) - Yes - Track detail object - **trackAssets** (TrackAssets) - Yes - Related track assets for the same circuit ### Return Type `IEnumerable` containing screenshot links ``` -------------------------------- ### Register with Caching Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/quick-reference.md Enable caching for the iRacingData API by adding memory cache services and using AddIRacingDataApiWithCaching. ```csharp services.AddMemoryCache(); services.AddIRacingDataApiWithCaching(options => { // Configuration }); ``` -------------------------------- ### Get Member Chart Data Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Obtains data for generating member account charts, allowing filtering by customer ID, category, and chart type. ```csharp Task> GetMemberChartDataAsync(int? customerId, int categoryId, MemberChartType chartType, CancellationToken cancellationToken = default) ``` -------------------------------- ### Get Season Team Standings Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves team standings for a specific season and car class. Optional parameters allow filtering by race week. ```csharp Task> GetSeasonTeamStandingsAsync(int seasonId, int carClassId, int? raceWeekIndex = null, CancellationToken cancellationToken = default) ``` -------------------------------- ### Enable Console and Debug Logging Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/quick-reference.md Configure the application to log messages to the console and the debug output. This is essential for debugging and monitoring application behavior. ```csharp services.AddLogging(builder => { builder.AddConsole(); builder.AddDebug(); }); ``` -------------------------------- ### GetSeriesAsync C# Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves the current season's series details. Use this method to get a list of all available series for the current racing season. ```csharp Task> GetSeriesAsync(CancellationToken cancellationToken = default) ``` -------------------------------- ### Get Track Asset Screenshot URIs (Async) Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves track screenshot URIs asynchronously by track ID. Supports cancellation via CancellationToken. ```csharp Task> GetTrackAssetScreenshotUrisAsync(int trackId, CancellationToken cancellationToken = default) ``` -------------------------------- ### Get World Records Async Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves world record times for a specific car and track. Optional parameters allow filtering by season year and quarter. ```csharp Task> GetWorldRecordsAsync(int carId, int trackId, int? seasonYear = null, int? seasonQuarter = null, CancellationToken cancellationToken = default) ``` -------------------------------- ### Get Season Qualifying Results Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves qualifying results for a specific season and car class. Optional parameters allow filtering by race week and division. ```csharp Task> GetSeasonQualifyResultsAsync(int seasonId, int carClassId, int? raceWeekIndex = null, int? division = null, CancellationToken cancellationToken = default) ``` -------------------------------- ### Configure OAuth Token Callback (Deprecated) Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/configuration.md Configures a callback to retrieve OAuth tokens. This method is deprecated in favor of UseOAuthTokenSource. ```csharp [Obsolete("Using a callback to retrieve an OAuth token is deprecated...")] public static iRacingDataClientOptions UseOAuthTokenCallback( this iRacingDataClientOptions options, GetOAuthTokenResponse getOAuthTokenResponse) ``` -------------------------------- ### Get Season Driver Standings Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves driver standings for a season, filtered by car class. Optional parameters include race week index and division. ```csharp Task> GetSeasonDriverStandingsAsync(int seasonId, int carClassId, int? raceWeekIndex = null, int? division = null, CancellationToken cancellationToken = default) ``` -------------------------------- ### Register Web App with Custom OAuth Token Source Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/configuration.md Demonstrates registering the iRacing Data API for a web application using a custom IOAuthTokenSource implementation to manage OAuth tokens. This approach is suitable when you need fine-grained control over token retrieval and caching. ```csharp using Microsoft.Extensions.DependencyInjection; using Aydsko.iRacingData; public class OAuthTokenManager : IOAuthTokenSource { private readonly IHttpClientFactory _httpClientFactory; private OAuthTokenValue? _cachedToken; public OAuthTokenManager(IHttpClientFactory httpClientFactory) { _httpClientFactory = httpClientFactory; } public async Task GetTokenAsync(CancellationToken cancellationToken = default) { // Return cached token if still valid if (_cachedToken?.ExpiresAt > DateTimeOffset.UtcNow.AddSeconds(60)) { return _cachedToken; } // Request new token from iRacing OAuth endpoint var client = _httpClientFactory.CreateClient(); var response = await client.PostAsJsonAsync( "https://oauth.iracing.com/oauth/token", new { /* OAuth parameters */ }, cancellationToken); var result = await response.Content.ReadAsAsync(); var expiresAt = DateTimeOffset.UtcNow.AddSeconds(result.ExpiresInSeconds - 60); _cachedToken = new OAuthTokenValue(result.AccessToken, expiresAt); return _cachedToken; } } public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddHttpClient(); services.AddScoped(); services.AddIRacingDataApi(options => { options.UseProductUserAgent("MyWebApp", new Version(2, 0)); options.UseOAuthTokenSource(sp => sp.GetRequiredService()); }); } } ``` -------------------------------- ### Configure Username/Password Authentication (Deprecated) Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/configuration.md Configures legacy username/password authentication. This method is deprecated and no longer functional as iRacing removed legacy authentication support. ```csharp [Obsolete("Legacy username/password authentication is deprecated by iRacing...")] public static iRacingDataClientOptions UseUsernamePasswordAuthentication( this iRacingDataClientOptions options, string userName, string password, bool passwordIsEncoded = false) ``` -------------------------------- ### Execute Batch Operations with Rate Limit Checks Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/common-patterns.md This pattern executes a series of operations in batches, incorporating rate limit checks to prevent exceeding limits. It includes logic to wait for the rate limit to reset if exceeded and retries the operation. Ensure `RateLimitMonitor` is properly initialized and updated. ```csharp public class RateLimitedBatchOperation { private readonly IDataClient _dataClient; private readonly RateLimitMonitor _monitor; private const double MinPercentageRemaining = 10; // Never use more than 90% public async Task ExecuteBatchAsync( IEnumerable>>> operations) { var results = new List(); foreach (var operation in operations) { var info = _monitor.GetCurrent(); if (info.PercentRemaining < MinPercentageRemaining) { Console.WriteLine($"Rate limit approaching ({info.PercentRemaining:F1}%), waiting"); await Task.Delay(info.TimeUntilReset); } try { var response = await operation(); _monitor.Update(response); results.Add(response.Data); } catch (iRacingRateLimitExceededException) { Console.WriteLine("Hit rate limit, waiting"); var info = _monitor.GetCurrent(); await Task.Delay(info.TimeUntilReset); // Retry this operation var response = await operation(); _monitor.Update(response); results.Add(response.Data); } } return results.ToArray(); } } ``` -------------------------------- ### Get Team Subsession Laps Async Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves lap details for a team within a subsession. Requires subsession ID, simulation session number, and team ID. ```csharp Task> GetTeamSubsessionLapsAsync(int subSessionId, int simSessionNumber, int teamId, CancellationToken cancellationToken = default) ``` -------------------------------- ### Cache Reference Data Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/common-patterns.md Implements a cache for reference data like cars, tracks, and car classes using IMemoryCache. This reduces redundant API calls by storing data for a specified duration. ```csharp public class ReferenceDataCache { private readonly IDataClient _dataClient; private readonly IMemoryCache _cache; private static readonly TimeSpan CacheDuration = TimeSpan.FromHours(24); public ReferenceDataCache(IDataClient dataClient, IMemoryCache cache) { _dataClient = dataClient; _cache = cache; } public async Task GetCarsAsync() { const string key = "reference:cars"; if (!_cache.TryGetValue(key, out Car[] cars)) { var response = await _dataClient.GetCarsAsync(); cars = response.Data; _cache.Set(key, cars, new MemoryCacheEntryOptions { AbsoluteExpirationRelativeToNow = CacheDuration }); } return cars; } public async Task GetTracksAsync() { const string key = "reference:tracks"; if (!_cache.TryGetValue(key, out Track[] tracks)) { var response = await _dataClient.GetTracksAsync(); tracks = response.Data; _cache.Set(key, tracks, new MemoryCacheEntryOptions { AbsoluteExpirationRelativeToNow = CacheDuration }); } return tracks; } public async Task GetCarClassesAsync() { const string key = "reference:carclasses"; if (!_cache.TryGetValue(key, out CarClass[] classes)) { var response = await _dataClient.GetCarClassesAsync(); classes = response.Data; _cache.Set(key, classes, new MemoryCacheEntryOptions { AbsoluteExpirationRelativeToNow = CacheDuration }); } return classes; } } ``` -------------------------------- ### Search Official Results Async Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Searches for official session results over a maximum 90-day period. Requires specific search parameters and returns header and item data. ```csharp Task> SearchOfficialResultsAsync(OfficialSearchParameters searchParameters, CancellationToken cancellationToken = default) ``` -------------------------------- ### Get Season Results Async Source: https://github.com/adrianjsclark/aydsko-iracingdata/blob/main/_autodocs/api-reference-idataclient.md Retrieves race results for a given week within a season. Requires season ID, event type, and race week number. ```csharp Task> GetSeasonResultsAsync(int seasonId, Common.EventType eventType, int raceWeekNumber, CancellationToken cancellationToken = default) ```