Skip to content
ipdataPublic

About

Official C# client library for the ipdata API

Topics

Resources

Contributing

Stars

13 stars

Watchers

2 watching

Forks

Latest commit

 

History

167 Commits

Folders and files

Repository files navigation

ipdata

License: MIT IPData

v3 Breaking Changes — All public types have been renamed to follow .NET naming conventions for two-letter acronyms. See the Migration Guide for details.

ipdata.co is a fast, reliable and clean service that allows you to look up the location of an IP Address and other data.

Table of Content

Install

NuGet package install using package manager:

Install-Package IPData

NuGet package install using .NET CLI:

dotnet add package IPData

Lookup

All usage examples you can find on samples folder.

Basic

var client = new IPDataClient("API_KEY");

// Get IP data from my IP
var myIp = await client.Lookup();
Console.WriteLine($"Country name for {myIp.Ip} is {myIp.CountryName}");

// Get IP data from IP
var ipInfo = await client.Lookup("8.8.8.8");
Console.WriteLine($"Country name for {ipInfo.Ip} is {ipInfo.CountryName}");

// Get single field from IP
var countryName = await client.Lookup("8.8.8.8", x => x.CountryName);
Console.WriteLine($"Country name for 8.8.8.8 is {countryName}");

// Get multiple fields from IP
var geolocation = await client.Lookup("8.8.8.8", x => x.Latitude, x => x.Longitude);
Console.WriteLine($"Geolocation for 8.8.8.8 is lat: {geolocation.Latitude} long: {geolocation.Longitude}");

Bulk

From ipdata.co docs:

Note that bulk lookups are only available to paid users and are currently limited to a 100 at a time. Reach out to support if you need to lookup larger batches.

var client = new IPDataClient("API_KEY");

var ipInfoList = await client.Lookup(new string[] { "1.1.1.1", "2.2.2.2", "3.3.3.3" });
foreach (var ipInfo in ipInfoList)
{
    Console.WriteLine($"Country name for {ipInfo.Ip} is {ipInfo.CountryName}");
}

Carrier

var client = new IPDataClient("API_KEY");

var carrierInfo = await client.Carrier("69.78.70.144");
Console.WriteLine($"Carrier name: {carrierInfo.Name}");

Company

var client = new IPDataClient("API_KEY");

var companyInfo = await client.Company("69.78.70.144");
Console.WriteLine($"Company name: {companyInfo.Name}");

ASN

var client = new IPDataClient("API_KEY");

var asnInfo = await client.Asn("69.78.70.144");
Console.WriteLine($"ASN name: {asnInfo.Name}");

Timezone

var client = new IPDataClient("API_KEY");

var timezoneInfo = await client.TimeZone("69.78.70.144");
Console.WriteLine($"TimeZone name: {timezoneInfo.Name}");

Currency

var client = new IPDataClient("API_KEY");

var currencyInfo = await client.Currency("69.78.70.144");
Console.WriteLine($"Currency name: {currencyInfo.Name}");

Threat

var client = new IPDataClient("API_KEY");

var threatInfo = await client.Threat("69.78.70.144");
Console.WriteLine($"Threat is Tor: {threatInfo.IsTor}");
Console.WriteLine($"Threat is VPN: {threatInfo.IsVpn}, trust score: {threatInfo.Scores?.TrustScore}");

Response fields

IPLookupResult maps the JSON response one property per field (is_eu is IsEu, country_name is CountryName, and so on); nested objects such as asn, threat and currency have model classes of their own, and keys the library does not know are ignored. The most recent additions:

JSON field Property Description
is_satellite IPLookupResult.IsSatellite true for satellite ISPs. The API sends the key only when it is true; the property reads false otherwise.
is_anycast IPLookupResult.IsAnycast true for anycast addresses. The API sends the key only when it is true; the property reads false otherwise.
threat.blocklists[].first_seen BlocklistInfo.FirstSeen First day the address was seen on that blocklist, a YYYY-MM-DD (UTC) string; null when the feed does not report it.
threat.blocklists[].last_seen BlocklistInfo.LastSeen Last day the address was seen on that blocklist, a YYYY-MM-DD (UTC) string; null when the feed does not report it.
threat.blocklists[].days_seen BlocklistInfo.DaysSeen Number of days the address was seen on that blocklist (int?); null when the feed does not report it.
threat.is_vpn Threat.IsVpn true when the address is a VPN endpoint (bool?); null when the response does not include the key.
threat.scores Threat.Scores A ThreatScores object with VpnScore, ProxyScore, ThreatScore and TrustScore (int?, from vpn_score, proxy_score, threat_score and trust_score). Scores is null when the response does not include the object, and a score is null when the object does not include it.

Both flags can be requested on their own or as part of a field selection:

var isAnycast = await client.Lookup("8.8.8.8", x => x.IsAnycast);
var flags = await client.Lookup("8.8.8.8", x => x.IsSatellite, x => x.IsAnycast);

Connection reuse and HTTP/2

An IPDataClient keeps a persistent HTTPS connection pool for as long as it lives. Create one client per process (or one per API key or endpoint), keep it, and reuse it for every lookup: a reused connection skips the TCP and TLS handshake that every new connection pays. Requests to api.ipdata.co are multiplexed over HTTP/2 when the platform negotiates it, and fall back to HTTP/1.1 keep-alive otherwise.

  • Thread safety. IPDataClient holds no per-request state; one instance can serve any number of concurrent lookups from any thread.
  • Shared default pool. Clients constructed without an HttpClient (new IPDataClient("API_KEY"), with or without a base URL) share one process-wide HttpClient. It lives for the lifetime of the process and is never disposed, so there is nothing to close. On .NET 8+ it keeps idle connections for 60 seconds, recycles every connection after 5 minutes and sends HTTP/2 keep-alive pings every 30 seconds.
  • HTTP/2 on .NET 8+. The net8.0 build asks for HTTP/2 on every request (HttpVersionPolicy.RequestVersionOrLower) and falls back to HTTP/1.1 automatically when the server or a proxy does not negotiate it. The netstandard2.0 build, used by .NET Framework and other .NET Standard consumers, never asks for HTTP/2 and relies on HTTP/1.1 keep-alive.
  • Bring your own HttpClient. Pass an HttpClient to send every request through it, for example one managed by IHttpClientFactory (see Dependency Injection). It can be combined with a custom base URL through the IPDataClient(string apiKey, HttpClient httpClient, Uri baseUrl) constructor. You own that client's lifetime; the library never disposes it. The same applies to a custom IHttpClient implementation.
  • Request headers. Every request carries User-Agent: ipdata-dotnet/<version> (the package version) and Accept: application/json.
// One client for the whole application; reuse it for every lookup.
var client = new IPDataClient("API_KEY");

// Your own HttpClient, here combined with the EU endpoint; you dispose it at shutdown.
var httpClient = new HttpClient();
var euClient = new IPDataClient("API_KEY", httpClient, new Uri("https://eu-api.ipdata.co"));

EU Endpoint

To ensure your data stays in the EU, use the EU endpoint by passing a custom base URL:

var client = new IPDataClient("API_KEY", new Uri("https://eu-api.ipdata.co"));

var ipInfo = await client.Lookup("8.8.8.8");

Dependency Injection

If you're using ASP.NET Core, you can register IPDataClient with IHttpClientFactory to benefit from managed connection pooling and handler lifetimes:

// In Program.cs or Startup.cs
services.AddHttpClient("ipdata");
services.AddSingleton<IIPDataClient>(sp =>
{
    var factory = sp.GetRequiredService<IHttpClientFactory>();
    var httpClient = factory.CreateClient("ipdata");
    return new IPDataClient("API_KEY", httpClient);
});

Then inject IIPDataClient wherever you need it:

public class MyService
{
    private readonly IIPDataClient _ipDataClient;

    public MyService(IIPDataClient ipDataClient)
    {
        _ipDataClient = ipDataClient;
    }

    public async Task<string> GetCountry(string ip)
    {
        var result = await _ipDataClient.Lookup(ip);
        return result.CountryName;
    }
}

Migrating from v2 to v3

v3 renames all public types to follow .NET naming conventions for two-letter acronyms. It also adds EU endpoint support and a Company lookup.

Renamed types

v2 v3
IpDataClient IPDataClient
IIpDataClient IIPDataClient
IpInfo IPLookupResult

Namespace change

- using IpData;
- using IpData.Models;
+ using IPData;
+ using IPData.Models;

NuGet package

The package ID has changed from IpData to IPData:

dotnet remove package IpData
dotnet add package IPData

New features in v3

  • EU endpoint — Pass a custom base URL to route requests through EU servers:
    var client = new IPDataClient("API_KEY", new Uri("https://eu-api.ipdata.co"));
  • Company lookup — Fetch company info for an IP:
    var companyInfo = await client.Company("8.8.8.8");

Contributing

Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests to us.

Versioning

We use SemVer for versioning. For the versions available, see the tags on this repository.

Releasing

Releases are cut by CI from the version in src/IPData/IPData.csproj. To ship a new version, bump VersionPrefix in a pull request and merge it: the CI run on master tags the merge commit vX.Y.Z, creates the GitHub release with generated notes and publishes the package to NuGet. A merge whose version is already tagged publishes nothing.

License

This project is licensed under the MIT License - see the LICENSE.md file for details

About

Official C# client library for the ipdata API

Topics

Resources

Contributing

Stars

13 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages