Lookups

View as markdown

Look up IP addresses and domains, and check your account and the API's health.

LookupIPAsync

Returns intelligence for an IPv4 or IPv6 address.

public Task<IPInfo> LookupIPAsync(IPAddress ip, CancellationToken cancellationToken = default)
var info = await client.LookupIPAsync(IPAddress.Parse("213.149.183.127"));
if (info.Location is not null)
{
    Console.WriteLine($"{info.Location.City} {info.Location.Country}");
}
if (info.Intelligence is not null)
{
    foreach (var provider in info.Intelligence.Providers)
    {
        Console.WriteLine($"{provider.Name} {provider.Type} {provider.LastSeen:u}");
    }
}
  • Cost: Each lookup costs one credit, and failed lookups are not billed.
  • Input: An IPv6 address with a scope ID, such as fe80::1%3, throws an ArgumentException without sending a request. Use IPAddress.TryParse to validate untrusted input first.
  • Errors: Private and reserved addresses fail with a 422 ApiException.

LookupIPsAsync

Looks up as many as 1000 addresses in one request.

public Task<IReadOnlyList<IPInfo>> LookupIPsAsync(IEnumerable<IPAddress> ips, CancellationToken cancellationToken = default)
IPAddress[] addresses = [IPAddress.Parse("8.8.8.8"), IPAddress.Parse("1.1.1.1")];
var results = await client.LookupIPsAsync(addresses);
foreach (var result in results)
{
    if (result.Intelligence is null)
    {
        Console.WriteLine($"{result.IP} no intelligence available");
        continue;
    }
    Console.WriteLine($"{result.IP} {result.Intelligence.RiskScore}");
}
  • Cost: The API bills ceil(n * 0.9) credits for the n distinct addresses it looks up, and bills nothing if the account cannot cover the whole batch.
  • Results: Private and reserved addresses are skipped and duplicates collapse into one result, so there can be fewer results than addresses. Match results by IP, which the API canonicalizes, rather than by position.
  • Input: An empty batch returns an empty list without a request. More than 1000 addresses, a null address, or an IPv6 address with a scope ID throws an ArgumentException before anything is sent.
  • Errors: A batch with no address the API can look up fails with a 422 ApiException.

LookupDomainAsync

Returns the honeypot traffic Synthient has observed for a domain.

public Task<DomainInfo> LookupDomainAsync(string domain, int? limit = null, CancellationToken cancellationToken = default)
var domain = await client.LookupDomainAsync("example.com", limit: 10);
Console.WriteLine($"{domain.Status} {domain.Stats.Events24h}");
foreach (var recent in domain.RecentEvents)
{
    Console.WriteLine($"{recent.Timestamp:u} {recent.TargetSubdomain} {recent.Port}");
}
  • Cost: Each lookup costs one credit.
  • Input: Internationalized names must be sent in Punycode. limit caps the number of recent events returned, from 1 to 1000, and null uses the API default of 50. An empty domain, ".", or ".." throws an ArgumentException, and a limit below 1 throws an ArgumentOutOfRangeException, without a request.
  • Results: A domain that has never been observed returns DomainStatus.Inactive and zero counts rather than an error.

Account and health

GetAccountAsync

Returns the account that owns the API key, including its scopes and remaining lookup credits.

public Task<Account> GetAccountAsync(CancellationToken cancellationToken = default)
var account = await client.GetAccountAsync();
Console.WriteLine($"{account.Email} {account.Organization.Name} {string.Join(", ", account.Scopes)}");
Console.WriteLine($"{account.LookupQuota.Credits} credits, resetting in {account.LookupQuota.ResetsIn}");
  • Cost: It costs no credits.

CheckHealthAsync

Completes if the API and its dependencies are healthy, and throws a 503 ApiException if not.

public Task CheckHealthAsync(CancellationToken cancellationToken = default)
try
{
    await client.CheckHealthAsync();
}
catch (ApiException e)
{
    Console.WriteLine($"unhealthy: {e.StatusCode}");
}
  • Cost: It costs no credits.
  • Errors: The API does not check the key, but a malformed key fails with a 401 ApiException.