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 →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.
Distinguish phishing from financial, cryptocurrency, investment, hiring and raffle scams. Keep the category when routing a finding for review.
Explore phishing records →Identify domains classified as adware distributors or unwanted application distributors. Apply a policy appropriate to this type of risk.
Explore unwanted-app records →Recognize a separate browser-spam category alongside suspicious shops and other suspicious sites.
Explore browser-spam records →These links open current database records. A category describes the finding; it does not prescribe the same blocking action for every customer.
Read the category, reputation score, tags and report reference when available. A reputation score is not a calibrated probability of safety.
Use the returned date to assess the age of the available analysis. A lookup does not promise that every domain has just been reanalysed.
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.
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.
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"}'
| Field | Meaning |
|---|---|
| subject, domain | The normalized domain that was checked. |
| verdict | A 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_available | Boolean. False means there is no usable assessment; it does not mean safe. |
| score, reputation | Aliases for the available reputation score (0–100, higher is better), or null. This is not a probability or confidence percentage. |
| category | Available category identifier, or null. Zero is a valid category (Adult Content), not a missing value. |
| tags | Available category or behavior tags, or null. |
| date | Date 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. |
| fingerprint | Available fingerprint value, or null. |
| whitelisted | Whether the available assessment marks the domain as whitelisted. |
| report | Available report reference, or null. |
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
}
{
"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.
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.
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"}'
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(())
}
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()
Your current allowance is exhausted. Compare the available API subscriptions or contact us about a different volume.
View plans and credit costsCompare monthly or annual billing, review your selected plan, and continue to secure checkout.
Choose a subscription