| GitHubApiStatus | GitHubApiStatus.Extensions | 
|---|---|
GitHubApiStatus makes it easy to understand GitHub's API Rate Limit!
- Jump to the Setup
 - Jump to the GitHubApiStatus API
 - Jump to the GitHubApiStatus.Extensions API
 - Jump to Examples
 
For more information, check out this blog post, Introducing GitHubApiStatus

(From the GitHub REST API Docs)
(From the GitHub GraphQL API Docs)
- Available on NuGet: https://www.nuget.org/packages/GitHubApiStatus/
 - Add to any project supporting .NET Standard 1.3
 
- Available on NuGet: https://www.nuget.org/packages/GitHubApiStatus.Extensions/
 - Add to any project supporting .NET Standard 2.0
 - Leverages Microsoft.Extensions.Http
 
public Task<GitHubApiRateLimits> GetApiRateLimits(AuthenticationHeaderValue authenticationHeaderValue)- Get the current GitHub API Rate Limit status
 - Returns 
RateLimitDatafor the following GitHub APIs:- REST API
 - Search API
 - GraphQL API
 - Source Import API
 - App Manifest Configuration API
 
 - Leverage's GitHub Rate Limit API which does not count against your rate limit totals
 
public int GetRateLimit(HttpResponseHeaders httpResponseHeaders)- Get the total number of GitHub API Requests available
 - Parses the 
X-RateLimit-Limitheader and return itsintvalue 
public int GetRemainingRequestCount(HttpResponseHeaders httpResponseHeaders)- Get the number of GitHub API Requests remaining
 - Parses the 
X-RateLimit-Remainingheader and return itsintvalue 
public bool HasReachedMaximumApiCallLimit(HttpResponseHeaders httpResponseHeaders)- Determines whether the maximum number of requests
 - Parses the 
X-RateLimit-Remainingheader and returns wether or not it is greater than 0 
public TimeSpan GetRateLimitTimeRemaining(HttpResponseHeaders httpResponseHeaders)- Get the time remaining until GitHub API rate limit resets
 - Parses the 
X-RateLimit-Resetheader and returns theTimeSpanvalue from the current time 
public bool IsResponseFromAuthenticatedRequest(HttpResponseHeaders httpResponseHeaders)- Determine whether the request was made using an authenticated bearer token
 - Determines whether or not the 
Authorizationkey exists in theVaryheader 
public DateTimeOffset GetRateLimitResetDateTime(HttpResponseHeaders httpResponseHeaders)- Get the Date Time when the GitHub API rate limit resets
 - Parses the 
X-RateLimit-Resetheader and returns itsDateTimeOffsetvalue 
public long GetRateLimitResetDateTime_UnixEpochSeconds(HttpResponseHeaders httpResponseHeaders)- Get the Date Time when the GitHub API rate limit resets
 - Parses the 
X-RateLimit-Resetheader and returns itslongvalue in Unix Epoch Seconds 
public static bool DoesContainGitHubRateLimitHeader(this HttpResponseHeaders headers)- Returns whether HttpResponseHeaders Contain X-RateLimit-Limit
 
public static bool DoesContainGitHubRateLimitResetHeader(this HttpResponseHeaders headers)- Returns whether HttpResponseHeaders Contain X-RateLimit-Reset
 
public static bool DoesContainGitHubRateLimitRemainingHeader(this HttpResponseHeaders headers)- Returns whether HttpResponseHeaders Contain X-RateLimit-Remaining
 
public static IHttpClientBuilder AddGitHubApiStatusService(this IServiceCollection services, AuthenticationHeaderValue authenticationHeaderValue, ProductHeaderValue productHeaderValue)- Adds GitHubApiStatus.GitHubApiStatusService to 
Microsoft.Extensions.DependencyInjection.IServiceCollection 
public static IHttpClientBuilder AddGitHubApiStatusService<TGitHubApiStatusService>(this IServiceCollection services, AuthenticationHeaderValue authenticationHeaderValue, ProductHeaderValue productHeaderValue) where TGitHubApiStatusService : IGitHubApiStatusService- Adds a custom implementation of IGitHubApiStatusService to 
Microsoft.Extensions.DependencyInjection.IServiceCollection 
- Jump to Get Current GitHub API Status
 - Jump to Parse API Status from HttpResponseHeaders
 - Jump to Dependency Injection
 
static async Task Main(string[] args)
{
    var gitHubApiStatusService = new GitHubApiStatusService(new AuthenticationHeaderValue("bearer", "Your GitHub Personal Access Token, e.g. 123456789012345"));
    //Generate Personal Access Token https://github.com/settings/tokens
    var apiRateLimits = await gitHubApiStatusService.GetApiRateLimits();
    // REST API Results
    Console.WriteLine($"What is the GitHub REST API Rate Limit? {apiRateLimits.RestApi.RateLimit}"); // What is the GitHub REST API Rate Limit? 5000
    Console.WriteLine($"How many REST API requests do I have remaining? {apiRateLimits.RestApi.RemainingRequestCount}"); // How many REST API requests do I have remaining? 4983
    Console.WriteLine($"How long until the GitHub REST API Rate Limit resets? {apiRateLimits.RestApi.RateLimitReset_TimeRemaining}"); // How long until the GitHub REST API Rate Limit resets? 00:40:13.8035515
    Console.WriteLine($"When does the GitHub REST API Rate Limit reset? {apiRateLimits.RestApi.RateLimitReset_DateTime}"); // When does the GitHub REST API Rate Limit reset? 10/29/2020 3:28:58 AM +00:00
    Console.WriteLine();
    // GraphQL API Results
    Console.WriteLine($"What is the GitHub GraphQL API Rate Limit? {apiRateLimits.GraphQLApi.RateLimit}"); // What is the GitHub GraphQL API Rate Limit? 5000
    Console.WriteLine($"How many GraphQL API requests do I have remaining? {apiRateLimits.GraphQLApi.RemainingRequestCount}"); // How many GraphQL API requests do I have remaining? 5000
    Console.WriteLine($"How long until the GitHub GraphQL API Rate Limit resets? {apiRateLimits.GraphQLApi.RateLimitReset_TimeRemaining}"); // How long until the GitHub GraphQL API Rate Limit resets? 00:59:59.8034526
    Console.WriteLine($"When does the GitHub GraphQL API Rate Limit reset? {apiRateLimits.GraphQLApi.RateLimitReset_DateTime}"); // When does the GitHub GraphQL API Rate Limit reset? 10/29/2020 3:48:44 AM +00:00
    Console.WriteLine();
    // Search API Results
    Console.WriteLine($"What is the GitHub Search API Rate Limit? {apiRateLimits.SearchApi.RateLimit}"); // What is the GitHub Search API Rate Limit? 30
    Console.WriteLine($"How many Search API requests do I have remaining? {apiRateLimits.SearchApi.RemainingRequestCount}"); // How many Search API requests do I have remaining? 30
    Console.WriteLine($"How long until the GitHub Search API Rate Limit resets? {apiRateLimits.SearchApi.RateLimitReset_TimeRemaining}"); // How long until the GitHub Search API Rate Limit resets? 00:00:59.8034988
    Console.WriteLine($"When does the GitHub Search API Rate Limit reset? {apiRateLimits.SearchApi.RateLimitReset_DateTime}"); // When does the GitHub Search API Rate Limit reset? 10/29/2020 2:49:44 AM +00:00
    
    Console.WriteLine();
    // Source Import API Results
    Console.WriteLine($"What is the GitHub Source Import API Rate Limit? {apiRateLimits.SourceImport.RateLimit}"); // What is the GitHub Source Import API Rate Limit? 100
    Console.WriteLine($"How many Source Import API requests do I have remaining? {apiRateLimits.SourceImport.RemainingRequestCount}"); // How many Source Import API requests do I have remaining? 100
    Console.WriteLine($"How long until the GitHub Source Import API Rate Limit resets? {apiRateLimits.SourceImport.RateLimitReset_TimeRemaining}"); // How long until the GitHub Source Import API Rate Limit resets? 00:00:59.8034154
    Console.WriteLine($"When does the GitHub Source Import API Rate Limit reset? {apiRateLimits.SourceImport.RateLimitReset_DateTime}"); // When does the GitHub Source Import API Rate Limit reset? 10/29/2020 2:49:44 AM +00:00
    Console.WriteLine();
    // App Manifest Configuration API Results
    Console.WriteLine($"What is the GitHub App Manifest Configuration API Rate Limit? {apiRateLimits.AppManifestConfiguration.RateLimit}"); // What is the GitHub App Manifest Configuration API Rate Limit? 5000
    Console.WriteLine($"How many App Manifest Configuration API requests do I have remaining? {apiRateLimits.AppManifestConfiguration.RemainingRequestCount}"); // How many App Manifest Configuration API requests do I have remaining? 5000
    Console.WriteLine($"How long until the GitHub App Manifest Configuration API Rate Limit resets? {apiRateLimits.AppManifestConfiguration.RateLimitReset_TimeRemaining}"); // How long until the GitHub App Manifest Configuration API Rate Limit resets? 00:59:59.8033802
    Console.WriteLine($"When does the GitHub App Manifest Configuration API Rate Limit reset? {apiRateLimits.AppManifestConfiguration.RateLimitReset_DateTime}"); // When does the GitHub App Manifest Configuration API Rate Limit reset? 10/29/2020 3:48:44 AM +00:00
    Console.WriteLine();
    // Code Scanning Upload API Results
    Console.WriteLine($"What is the GitHub Code Scanning Upload API Rate Limit? {apiRateLimits.CodeScanningUpload.RateLimit}"); // What is the GitHub Code Scanning Upload API Rate Limit? 500
    Console.WriteLine($"How many Code Scanning Upload API requests do I have remaining? {apiRateLimits.CodeScanningUpload.RemainingRequestCount}"); // How many Code Scanning Upload API requests do I have remaining? 500
    Console.WriteLine($"How long until the GitHub Code Scanning Upload API Rate Limit resets? {apiRateLimits.CodeScanningUpload.RateLimitReset_TimeRemaining}"); // How long until the GitHub Code Scanning Upload API Rate Limit resets? 00:59:59.8033455
    Console.WriteLine($"When does the GitHub Code Scanning Upload API Rate Limit reset? {apiRateLimits.CodeScanningUpload.RateLimitReset_DateTime}"); // When does the GitHub Code Scanning Upload API Rate Limit reset? 10/29/2020 3:48:44 AM +00:00
}const string _gitHubRestApiUrl = "https://api.github.com";
static readonly HttpClient _client = new HttpClient
{
    DefaultRequestHeaders =
    {
        { "Authorization", "bearer [Your GitHub Personal Access Token, e.g. 123456789012345]" }
        { "User-Agent", "GitHubApiStatus" }
    }
};
static async Task Main(string[] args)
{
    var gitHubApiStatusService = new GitHubApiStatusService(_client);
    HttpResponseMessage restApiResponse = await _client.GetAsync($"{ _gitHubRestApiUrl}/repos/brminnick/GitHubApiStatus");
    restApiResponse.EnsureSuccessStatusCode();
    TimeSpan rateLimitTimeRemaining = gitHubApiStatusService.GetRateLimitTimeRemaining(restApiResponse.Headers);
    int rateLimit = gitHubApiStatusService.GetRateLimit(restApiResponse.Headers);
    int remainingRequestCount = gitHubApiStatusService.GetRemainingRequestCount(restApiResponse.Headers);
    bool isAuthenticated = gitHubApiStatusService.IsResponseFromAuthenticatedRequest(restApiResponse.Headers);
    bool hasReachedMaximumApiLimit = gitHubApiStatusService.HasReachedMaximumApiCallLimit(restApiResponse.Headers);
    Console.WriteLine($"What is the GitHub REST API Rate Limit? {rateLimit}"); // What is the GitHub REST API Rate Limit? 60
    Console.WriteLine($"Have I reached the Maximum REST API Limit? {hasReachedMaximumApiLimit}"); // Have I reached the Maximum REST API Limit? False
    Console.WriteLine($"How many REST API requests do I have remaining? {remainingRequestCount}"); // How many REST API requests do I have remaining? 56
    Console.WriteLine($"How long until the GitHub REST API Rate Limit resets? {rateLimitTimeRemaining}"); // How long until the GitHub REST API Rate Limit resets? 00:29:12.4134330
    Console.WriteLine($"Did the GitHub REST API Request include a Bearer Token? {isAuthenticated}"); // Did GitHub REST API Request include a Bearer Token? False
}public class Program
{
    public static Task Main(string[] args)
    {
        var builder = WebAssemblyHostBuilder.CreateDefault(args);
        builder.RootComponents.Add<App>("#app");
        builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
        // AddGitHubApiStatusService 
        builder.Services.AddGitHubApiStatusService(new AuthenticationHeaderValue("bearer", "[Your GitHub Personal Access Token, e.g. 123456789012345]"), new ProductHeaderValue("MyApp"))
            .ConfigurePrimaryHttpMessageHandler(config => new HttpClientHandler { AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate });
        return builder.Build().RunAsync();
    }
}@page "/graphql"
@using GitHubApiStatus
@inject IGitHubApiStatusService GitHubApiStatusService
<h1>GitHub REST Api Status</h1>
<p>@_graphQLApiStatus</p>
<button class="btn btn-primary" @onclick="GetGraphQLApiStatus">Get Status</button>
@code {
    string _graphQLApiStatus = string.Empty;
    async Task GetGraphQLApiStatus()
    {
        var apiRateLimitStatuses = await GitHubApiStatusService.GetApiRateLimits(System.Threading.CancellationToken.None).ConfigureAwait(false);
        _graphQLApiStatus = apiRateLimitStatuses.GraphQLApi.ToString();
    }
}- Learn more about Dependency Injection in ASP.NET Core
 
public class Startup
{
    // ...
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddGitHubApiStatusService(new AuthenticationHeaderValue("bearer", "[Your GitHub Personal Access Token, e.g. 123456789012345]"), new ProductHeaderValue("MyApp"))
            .ConfigurePrimaryHttpMessageHandler(config => new HttpClientHandler { AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate });
        services.AddRazorPages();
    }
    /// ...
}class MyPageModel : PageModel
{
    readonly ILogger<IndexModel> _logger;
    readonly IGitHubApiStatusService _gitHubApiStatusService;
    public MyPageModel(IGitHubApiStatusService gitHubApiStatusService, ILogger<MyPageModel> logger)
    {
        _logger = logger;
        _gitHubApiStatusService = gitHubApiStatusService;
    }
    // ...
}- Requires Microsoft.Azure.Functions.Extensions NuGet Package
 - Learn More about Azure Functions Dependency Injection
 
[assembly: FunctionsStartup(typeof(MyApp.Functions.Startup))]
namespace MyApp.Functions
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            builder.Services.AddGitHubApiStatusService(new AuthenticationHeaderValue("bearer", "[Your GitHub Personal Access Token, e.g. 123456789012345]"), new ProductHeaderValue("MyApp"))
                .ConfigurePrimaryHttpMessageHandler(config => new HttpClientHandler { AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate });
        }
    }
}class GitHubApiStatusFunction
{
    readonly IGitHubApiStatusService _gitHubApiStatusService;
    public MyHttpTriggerFunction(IGitHubApiStatusService gitHubApiStatusService) => _gitHubApiStatusService = gitHubApiStatusService
    [FunctionName("GitHubApiStatus")]
    public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req, ILogger log)
    {
        log.LogInformation("C# HTTP trigger function processed a request.");
        var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(2));
        var apiStatus = await _gitHubApiStatusService.GetApiRateLimits(cancellationTokenSource.Token).ConfigureAwait(false);
        return new OkObjectResult(apiStatus);
    }
}

