Email validation that preserves uncertainty.
Check address format, mail service, disposable-domain and spam signals. The response distinguishes an accepted recipient, a definitive rejection and an inconclusive mailbox check. SMTP acceptance alone does not prove delivery or ownership.
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.
How to use?
You need to use the HTTP POST method, sending your data in the form of a JSON object within the body of the request.
Each successful check costs 2 credits, including inconclusive results. API errors do not consume credits.
Request:
| Field | Type | Description |
|---|---|---|
| apikey | String | Your unique API key that authenticates requests to our services. |
| String | The email address you want to validate. |
Example:
You can use various tools or libraries to make this POST request. Here's how you might typically do it using curl, a command-line tool:
curl -X POST 'https://inspector.gridinsoft.com/api/v1/email/check' \
-H 'Content-Type: application/json' \
-d '{
"apikey": "YOUR_PRIVATE_APIKEY",
"email": "[email protected]"
}'
Response:
| Field | Type | Description |
|---|---|---|
| verdict | String | Validation result: "VALID", "INVALID", "NON_EXISTENT", "RISKY", or "UNKNOWN". |
| message | String | Human-readable description of the validation result. |
| checks | Object | Detailed checks; account can be null when the SMTP result is inconclusive. |
| checks.format | Boolean | Whether the email has a valid format. |
| checks.service | Boolean | Whether the domain exists and has MX records. |
| checks.account | Boolean or null | SMTP recipient result: true for accepted, false for rejected, null for inconclusive. Acceptance does not prove the mailbox exists or that delivery will succeed. |
| checks.disposable | Boolean | Whether the email domain is a known disposable/temporary email provider. |
| checks.spam | Boolean | Whether the domain is listed in spam blacklists (DNSBL). |
| mx_records | Array | List of MX servers found for the email domain. |
| account_status | String | accepted, rejected or unknown when an SMTP check is performed. Can be absent for early validation failures. |
| details | Array | SMTP conversation details for debugging purposes. |
Example: inconclusive mailbox check
Illustrative response excerpt. A server timeout or policy restriction must not be interpreted as a nonexistent mailbox.
{
"verdict": "UNKNOWN",
"account_status": "unknown",
"checks": {
"format": true,
"service": true,
"account": null,
"disposable": false,
"spam": false
}
}
Catch-all servers may accept recipients that do not have individual mailboxes. Use address confirmation when proof of ownership or deliverability is required.
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/email/check"
data = {
"apikey": "YOUR_PRIVATE_APIKEY",
"email": "[email protected]"
}
response = requests.post(url, json=data)
print(response.json())
$body = @{
apikey = "YOUR_PRIVATE_APIKEY"
email = "[email protected]"
} | ConvertTo-Json
$response = Invoke-RestMethod -Uri "https://inspector.gridinsoft.com/api/v1/email/check" `
-Method POST `
-ContentType "application/json" `
-Body $body
$response | ConvertTo-Json -Depth 10
const url = "https://inspector.gridinsoft.com/api/v1/email/check";
const data = {
apikey: "YOUR_PRIVATE_APIKEY",
email: "[email protected]"
};
fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data)
})
.then(response => response.json())
.then(result => console.log(result))
.catch(error => console.error("Error:", error));
import java.net.HttpURLConnection
import java.net.URL
import com.google.gson.Gson
fun main() {
val url = URL("https://inspector.gridinsoft.com/api/v1/email/check")
val data = mapOf(
"apikey" to "YOUR_PRIVATE_APIKEY",
"email" to "[email protected]"
)
val connection = url.openConnection() as HttpURLConnection
connection.requestMethod = "POST"
connection.setRequestProperty("Content-Type", "application/json")
connection.doOutput = true
connection.outputStream.bufferedWriter().use {
it.write(Gson().toJson(data))
}
val response = connection.inputStream.bufferedReader().readText()
println(response)
}
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
func main() {
url := "https://inspector.gridinsoft.com/api/v1/email/check"
data := map[string]string{
"apikey": "YOUR_PRIVATE_APIKEY",
"email": "[email protected]",
}
jsonData, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonData))
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
#!/bin/bash
curl -X POST 'https://inspector.gridinsoft.com/api/v1/email/check' \
-H 'Content-Type: application/json' \
-d '{
"apikey": "YOUR_PRIVATE_APIKEY",
"email": "[email protected]"
}'
require 'net/http'
require 'json'
require 'uri'
uri = URI("https://inspector.gridinsoft.com/api/v1/email/check")
data = {
apikey: "YOUR_PRIVATE_APIKEY",
email: "[email protected]"
}
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == 'https'
request = Net::HTTP::Post.new(uri.path, { 'Content-Type' => 'application/json' })
request.body = data.to_json
response = http.request(request)
puts JSON.parse(response.body)
<?php
$url = "https://inspector.gridinsoft.com/api/v1/email/check";
$data = [
'apikey' => 'YOUR_PRIVATE_APIKEY',
'email' => '[email protected]'
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response, true));
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
var url = "https://inspector.gridinsoft.com/api/v1/email/check";
var data = new
{
apikey = "YOUR_PRIVATE_APIKEY",
email = "[email protected]"
};
using var client = new HttpClient();
var json = JsonSerializer.Serialize(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync(url, content);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
}
}
#include <iostream>
#include <curl/curl.h>
#include <string>
size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* output) {
output->append((char*)contents, size * nmemb);
return size * nmemb;
}
int main() {
CURL* curl = curl_easy_init();
std::string response;
if (curl) {
std::string url = "https://inspector.gridinsoft.com/api/v1/email/check";
std::string json = R"({"apikey": "YOUR_PRIVATE_APIKEY", "email": "[email protected]"})";
struct curl_slist* headers = NULL;
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
curl_easy_perform(curl);
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
std::cout << response << std::endl;
}
return 0;
}
import java.net.http.*;
import java.net.URI;
public class EmailCheck {
public static void main(String[] args) throws Exception {
String url = "https://inspector.gridinsoft.com/api/v1/email/check";
String json = """
{
"apikey": "YOUR_PRIVATE_APIKEY",
"email": "[email protected]"
}
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
use reqwest::blocking::Client;
use serde_json::json;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let url = "https://inspector.gridinsoft.com/api/v1/email/check";
let data = json!({
"apikey": "YOUR_PRIVATE_APIKEY",
"email": "[email protected]"
});
let client = Client::new();
let response = client.post(url)
.header("Content-Type", "application/json")
.json(&data)
.send()?;
println!("{}", response.text()?);
Ok(())
}
import Foundation
let url = URL(string: "https://inspector.gridinsoft.com/api/v1/email/check")!
let data: [String: Any] = [
"apikey": "YOUR_PRIVATE_APIKEY",
"email": "[email protected]"
]
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try? JSONSerialization.data(withJSONObject: data)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else { return }
if let json = try? JSONSerialization.jsonObject(with: data) {
print(json)
}
}
task.resume()
RunLoop.main.run()