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.

POST https://inspector.gridinsoft.com/api/v1/email/check

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.
email 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_statusStringaccepted, 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()
Ready to get started?
Sign up to try Inspector API