Unofficial C# wrapper around Unsplash API targeting .NET Standard 2.0.
This lib is compatible with .NET Core, .NET Framework 4.6.1+, Xamarin (iOS, Android), Universal Windows Platform.
This library has been enhanced with modern .NET practices and reliability features:
- π Async/Await Patterns: Improved async patterns with proper
ConfigureAwait(false)
usage - βΉοΈ Cancellation Token Support: All async methods now support
CancellationToken
for request cancellation and timeouts - π Structured Logging: Built-in support for Microsoft.Extensions.Logging with detailed request/response logging
- π Retry Policies: Automatic retry logic using Polly for resilient HTTP requests
- β‘ Performance: Migrated to System.Text.Json for 2-3x faster JSON processing and reduced memory usage
- π‘οΈ Comprehensive Error Handling: Structured exceptions with rich context for better debugging and error recovery
- π Modern JSON: System.Text.Json integration with custom converters and safe property access
Currently incomplete π§
- Missing user's authentication actions
Comprehensive documentation is available with guides for all experience levels:
- π Complete Documentation Hub - Start here for everything
- π Getting Started Guide - Step-by-step setup and examples
- π API Reference - Complete method documentation
- π‘ Code Examples - Practical examples and recipes
- β‘ Quick Reference - Fast reference for common operations
- New to Unsplasharp? β Getting Started
- Need specific examples? β Code Examples
- Having issues? β Error Handling Guide
- Building for production? β Best Practices
- Upgrading versions? β Migration Guide
NuGet: Install-Package unsplasharp.api
using Unsplasharp;
var client = new UnsplasharpClient("YOUR_APPLICATION_ID");
var photosFound = await client.SearchPhotos("mountains");
All async methods now support CancellationToken
for request cancellation and timeout handling:
using Unsplasharp;
var client = new UnsplasharpClient("YOUR_APPLICATION_ID");
// Timeout after 30 seconds
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
var photo = await client.GetRandomPhoto(cts.Token);
// Manual cancellation
using var cts2 = new CancellationTokenSource();
var searchTask = client.SearchPhotos("nature", 1, 10, cts2.Token);
// Later: cts2.Cancel();
// Integration with ASP.NET Core
public async Task<IActionResult> GetPhoto(string id, CancellationToken cancellationToken)
{
var photo = await client.GetPhoto(id, 0, 0, cancellationToken);
return Ok(photo);
}
Supported Methods:
- All photo methods:
GetPhoto()
,GetRandomPhoto()
,ListPhotos()
,SearchPhotos()
- All collection methods:
GetCollection()
,ListCollections()
,GetCollectionPhotos()
- All user methods:
GetUser()
- All search methods:
SearchPhotos()
,SearchCollections()
- Stats methods:
GetTotalStats()
π Backward Compatibility: All existing method signatures remain unchanged. Cancellation token support is added as optional overloads, so your existing code will continue to work without any modifications.
using Unsplasharp;
using Microsoft.Extensions.Logging;
// Create a logger factory
using var loggerFactory = LoggerFactory.Create(builder =>
builder.AddConsole().SetMinimumLevel(LogLevel.Debug));
var logger = loggerFactory.CreateLogger<UnsplasharpClient>();
// Create client with logging support
var client = new UnsplasharpClient("YOUR_APPLICATION_ID", logger: logger);
// The client will now log HTTP requests, retries, and errors
var photos = await client.SearchPhotos("nature");
For ASP.NET Core and modern .NET applications, use the IHttpClientFactory integration:
using Unsplasharp.Extensions;
// In Program.cs or Startup.cs
builder.Services.AddUnsplasharp("YOUR_APPLICATION_ID");
// Or with configuration
builder.Services.AddUnsplasharp(options =>
{
options.ApplicationId = "YOUR_APPLICATION_ID";
options.Secret = "YOUR_SECRET"; // Optional
options.ConfigureHttpClient = client =>
{
client.Timeout = TimeSpan.FromSeconds(60);
};
});
// In your controller or service
public class PhotoService
{
private readonly UnsplasharpClient _client;
public PhotoService(UnsplasharpClient client)
{
_client = client;
}
public async Task<List<Photo>> GetPhotos(string query)
{
return await _client.SearchPhotos(query);
}
}
- π IHttpClientFactory Support: Modern HTTP client management with proper lifecycle and DI integration
- π Automatic Retries: Failed requests are automatically retried up to 3 times with exponential backoff
- π Structured Logging: Detailed logging of HTTP requests, responses, and retry attempts
- π Rate Limit Tracking: Built-in rate limit monitoring and logging
- β‘ Async/Await: All methods use proper async patterns with
ConfigureAwait(false)
- π High Performance JSON: System.Text.Json for faster parsing and lower memory usage
- π§ Dependency Injection: Seamless integration with .NET DI containers
- π Backward Compatible: Existing code continues to work without changes
Unsplasharp now provides structured exception handling with rich context information for better debugging and error recovery:
try {
// New methods that throw specific exceptions
var photo = await client.GetRandomPhotoAsync();
var specificPhoto = await client.GetPhotoAsync("photo-id");
} catch (UnsplasharpNotFoundException ex) {
// Handle resource not found (404)
Console.WriteLine($"Photo '{ex.ResourceId}' not found");
} catch (UnsplasharpRateLimitException ex) {
// Handle rate limiting (429)
Console.WriteLine($"Rate limit exceeded. Reset at: {ex.RateLimitReset}");
await Task.Delay(ex.TimeUntilReset ?? TimeSpan.FromMinutes(1));
} catch (UnsplasharpAuthenticationException ex) {
// Handle authentication errors (401)
Console.WriteLine("Invalid application ID or access token");
} catch (UnsplasharpNetworkException ex) when (ex.IsRetryable) {
// Handle retryable network errors
Console.WriteLine("Temporary network error, will retry automatically");
} catch (UnsplasharpException ex) {
// Handle any other API errors
Console.WriteLine($"API Error: {ex.Message}");
Console.WriteLine($"Context: {ex.Context?.ToSummary()}");
}
Key Features:
- π― Specific Exception Types: Different exceptions for different error scenarios
- π Rich Error Context: Correlation IDs, timing, rate limits, and request details
- π Intelligent Retries: Automatic retry logic based on error types
- π Backward Compatibility: Existing methods still return null/empty on errors
- π Enhanced Logging: Structured logging with correlation IDs for debugging
For detailed information, see the Error Handling Guide.
- Error Handling Guide - Comprehensive error handling with structured exceptions
- IHttpClientFactory Integration Guide - Comprehensive guide for modern .NET applications
- Logging Guide - Detailed logging configuration and usage
- System.Text.Json Migration Guide - Performance improvements and technical details
- Changelog - Version history and breaking changes
It's necessary to instanciate a new client with at least an application ID to start making requests.
var client = new Client("YOUR_APPLICATION_ID");
Unsplash has API requests rates limits.
An Unsplashsharp client has two properties to help you monitor API calls:
Max API calls allowed per hour
MaxRateLimit
API calls remaining for the current hour
RateLimitRemaining
if (client.RateLimitRemaining == 0) {
// Warning the user that he's to wait some time
// before using the app again.
}
if (client.MaxRateLimit == 50) {
// Application is in dev mode.
} else if (client.MaxRateLimit == 5000) {
// Application is in prod mode.
} else { /* Unknown mode */ }
var photo = await client.GetPhoto("TPv9dh822VA");
// get a photo in the specified width and height in pixels
var photoWidthHeight = await client.GetPhoto(id: "TPv9dh822VA", width: 500, height: 500);
var randomPhoto = await client.GetRandomPhoto();
// using collections' IDs
var randomPhotoFromCollections = await client.GetRandomPhoto(new string[] { "499830", "194162" });
// from a specific user
var randomPhotoFromUser = await client.GetRandomPhoto(count: 1, username: "matthewkane");
var randomPhotosFromQuery = await client.GetRandomPhoto(count: 3, query:"woman");
var listPhotos = await client.ListPhotos();
var listPhotosPaged = await client.ListPhotos(page:2, perPage:15, orderBy: OrderBy.Popular);
var collection = await client.GetCollection("771520");
var listCollection = await client.ListCollections();
var listFeaturedCollection = await client.ListFeaturedCollections();
var listPhotos = await client.GetCollectionPhotos("771520");
var collectionsRelated = await client.ListRelatedCollections("771520");
var user = await client.GetUser("unsplash");
var userCustomProfileImage = client.GetUser("seteales", width: 100, height: 100);
var userCollections = await client.ListUserCollections("unsplash");
var userPhotos = await client.ListUserPhotos("seteales");
var userPhotosCustomParam = await client.ListUserPhotos("seteales", page: 2, perPage: 2, stats: true);
var userLikedPhotos = await client.ListUserLikedPhotos("seteales");
var userStats = await client.GetUserStats("seteales");
var photosFound = await client.SearchPhoto("mountains");
var collectionsFound = await client.SearchCollections("mountains");
var usersFound = await client.SearchUsers("seteales");
Get Unsplash total stats
var totalStats = await client.GetTotalStats();
Get Unsplash monthly stats
var monthlyStats = await client.GetMonthlyStats();
In adition to the previous API methods, you can build and use custom URL's to fetch photos, photos' lists, and collections' lists.
There're also methods to search for collections, photos and users using a custom URL.
var photo = await client.FetchPhoto("you_custom_url");
var photos = await client.FetchPhotosList("you_custom_url");
var collections = await client.FetchCollectionsList("you_custom_url");
var photosFound = await client.FetchSearchPhotosList("your_custom_url");
var collectionsFound = await client.FetchSearcCollectionsList("your_custom_url");
var usersFound = await client.FetchSearcUsersList("your_custom_url");
Tests are under UnsplashsharpTests project.
They check the Unsplash API status and that every methods in the lib works properly.
In this project, a dev API key is used which is limited to 50 requests per hour. So ensure you're not off limit.
If you want to get your personal API key from Unsplash:
- Go to Unsplash
- Log in or create a new account
- In the top bar, click on 'API/Developers'
- Go to 'Your applications'
- Click on 'New Application' to create a new one and get an API key (and a Secret).
- System.Text.Json - High-performance JSON serialization (included in .NET Standard 2.0+)
- Microsoft.Extensions.Logging.Abstractions - Structured logging support
- Microsoft.Extensions.Http - IHttpClientFactory integration
- Polly - Resilience and retry policies
Newtonsoft.Json- Replaced with System.Text.Json for better performance