# Lookups Look up IP addresses and domains, and check your account and the API's health. ## LookupIP Returns intelligence for an IPv4 or IPv6 address. ```go func (c *Client) LookupIP(ctx context.Context, ip netip.Addr) (*IPInfo, error) ``` ```go 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. ```go func (c *Client) LookupIPs(ctx context.Context, ips []netip.Addr) ([]IPInfo, error) ``` ```go 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. ```go func (c *Client) LookupDomain(ctx context.Context, domain string, params ...LookupDomainParams) (*DomainInfo, error) ``` - `LookupDomainParams.Limit` `int` — Caps the number of recent events returned, from 1 to 1000. Zero uses the API default of 50. ```go 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. ```go func (c *Client) Account(ctx context.Context) (*Account, error) ``` ```go 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. ```go func (c *Client) Health(ctx context.Context) error ``` ```go 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`.