GET /v1/lookup

Resolve an IP to its provider.

One endpoint. Give it an IPv4 or IPv6 address; get back every operator whose published ranges contain it, with the matching CIDR and a trust level, or an empty array when nothing matches.

Quickstart
curl -s 'https://sourceip.io/v1/lookup?ip=8.8.8.8' \
  -H 'x-api-key: YOUR_KEY'

No key yet? Request a free one, or try it without any setup from the search box on the home page.

Authentication

Pass your key in the x-api-key header on every request. Keys are issued per organisation. Do not embed a key in client-side code or a public repository: anything shipped to a browser is public.

x-api-key: YOUR_KEY
Lookup endpoint
ParameterTypeRequiredDescription
ipstringyesIPv4 or IPv6 address in standard notation. CIDR ranges are not accepted.
Response schema
{
  "ip": "8.8.8.8",
  "last_updated": "2026-08-05T04:12:07Z",
  "providers": [
    {
      "id": "0ec4da84-96c0-3756-b79c-4d0034b75228",
      "name": "Google Public DNS",
      "description": "Google's global domain name system (DNS) resolution service.",
      "category": "public_dns",
      "explanation": "Public DNS services are used as alternatives to ISP's name servers...",
      "logo": "https://upload.wikimedia.org/wikipedia/commons/2/2f/Google_2015_logo.svg",
      "precedence": 0,
      "trust_level": 1,
      "ip_cidr": "8.8.8.8/32"
    }
  ]
}
FieldTypeDescription
ipstringThe address you queried, echoed back.
last_updatedstringISO8601 build time of the snapshot that answered this query.
providersarrayEvery provider whose published ranges contain this address. Empty when there is no match.
providers[].idstringStable UUID for the provider.
providers[].namestringProvider name.
providers[].descriptionstringWhat the organisation is and what these ranges are for.
providers[].categorystringService category, e.g. cloud, cdn, public_dns, security.
providers[].explanationstringWhy you would see this traffic on your network.
providers[].logostringLogo URL. May be empty.
providers[].precedencenumberOrdering hint for overlapping matches; higher sorts first.
providers[].trust_levelnumberHow much weight the attribution carries. See trust levels.
providers[].ip_cidrstringThe specific CIDR that matched.

Multiple providers can match one address: a service running on a cloud provider matches both. Results are sorted by precedence, most specific first.

Errors
StatusMeaning
400Missing or unparseable ip query parameter.
403Missing or invalid API key.
429Rate limit exceeded. Check the Retry-After header.
500Server error. Retry with backoff.

Errors return JSON with an error field. A successful lookup with no match is 200 with an empty providers array, not a 404: an address we have no source for is an answer, not a failure.

Rate limits
TierLimitCounted by
Anonymous (website)100/dayclient address
Free key1,000/dayAPI key
PaidnegotiatedAPI key

Quotas reset at midnight UTC. A 429 carries Retry-After in seconds; anonymous responses also carryX-RateLimit-Remaining. Cache results. The dataset changes daily, so re-querying the same address within a day gains you nothing.

Trust levels
LevelLabelMeaning
1TRUSTEDThe provider directly operates the service (e.g., API endpoints, DNS, software delivery, or control-plane infrastructure published by the operator itself).
2SHARED INFRASTRUCTUREOwnership is known, but the provider supplies infrastructure to customers or third parties, so activity is not attributable to the provider itself.
0INFORMATIONALDescriptive context only — the match provides information without serving as a basis for trust or distrust decisions.
-1UNTRUSTEDImportant to label, but a match must not imply benign behaviour, accountability, or allow-list suitability.

trust_level describes what an attribution means;precedence only orders overlapping matches. They are not the same thing. Level 1 can support allow-list style decisions where your policy allows it; level 2 cannot, because the provider is supplying infrastructure to third parties.

Examples

curl

curl -s 'https://sourceip.io/v1/lookup?ip=1.1.1.1' \
  -H 'x-api-key: YOUR_KEY' | jq '.providers[].name'

Python

import os, requests

resp = requests.get(
    "https://sourceip.io/v1/lookup",
    params={"ip": "1.1.1.1"},
    headers={"x-api-key": os.environ["SOURCEIP_KEY"]},
    timeout=5,
)
resp.raise_for_status()

for provider in resp.json()["providers"]:
    print(provider["name"], provider["ip_cidr"], provider["trust_level"])

Go

req, _ := http.NewRequest("GET", "https://sourceip.io/v1/lookup?ip=1.1.1.1", nil)
req.Header.Set("x-api-key", os.Getenv("SOURCEIP_KEY"))

resp, err := http.DefaultClient.Do(req)
if err != nil {
    log.Fatal(err)
}
defer resp.Body.Close()

var out struct {
    IP        string `json:"ip"`
    Providers []struct {
        Name       string `json:"name"`
        IPCIDR     string `json:"ip_cidr"`
        TrustLevel int    `json:"trust_level"`
    } `json:"providers"`
}
json.NewDecoder(resp.Body).Decode(&out)

A machine-readable spec is at /openapi.json.