Lookups

View as markdown

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

LookupIP

Returns intelligence for an IPv4 or IPv6 address.

func (c *Client) LookupIP(ctx context.Context, ip netip.Addr) (*IPInfo, error)
info, err := client.LookupIP(ctx, netip.MustParseAddr("213.149.183.127"))
if err != nil {
	log.Fatal(err)
}
if info.Location != nil {
	fmt.Println(info.Location.City, info.Location.Country)
}
if info.Intelligence != nil {
	for _, provider := range info.Intelligence.Providers {
		fmt.Println(provider.Name, provider.Type, provider.LastSeen.Time())
	}
}
  • Cost: Each lookup costs one credit, and failed lookups are not billed.
  • Input: A zero netip.Addr returns an error without sending a request; use netip.ParseAddr to validate untrusted input first.
  • Errors: Private and reserved addresses return a 422 *APIError.

LookupIPs

Looks up as many as 1000 addresses in one request.

func (c *Client) LookupIPs(ctx context.Context, ips []netip.Addr) ([]IPInfo, error)
addrs := []netip.Addr{netip.MustParseAddr("8.8.8.8"), netip.MustParseAddr("1.1.1.1")}
results, err := client.LookupIPs(ctx, addrs)
if err != nil {
	log.Fatal(err)
}
for _, result := range results {
	if result.Intelligence == nil {
		fmt.Println(result.IP, "no intelligence available")
		continue
	}
	fmt.Println(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 index.
  • Input: An empty slice returns nil without a request. More than 1000 addresses, or a zero netip.Addr, returns an error before anything is sent.
  • Errors: A batch with no address the API can look up returns a 422 *APIError.

LookupDomain

Returns the honeypot traffic Synthient has observed for a domain.

func (c *Client) LookupDomain(ctx context.Context, domain string, params ...LookupDomainParams) (*DomainInfo, error)
  • Name
    LookupDomainParams.Limit
    Type
    int
    Description

    Caps the number of recent events returned, from 1 to 1000. Zero uses the API default of 50.

domain, err := client.LookupDomain(ctx, "example.com", synthient.LookupDomainParams{Limit: 10})
if err != nil {
	log.Fatal(err)
}
fmt.Println(domain.Status, domain.Stats.Events24h)
for _, event := range domain.RecentEvents {
	fmt.Println(event.Timestamp.Time(), event.TargetSubdomain, event.Port)
}
  • Cost: Each lookup costs one credit.
  • Input: Internationalized names must be sent in Punycode. params is optional, and only the first is used. An empty domain, ".", or ".." returns an error without a request.
  • Results: A domain that has never been observed returns DomainStatusInactive and zero counts rather than an error.

Account and health

Account

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

func (c *Client) Account(ctx context.Context) (*Account, error)
account, err := client.Account(ctx)
if err != nil {
	log.Fatal(err)
}
fmt.Println(account.Email, account.Organization.Name, account.Scopes)
fmt.Println(account.LookupQuota.Credits, "credits, resetting in", account.LookupQuota.ResetsIn, "seconds")
  • Cost: It costs no credits.

Health

Returns nil if the API and its dependencies are healthy.

func (c *Client) Health(ctx context.Context) error
err := client.Health(ctx)
if err != nil {
	log.Fatal(err)
}
  • Cost: It costs no credits.
  • Errors: An unhealthy API returns an *APIError with status 503. The API does not check the key, but a malformed key returns a 401 *APIError.