IPGeoTrace.Client
0.0.1
dotnet add package IPGeoTrace.Client --version 0.0.1
NuGet\Install-Package IPGeoTrace.Client -Version 0.0.1
<PackageReference Include="IPGeoTrace.Client" Version="0.0.1" />
<PackageVersion Include="IPGeoTrace.Client" Version="0.0.1" />
<PackageReference Include="IPGeoTrace.Client" />
paket add IPGeoTrace.Client --version 0.0.1
#r "nuget: IPGeoTrace.Client, 0.0.1"
#:package IPGeoTrace.Client@0.0.1
#addin nuget:?package=IPGeoTrace.Client&version=0.0.1
#tool nuget:?package=IPGeoTrace.Client&version=0.0.1
IPGeoTrace .NET Client
Official .NET client for the IPGeoTrace IP geolocation API. Resolve a single IP or a batch of up to 100, with optional caching and automatic retries.
Sign up and grab your API key at app.ipgeotrace.com.
Install
dotnet add package IPGeoTrace.Client
Targets netstandard2.0 and net8.0, so it runs on .NET Framework 4.6.1+, .NET Core, and modern
.NET alike.
Building an ASP.NET Core app and want the caller resolved automatically on every request? Add the IPGeoTrace.Client.AspNetCore package, which layers request-pipeline middleware on top of this client. Everything below still applies; that package only adds the automatic per-request lookup.
Quick start
Construct the client once and reuse it for the lifetime of your app:
using IPGeoTrace.Client;
using var client = new IpGeoTraceClient("your-api-key");
IpGeoTraceResult<GeoResponse> result = await client.ResolveAsync("8.8.8.8");
if (result.IsSuccess)
Console.WriteLine($"{result.Value.City?.Name}, {result.Value.Country?.Name} ({result.Value.Location?.TimeZone})");
else
Console.WriteLine($"failed: {result.Error.Code}");
The IP is always supplied by you. This is a server-side library and never sniffs a caller
address: where the IP comes from, a signup form, a webhook payload, a stored audit log, is
entirely your call. Invalid IPs and oversized batches are caught locally (returning invalid_ip
and bad_request) with no wasted round trip.
Screen new signups for datacenter IPs and country mismatches:
public sealed class SignupScreening(IIpGeoTraceClient geo)
{
public async Task<bool> NeedsReviewAsync(string signupIp, string billingCountry, CancellationToken ct)
{
var result = await geo.ResolveAsync(signupIp, ct);
if (!result.IsSuccess)
return false;
var fromDatacenter = result.Value.Asn?.Type == "hosting";
var countryMismatch = result.Value.Country?.Code is { } code && code != billingCountry;
return fromDatacenter || countryMismatch;
}
}
Price a checkout in the visitor's own currency:
var result = await client.ResolveAsync(visitorIp);
var currency = result.IsSuccess ? result.Value.Country?.Currency ?? "USD" : "USD";
return catalog.PricedIn(currency);
Batch lookups
Resolve up to 100 addresses in a single call, for example to enrich a page of sign-in records:
IpGeoTraceResult<GeoBatchResponse> batch = await client.ResolveBatchAsync(logins.Select(l => l.IpAddress));
if (batch.IsSuccess)
foreach (GeoBatchItem item in batch.Value.Results)
report.Add(item.Ip, item.Found ? item.Country?.Name : item.Error);
Results come back in request order, one item per address. A single bad address fails as its own
item (Found = false, Error = "...") without failing the batch. With caching on, cached IPs are
served locally and only the misses are sent in one request; if every IP is a hit, no request is
made at all and batch.FromCache is true.
Results, not exceptions
The client never throws for an API or network failure. Every call returns
IpGeoTraceResult<T>; check IsSuccess and the compiler knows Value (and on failure, Error)
is non-null, so no ! is needed.
The one deliberate exception: canceling the CancellationToken you pass in surfaces as a standard
OperationCanceledException, so the client composes with Task.WhenAny, Polly, and your own
cancellation handling.
Configuration
All settings live on IpGeoTraceClientOptions. Each one is optional.
using var client = new IpGeoTraceClient("your-api-key", new IpGeoTraceClientOptions
{
CacheEnabled = true,
Timeout = TimeSpan.FromSeconds(3)
});
Caching
Off by default. Turn it on and repeat lookups of the same IP are served from memory: no API call, no latency, and nothing counted against your monthly quota.
options.CacheEnabled = true;
Only successful lookups are cached, never errors. Batch calls share the same cache, so only the misses are sent to the API.
Cache lifetime
How long a cached lookup stays valid. The default is 5 minutes.
options.CacheTtl = TimeSpan.FromHours(6);
Your own cache store
Supply any IGeoCache implementation (Redis, IMemoryCache, anything) and caching turns on
automatically. A throwing store never breaks a lookup; the client falls back to calling the API
directly.
options.Cache = new RedisGeoCache(connection);
Timeout
Per-request timeout, applied when the client owns its HttpClient. The default is 10 seconds.
options.Timeout = TimeSpan.FromSeconds(3);
Retries
Rate limits (429) and outages (503) are retried automatically, honoring the API's Retry-After
header and falling back to capped exponential backoff. The default is 2 retries. Set it to 0 to
disable retries, for example when you bring your own resilience handler.
options.MaxRetries = 0;
Dependency injection (ASP.NET / generic host)
DI wiring ships in this package, no extra install. Register in Program.cs:
builder.Services.AddIpGeoTrace(builder.Configuration["IpGeoTrace:ApiKey"]!, options =>
{
options.CacheEnabled = true;
});
Then inject IIpGeoTraceClient (or the concrete IpGeoTraceClient) anywhere. The interface makes
services trivially mockable in tests:
public sealed class GeoService(IIpGeoTraceClient geo)
{
public Task<IpGeoTraceResult<GeoResponse>> Lookup(string ip) => geo.ResolveAsync(ip);
}
The client is registered as a typed IHttpClientFactory client (rotated handlers, no DNS
staleness). The cache is a single shared instance across every resolved client; if you register
your own IGeoCache in the container, it is picked up automatically. AddIpGeoTrace returns the
IHttpClientBuilder, so you can chain resilience and logging handlers.
To wire it manually instead, pass a factory-managed HttpClient. The client never mutates or
disposes it, and builds absolute request URLs itself from options:
services.AddHttpClient("ipgeotrace");
services.AddScoped(sp =>
new IpGeoTraceClient(sp.GetRequiredService<IHttpClientFactory>().CreateClient("ipgeotrace"), "your-api-key"));
Errors
On failure, Error carries the reason:
public sealed record GeoError
{
public string Code { get; } // GeoErrorCodes.*
public string Message { get; }
public int? StatusCode { get; } // HTTP status (null when no response was received)
public int? RetryAfterSeconds { get; } // from the API's Retry-After header
}
Codes (GeoErrorCodes): unauthorized, invalid_ip, bad_request, not_found, rate_limited,
quota_exceeded, license_inactive, forbidden, service_unavailable, network_error,
timeout, invalid_response, unknown.
In a batch call, whole-request failures (for example quota_exceeded) surface as Error; per-IP
failures come back inside each GeoBatchItem { Found = false, Error = "..." }.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Microsoft.Extensions.Http (>= 8.0.1)
- System.Net.Http.Json (>= 8.0.1)
- System.Threading.Tasks.Extensions (>= 4.5.4)
-
net8.0
- Microsoft.Extensions.Http (>= 8.0.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on IPGeoTrace.Client:
| Package | Downloads |
|---|---|
|
IPGeoTrace.Client.AspNetCore
ASP.NET Core request-pipeline integration for the IPGeoTrace client: resolve the caller's IP per request and read it anywhere via HttpContext.GetGeo(). |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.0.1 | 140 | 7/2/2026 |