A simple, modern Updown.io .NET Client
https://www.nuget.org/packages/UpdownDotnet
Don't currently utilize Updown.IO? Join here --> https://updown.io/r/WioVu
- ✅ Full API Coverage: Checks, Recipients, Status Pages, Pulse Monitoring, Downtimes, Metrics, and Nodes
- ✅ Modern Async/Await: All methods support async patterns with
CancellationToken - ✅ Custom Exceptions: Specific exception types for better error handling
- ✅ Nullable Reference Types: Full nullability annotations for safer code
- ✅ Multi-Targeting: Supports .NET 9, .NET 8, .NET 6, and .NET Standard 2.0
- ✅ Comprehensive Testing: 49+ unit tests with 100% pass rate
- ✅ XML Documentation: Full IntelliSense support
dotnet add package UpdownDotnetusing UpdownDotnet;
using UpdownDotnet.Models;
// Create client using builder (recommended)
var client = new UpdownClientBuilder()
.WithApiKey("your-api-key")
.Build();
// Get all checks
var checks = await client.ChecksAsync();
// Create a new check
var checkParams = new CheckParameters
{
Url = "https://example.com",
Alias = "My Website",
Period = 60 // Check every 60 seconds
};
var check = await client.CheckCreateAsync(checkParams);| Entity | Status |
|---|---|
| Checks | ✅ Complete |
| Downtimes | ✅ Complete |
| Metrics | ✅ Complete |
| Nodes | ✅ Complete |
| Recipients | ✅ Complete |
| Status Pages | ✅ Complete |
| Pulse Monitoring | ✅ Complete |
// Get all checks
var checks = await client.ChecksAsync();
// Get specific check
var check = await client.CheckAsync("check-token");
// Create a check
var parameters = new CheckParameters
{
Url = "https://example.com",
Alias = "Example Site",
Period = 300,
Enabled = true
};
var newCheck = await client.CheckCreateAsync(parameters);
// Update a check
var updateParams = new CheckParameters { Period = 600 };
var updated = await client.CheckUpdateAsync("check-token", updateParams);
// Delete a check
await client.CheckDeleteAsync("check-token");// Get downtimes for a check
var downtimes = await client.DowntimesAsync("check-token");
// With pagination
var page2 = await client.DowntimesAsync("check-token", page: 2);// Get metrics for a check
var metrics = await client.MetricsAsync("check-token");
// Get metrics for a date range
var metrics = await client.MetricsAsync(
"check-token",
from: "2024-01-01",
to: "2024-01-31"
);
// Group by time or location
var metrics = await client.MetricsAsync(
"check-token",
group: "time"
);// Get all monitoring nodes
var nodes = await client.NodesAsync();
// Get IPv4 addresses
var ipv4 = await client.NodesIpv4Async();
// Get IPv6 addresses
var ipv6 = await client.NodesIpv6Async();Pulse monitoring is used to monitor cron jobs, background tasks, and scheduled processes. Your application sends heartbeat signals to Updown.io on schedule.
// Send a pulse heartbeat
await client.SendPulseAsync("https://pulse.updown.io/YOUR-TOKEN/YOUR-KEY");
// In a scheduled job
public async Task RunScheduledTask()
{
try
{
// Your work here
await DoImportantWork();
// Send success pulse
await client.SendPulseAsync(pulseUrl);
}
catch (Exception ex)
{
// Don't send pulse on failure - Updown.io will alert you
_logger.LogError(ex, "Task failed");
}
}The client provides specific exception types for different error scenarios:
using UpdownDotnet.Exceptions;
try
{
var check = await client.CheckAsync("token");
}
catch (UpdownNotFoundException ex)
{
// 404 - Check not found
Console.WriteLine("Check doesn't exist");
}
catch (UpdownUnauthorizedException ex)
{
// 401 - Invalid API key
Console.WriteLine("Authentication failed");
}
catch (UpdownBadRequestException ex)
{
// 400 - Invalid request parameters
Console.WriteLine($"Bad request: {ex.ResponseContent}");
}
catch (UpdownRateLimitException ex)
{
// 429 - Rate limit exceeded
Console.WriteLine($"Rate limited. Retry after {ex.RetryAfterSeconds}s");
if (ex.RetryAfterSeconds.HasValue)
{
await Task.Delay(TimeSpan.FromSeconds(ex.RetryAfterSeconds.Value));
// Retry...
}
}
catch (UpdownApiException ex)
{
// Other API errors (500+)
Console.WriteLine($"API error: {ex.StatusCode} - {ex.Message}");
}Program.cs:
// Register with dependency injection
builder.Services.AddHttpClient<IUpdownService, UpdownService>((sp, client) =>
{
client.BaseAddress = new Uri("https://updown.io");
var apiKey = builder.Configuration["Updown:ApiKey"];
client.DefaultRequestHeaders.Add("X-API-KEY", apiKey);
});Service Implementation:
public class UpdownService : IUpdownService
{
private readonly UpdownClient _client;
public UpdownService(HttpClient httpClient)
{
_client = new UpdownClient(httpClient);
}
public async Task<List<Check>> GetAllChecksAsync(CancellationToken ct = default)
{
return await _client.ChecksAsync(ct);
}
}var client = new UpdownClientBuilder()
.WithApiKey("your-api-key")
.WithTimeout(TimeSpan.FromSeconds(30))
.WithUserAgent("MyApp/1.0")
.Build();var handler = new SocketsHttpHandler
{
PooledConnectionLifetime = TimeSpan.FromMinutes(5),
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
};
var client = new UpdownClientBuilder()
.WithApiKey("your-api-key")
.WithHttpMessageHandler(handler)
.Build();// Pass cancellation token for long-running operations
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
try
{
var checks = await client.ChecksAsync(cts.Token);
}
catch (OperationCanceledException)
{
Console.WriteLine("Request cancelled");
}Version 2.0 introduces several improvements while maintaining backward compatibility:
Old (still works, but deprecated):
var client = UpdownClientFactory.Create("api-key");
var checks = await client.Checks(); // No Async suffix
var check = await client.Check("token");New (recommended):
var client = new UpdownClientBuilder()
.WithApiKey("api-key")
.Build();
var checks = await client.ChecksAsync(); // Async suffix
var check = await client.CheckAsync("token");For full migration details, see the CHANGELOG.
-
Use the Builder Pattern: More flexible and thread-safe than the factory
var client = new UpdownClientBuilder().WithApiKey("key").Build();
-
Pass CancellationTokens: Especially in web applications
await client.ChecksAsync(cancellationToken);
-
Handle Specific Exceptions: Use custom exception types for better error handling
catch (UpdownRateLimitException ex) { /* Handle rate limit */ }
-
Use Async Methods: Always use methods with
Asyncsuffixawait client.ChecksAsync(); // ✅ Good await client.Checks(); // ⚠️ Deprecated
-
Dispose HttpClient Properly: When using custom HttpClient instances
using var httpClient = new HttpClient(); var client = new UpdownClient(httpClient);
- Verify your API key is correct
- Check that the API key is active in your Updown.io dashboard
- Updown.io has rate limits on API calls
- Catch
UpdownRateLimitExceptionand respectRetryAfterSeconds - Consider caching responses when appropriate
- Default timeout is 100 seconds
- Configure custom timeout using
UpdownClientBuilder.WithTimeout()
Contributions are welcome! Please see our Contributing Guide for details.
git clone https://github.com/strvmarv/updown-dotnet.git
cd updown-dotnet
dotnet restore
dotnet builddotnet test- API Reference - Complete API documentation
- Architecture - Design and architecture details
- CHANGELOG - Version history and migration guides
- Updown.io API Docs - Official API documentation
MIT License - see LICENSE file for details
Made with ❤️ for the .NET community