How to Consume a Third-Party API in .NET Core etd_admin, December 22, 2025December 22, 2025 When your app needs data from outside services (payments, weather, shipping, identity, etc.), you typically call a third-party API over HTTP. In .NET Core, the recommended way is to use HttpClient via IHttpClientFactory, handle JSON serialization, and add basic resilience (timeouts, retries, and error handling). If you’re learning to consume a third-party API in .NET core, the key is building a small, testable client class that your application can reuse. Add the Right Packages For modern .NET (6/7/8+), you can use the built-in JSON library: System.Net.Http (built-in) System.Text.Json (built-in) No extra packages are required for basic JSON requests. Register an HttpClient using IHttpClientFactory In an ASP.NET Core app, register a named or typed client. A typed client is clean and testable. Program.cs: using System.Net.Http.Headers; var builder = WebApplication.CreateBuilder(args); // Typed client registration builder.Services.AddHttpClient<WeatherApiClient>(client => { client.BaseAddress = new Uri("https://api.example.com/"); client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/json")); // Optional: default timeout client.Timeout = TimeSpan.FromSeconds(10); }); builder.Services.AddControllers(); var app = builder.Build(); app.MapControllers(); app.Run();using System.Net.Http.Headers; var builder = WebApplication.CreateBuilder(args); // Typed client registration builder.Services.AddHttpClient<WeatherApiClient>(client => { client.BaseAddress = new Uri("https://api.example.com/"); client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/json")); // Optional: default timeout client.Timeout = TimeSpan.FromSeconds(10); }); builder.Services.AddControllers(); var app = builder.Build(); app.MapControllers(); app.Run(); This is the most common setup to consume a third-party API in .NET core while avoiding common HttpClient misuse (like socket exhaustion from creating new clients repeatedly). Create a Typed API Client Your client should: Build requests (URL, headers, auth) Send the request Validate status codes Deserialize JSON into C# models Example models: public sealed class WeatherResponse { public string? City { get; set; } public decimal TemperatureC { get; set; } }public sealed class WeatherResponse { public string? City { get; set; } public decimal TemperatureC { get; set; } } The client: using System.Net.Http.Json; public sealed class WeatherApiClient { private readonly HttpClient _http; public WeatherApiClient(HttpClient http) { _http = http; } public async Task<WeatherResponse> GetWeatherAsync(string city, CancellationToken ct = default) { // Example endpoint: /weather?city=Manila var url = $"weather?city={Uri.EscapeDataString(city)}"; using var response = await _http.GetAsync(url, ct); // Throw if non-success (4xx/5xx) to keep callers clean response.EnsureSuccessStatusCode(); var payload = await response.Content.ReadFromJsonAsync<WeatherResponse>(cancellationToken: ct); if (payload is null) throw new InvalidOperationException("API returned empty response."); return payload; } }using System.Net.Http.Json; public sealed class WeatherApiClient { private readonly HttpClient _http; public WeatherApiClient(HttpClient http) { _http = http; } public async Task<WeatherResponse> GetWeatherAsync(string city, CancellationToken ct = default) { // Example endpoint: /weather?city=Manila var url = $"weather?city={Uri.EscapeDataString(city)}"; using var response = await _http.GetAsync(url, ct); // Throw if non-success (4xx/5xx) to keep callers clean response.EnsureSuccessStatusCode(); var payload = await response.Content.ReadFromJsonAsync<WeatherResponse>(cancellationToken: ct); if (payload is null) throw new InvalidOperationException("API returned empty response."); return payload; } } Call the Client from a Controller or Service Controller example: using Microsoft.AspNetCore.Mvc; [ApiController] [Route("api/weather")] public sealed class WeatherController : ControllerBase { private readonly WeatherApiClient _client; public WeatherController(WeatherApiClient client) { _client = client; } [HttpGet] public async Task<ActionResult<WeatherResponse>> Get([FromQuery] string city, CancellationToken ct) { try { var result = await _client.GetWeatherAsync(city, ct); return Ok(result); } catch (HttpRequestException ex) { // For production apps, log ex return StatusCode(502, "Failed to reach upstream API."); } } }using Microsoft.AspNetCore.Mvc; [ApiController] [Route("api/weather")] public sealed class WeatherController : ControllerBase { private readonly WeatherApiClient _client; public WeatherController(WeatherApiClient client) { _client = client; } [HttpGet] public async Task<ActionResult<WeatherResponse>> Get([FromQuery] string city, CancellationToken ct) { try { var result = await _client.GetWeatherAsync(city, ct); return Ok(result); } catch (HttpRequestException ex) { // For production apps, log ex return StatusCode(502, "Failed to reach upstream API."); } } } This gives you a clean API boundary and a reusable client—exactly what you want when you consume a third-party API in .NET core. Add Authentication (common pattern) Many APIs require an API key or Bearer token. API Key header: builder.Services.AddHttpClient<WeatherApiClient>(client => { client.BaseAddress = new Uri("https://api.example.com/"); client.DefaultRequestHeaders.Add("X-API-KEY", builder.Configuration["ApiKey"]); });builder.Services.AddHttpClient<WeatherApiClient>(client => { client.BaseAddress = new Uri("https://api.example.com/"); client.DefaultRequestHeaders.Add("X-API-KEY", builder.Configuration["ApiKey"]); }); Bearer token: client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); Tip: store secrets in user-secrets, environment variables, or a secret manager—never hardcode them. Practical Error Handling Checklist When calling external APIs, keep these basics in mind: Timeouts: set a reasonable HttpClient.Timeout Cancellation: pass CancellationToken from controllers/services Non-success responses: use EnsureSuccessStatusCode() or handle specific status codes Validation: check for null JSON payloads or missing fields Logging: log upstream failures with enough context (endpoint, status code) With those in place, you’ll have a robust and simple approach to consume a third-party API in .NET core. .NET .NETAPI