Understand the risk behind a domain.

Gridinsoft Domain Intelligence turns a domain name into a classified assessment: phishing, scam, unwanted software, browser spam and more. Get the verdict and available context in one JSON response.

A category you can act on

Phishing and scams

Distinguish phishing from financial, cryptocurrency, investment, hiring and raffle scams. Keep the category when routing a finding for review.

Explore phishing records →

Unwanted software

Identify domains classified as adware distributors or unwanted application distributors. Apply a policy appropriate to this type of risk.

Explore unwanted-app records →

These links open current database records. A category describes the finding; it does not prescribe the same blocking action for every customer.

Know what the result means

Verdict and context

Read the category, reputation score, tags and report reference when available. A reputation score is not a calibrated probability of safety.

Analysis date

Use the returned date to assess the age of the available analysis. A lookup does not promise that every domain has just been reanalysed.

Unknown is explicit

When no usable assessment is available, the response has verdict: Unknown and data_available: false. Do not turn that into an allow decision by treating it as Safe.

Domain, URL or feed?

Use this API for a domain or subdomain assessment. Choose URL Analysis for a specific page, its redirects and available page evidence. Choose Data Feeds for recurring matching against a domain dataset.

API subscriptions use our standard terms. Paying for a plan does not make submissions private or remove our rights to use and publish analysis. Private processing, customer-facing services, redistribution, and other special rights require written agreement. Discuss your requirements.

Request and response examples

Domain Intelligence API

POST a JSON object containing your API key and a domain or subdomain. Use a domain name without a URL path. A leading www. is removed before the lookup: www.example.com checks example.com. Other subdomains are checked individually. The subject and domain fields contain the normalized name.

3 credits per successful check, including Unknown results. API errors do not consume credits.

curl -X POST 'https://inspector.gridinsoft.com/api/v1/domain/check' \
  -H 'Content-Type: application/json' \
  -d '{"apikey":"YOUR_PRIVATE_APIKEY","domain":"example.com"}'

Response fields

FieldMeaning
subject, domainThe normalized domain that was checked.
verdictA category such as Safe, Phishing, Adware Distributor or Unknown. Safe means an available assessment found no classified threat; it is not a guarantee of safety. Do not assume there are only three possible verdict strings.
data_availableBoolean. False means there is no usable assessment; it does not mean safe.
score, reputationAliases for the available reputation score (0–100, higher is better), or null. This is not a probability or confidence percentage.
categoryAvailable category identifier, or null. Zero is a valid category (Adult Content), not a missing value.
tagsAvailable category or behavior tags, or null.
dateDate of the available assessment, when known; otherwise null. A null date does not invalidate an available verdict or category. Use data_available to distinguish an assessment from no data. The date is not the time of this request.
fingerprintAvailable fingerprint value, or null.
whitelistedWhether the available assessment marks the domain as whitelisted.
reportAvailable report reference, or null.

Example: a classified domain

Illustrative response using a reserved example domain. This is a format example, not a finding about a real website.

{
  "subject": "download.example",
  "domain": "download.example",
  "verdict": "Unwanted Application Distributor",
  "data_available": true,
  "score": 15,
  "reputation": 15,
  "category": 8,
  "tags": null,
  "date": "2026-09-27 12:00:00",
  "fingerprint": null,
  "whitelisted": false,
  "report": null
}

Example: no analysis record

{
  "subject": "unknown.example",
  "domain": "unknown.example",
  "verdict": "Unknown",
  "data_available": false,
  "score": null,
  "reputation": null,
  "category": null,
  "tags": null,
  "date": null,
  "fingerprint": null,
  "whitelisted": false,
  "report": null
}

Handle Unknown separately from Safe. Optional context may be null even when a verdict is available. A missing verdict does not guarantee that a new analysis will be completed during the lookup.

Errors and timing

Handle HTTP 400 (invalid input), 401 (authentication), 405 (method), 429 (insufficient credits), and 5xx errors. Response times vary; use timeouts and bounded retries for transient errors. Check your credit balance before retrying a 429 response.

For programming languages

Using one of these samples is the easiest way to start using our API. Feel free to add additional functionalities as needed.


import requests

url = "https://inspector.gridinsoft.com/api/v1/domain/check"
data = {
    "apikey": "YOUR_PRIVATE_APIKEY",
    "domain": "example.com"
}

response = requests.post(url, json=data)
print(response.json())

$body = @{ apikey = "YOUR_PRIVATE_APIKEY"; domain = "example.com" } | ConvertTo-Json
$response = Invoke-RestMethod -Method Post -Uri "https://inspector.gridinsoft.com/api/v1/domain/check" -Body $body -ContentType "application/json"
$response | ConvertTo-Json

const response = await fetch("https://inspector.gridinsoft.com/api/v1/domain/check", {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify({
        apikey: "YOUR_PRIVATE_APIKEY",
        domain: "example.com"
    })
});
console.log(await response.json());

import java.net.URI
import java.net.http.*

val client = HttpClient.newHttpClient()
val data = """{"apikey":"YOUR_PRIVATE_APIKEY", "domain":"example.com"}"""
val request = HttpRequest.newBuilder()
    .uri(URI.create("https://inspector.gridinsoft.com/api/v1/domain/check"))
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(data))
    .build()
println(client.send(request, HttpResponse.BodyHandlers.ofString()).body())

package main

import (
    "bytes"
    "fmt"
    "net/http"
    "io/ioutil"
)

func main() {
    url := "https://inspector.gridinsoft.com/api/v1/domain/check"
    jsonData := []byte(`{"apikey": "YOUR_PRIVATE_APIKEY", "domain": "example.com"}`)
    
    resp, _ := http.Post(url, "application/json", bytes.NewBuffer(jsonData))
    defer resp.Body.Close()
    
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}

curl -X POST "https://inspector.gridinsoft.com/api/v1/domain/check" \
     -H "Content-Type: application/json" \
     -d '{"apikey": "YOUR_PRIVATE_APIKEY", "domain": "example.com"}'
  • JSON Parsing: The script uses `jq` to parse the JSON response. Make sure `jq` is installed on your system to use this feature.
  • HTTP Status Codes: It captures the HTTP status code to determine whether the request was successful (`200 OK`) or if there was an error. This helps in determining the appropriate action based on the response code.
  • Output Handling: The script now properly separates the response handling and error messages, improving the readability and user experience when interacting with the script.
  • Reading Domains: Domains are read from a text file, making it easy to check multiple domains in one go.

require 'net/http'
require 'uri'
require 'json'

uri = URI.parse("https://inspector.gridinsoft.com/api/v1/domain/check")
response = Net::HTTP.post(uri, 
    {apikey: "YOUR_PRIVATE_APIKEY", domain: "example.com"}.to_json,
    "Content-Type" => "application/json"
)
puts response.body

$ch = curl_init('https://inspector.gridinsoft.com/api/v1/domain/check');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    'apikey' => 'YOUR_PRIVATE_APIKEY',
    'domain' => 'example.com'
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type:application/json']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
echo curl_exec($ch);
curl_close($ch);

using var client = new HttpClient();
var data = new { apikey = "YOUR_PRIVATE_APIKEY", domain = "example.com" };
var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json");
var response = await client.PostAsync("https://inspector.gridinsoft.com/api/v1/domain/check", content);
Console.WriteLine(await response.Content.ReadAsStringAsync());

// Using cpprestsdk
void check_domain() {
    http_client client(U("https://inspector.gridinsoft.com/api/v1/domain/check"));
    json::value data;
    data[U("apikey")] = json::value::string(U("YOUR_PRIVATE_APIKEY"));
    data[U("domain")] = json::value::string(U("example.com"));

    client.request(methods::POST, U(""), data.serialize(), U("application/json"))
        .then([](http_response response) {
            std::wcout << response.extract_json().get().serialize() << std::endl;
        }).wait();
}

HttpClient client = HttpClient.newHttpClient();
String data = "{\"apikey\":\"YOUR_PRIVATE_APIKEY\", \"domain\":\"example.com\"}";
HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://inspector.gridinsoft.com/api/v1/domain/check"))
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString(data))
        .build();
System.out.println(client.send(request, HttpResponse.BodyHandlers.ofString()).body());

// Use reqwest = { version = "0.11", features = ["blocking", "json"] }
fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = reqwest::blocking::Client::new();
    let res = client.post("https://inspector.gridinsoft.com/api/v1/domain/check")
        .json(&serde_json::json!({
            "apikey": "YOUR_PRIVATE_APIKEY",
            "domain": "example.com"
        }))
        .send()?;
    println!("{}", res.text()?);
    Ok(())
}
  • Dependencies: Uses `reqwest` for HTTP requests, `tokio` for async runtime, and `serde` for JSON handling.
  • Structs: `DomainCheckRequest` for the request body and `DomainCheckResponse` for parsing the JSON response.
  • Async Functionality: The `check_domain` function is asynchronous, using Tokio's async runtime to handle the HTTP requests concurrently.
  • Error Handling: Proper error handling is implemented, ensuring that any issues during the HTTP request or file operations are reported.
  • Reading Domains: Domains are read from a text file, making it easy to check multiple domains in one go.

var request = URLRequest(url: URL(string: "https://inspector.gridinsoft.com/api/v1/domain/check")!)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try? JSONSerialization.data(withJSONObject: ["apikey": "YOUR_PRIVATE_APIKEY", "domain": "example.com"])

URLSession.shared.dataTask(with: request) { data, _, _ in
    if let data = data, let result = String(data: data, encoding: .utf8) {
        print(result)
    }
}.resume()
Ready to get started?
Sign up to try Inspector API