How to Customize the Real-time API

How to create a customized API to validate emails in forms, apps or webservices

You can customize and install the SafetyMails email verification API with complete flexibility, using the programming language of your choice. With just a few lines of code and your access keys, you can integrate real-time verification directly into landing pages, forms, applications or point-of-sale (POS) systems.


The API responds instantly to queries, delivering the data you need to block invalid emails, reduce fraud and protect your registrations from the very first contact.

📌Our team is available to help you configure the code. Just click on the link in the support schedule to talk to our experts.

1. Log in to your account and activate credits

You must have an active credit subscription to use the email verification API. See the available email verification packages here.

2. Access the API in real time

  • In the platform's top menu, click on "Real-time API"
  • Click on "Add a new source"
  • Then select "For developers"

3. Register the source of the check

Give the source a name and enter the domain of your form (e.g. yourcompany.com).


This ensures that the API will only accept requests from authorized URLs.
After registering the origin, the system will automatically generate the following data:


  • API Key
  • Source Ticket


These keys will be used in your API integration code.
Example of source ticket and API key
APIKey
55a89975b74************75217b0a2eae840bd
Ticket Origem
b440e8d30f068************3d08b84afe2fe50

4. Authentication via HMAC

To guarantee the security of requests, API calls need to be authenticated using HMAC (Hash-based Message Authentication Code). This mechanism ensures that the data has not been tampered with during traffic, as long as both the sender and receiver share a secret key.


The hash function used must follow the HMAC-SHA256 standard, combining two elements:


  • VALUE: the email to be verified
  • KEY: your API Key provided by the platform

The hash generation formula is:

hash = HMAC_SHA256(VALUE, KEY);


This hash must be sent in the request header:


Sf-Hmac: (Hash content)

Example
Sf-Hmac: afc5382171c3745890b56********************4aa43506326b4e1fc993cb

5. Syntax for querying the email verification API

To make calls to the SafetyMails real-time verification API, you need to set up the URL correctly and send the email via the POST method. Here's how it works:


Generate the ticket code with the SHA1 algorithm:


CODE_TICKET = SHA1(<TICKET_ORIGEM>)

Set up the request URL in this format:


https://<TICKET_ORIGEM>.safetymails.com/api/<CODE_TICKET>

Send the request with the email field in the POST body.

📌 Important: The email must be sent with the field name exactly as "email", and authentication via Sf-Hmac must be present in the header.

6. See examples in different languages
JavaScript code example
<html>
<body>
<form action="">
<input type="email" name="email" value="">
<br>
<button type="button">OK</button>
</form>

<script>

// This function is just an example, if you prefer you can use your own javascript library
async function sha1(text) {
const encoder = new TextEncoder();
const data = encoder.encode(text);
const hashBuffer = await crypto.subtle.digest("SHA-1", data);
return [...new Uint8Array(hashBuffer)]
.map(byte => byte.toString(16).padStart(2, "0"))
.join("");
}
// This function is just an example, if you prefer you can use your own library javascript
async function hmacSHA256(value, key) {
const encoder = new TextEncoder();
const keyData = encoder.encode(key);
const valueData = encoder.encode(value);

const cryptoKey = await crypto.subtle.importKey(
"raw", keyData, { name: "HMAC", hash: { name: "SHA-256" } }, false, ["sign"]
);
const signature = await crypto.subtle.sign("HMAC", cryptoKey, valueData);
return [...new Uint8Array(signature)]
.map(byte => byte.toString(16).padStart(2, "0"))
.join("");
}

document.querySelector("button").addEventListener("click", async function () {
const emailInput = document.querySelector('[type="email"]');
if (!emailInput || emailInput.value.length < 1)
throw new Error("Invalid Email Input value");

// Enter the ticket_origin and api_key values generated on the SafetyMails platform below.
const ticket = '<TK ORIGEM INFORMADA NO PAINEL SAFETYMAILS>';
const api_key = '<APIKEY INFORMADA NO PAINEL SAFETYMAILS>';
const code = await sha1(ticket);

const email = emailInput.value;
const url = `https://${ticket}.safetymails.com/api/${code}`;
const hmac = await hmacSHA256(email, api_key);

let form = new FormData();
form.append('email',email);

try {
const response = await fetch(url, {
method: "POST",
headers: {
"Sf-Hmac": hmac
},
body: form
});

if (!response.ok) {
console.error(`HTTPCode ${response.status}`);
return;
}

const data = await response.json();

if (!data.Success) {
console.error("Response error", data);
return;
}

console.log("Response success", data);
} catch (error) {
console.error("Request failed", error);
}
});
</script>
</body>
</html>

Example code in PHP
<?php
function SafetyApi($email) {
$apiKey = '<APIKEY INFORMADA NO PAINEL SAFETYMAILS>';
$tkOrigem = '<TK ORIGEM INFORMADA NO PAINEL SAFETYMAILS>';
$timeout = 10; // Timeout da conexĂŁo com a Safetymails
$url = "https://{$tkOrigem}.safetymails.com/api/".sha1($tkOrigem);
$header[] = "Sf-Hmac: " . hash_hmac('sha256', $email, $apiKey);
$post['email'] = $email;

$process = curl_init($url);
curl_setopt($process, CURLOPT_HEADER, 0);
curl_setopt($process, CURLOPT_FRESH_CONNECT, 1);
curl_setopt($process, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($process, CURLOPT_FORBID_REUSE, 1);
curl_setopt($process, CURLOPT_TIMEOUT, $timeout);
curl_setopt($process, CURLOPT_ENCODING, '');
curl_setopt($process, CURLOPT_POST, 1);
curl_setopt($process, CURLOPT_HTTPHEADER, $header);
curl_setopt($process, CURLOPT_POSTFIELDS, http_build_query($post));

$ret = curl_exec($process);
curl_close($process);

$httpCode = curl_getinfo($process, CURLINFO_HTTP_CODE);

$result = NULL;

if ($ret === false && curl_errno($process) === CURLE_OPERATION_TIMEOUTED)
$httpCode = 408; // Timeout
elseif ($httpCode == 200)
$result = json_decode($ret, true);

# HTTPCODE 400 - Parâmetros inválidos
# HTTPCODE 401 - API Key inválida
# HTTPCODE 402 - Créditos insuficientes para a consulta
# HTTPCODE 403 - Acesso de uma origem diferente da cadastrada
# HTTPCODE 406 - Ticket Origem inválido ou inativo
# HTTPCODE 408 - Timeout
# HTTPCODE 429 - Limite de consultas por hora ou minuto ultrapassado

return ['Status'=>$httpCode, 'Result'=>$result];
}

$emailTeste = "teste@email.com";
print_r(SafetyApi($emailTeste));
Example code in Python
import requests
import hashlib
import hmac

def safety_api(email):
api_key = '<APIKEY INFORMADA NO PAINEL SAFETYMAILS>'
tk_origem = '<TK ORIGEM INFORMADA NO PAINEL SAFETYMAILS>'
timeout = 10 # Timeout da conexĂŁo com a Safetymails

url = f"https://{tk_origem}.safetymails.com/api/{hashlib.sha1(tk_origem.encode()).hexdigest()}"

sf_hmac = hmac.new(api_key.encode(), email.encode(), hashlib.sha256).hexdigest()
headers = {"Sf-Hmac": sf_hmac}
data = {"email": email}

try:
response = requests.post(url, headers=headers, data=data, timeout=timeout)
http_code = response.status_code
result = response.json() if http_code == 200 else None
except requests.exceptions.RequestException as e:
return {"Status": "400", "Result": str(e)}

return {"Status": http_code, "Result": result}

# Exemplo de uso
if __name__ == "__main__":
email_teste = "teste@email.com"
resposta = safety_api(email_teste)
print(resposta)
Java code example
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.OutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class SafetyApi {
public static String generateSha1(String input) throws Exception {
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] hash = md.digest(input.getBytes(StandardCharsets.UTF_8));
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
hexString.append(String.format("%02x", b));
}
return hexString.toString();
}

public static String generateHmacSha256(String key, String data) throws Exception {
Mac hmac = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
hmac.init(secretKey);
byte[] hash = hmac.doFinal(data.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(hash);
}

public static String safetyApi(String email) {
String apiKey = "<APIKEY INFORMADA NO PAINEL SAFETYMAILS>";
String tkOrigem = "<TK ORIGEM INFORMADA NO PAINEL SAFETYMAILS>";
int timeout = 10000; // Timeout em milissegundos

try {
String sha1TkOrigem = generateSha1(tkOrigem);
String urlStr = "https://" + tkOrigem + ".safetymails.com/api/" + sha1TkOrigem;
String sfHmac = generateHmacSha256(apiKey, email);

URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Sf-Hmac", sfHmac);
conn.setDoOutput(true);
conn.setConnectTimeout(timeout);
conn.setReadTimeout(timeout);

String postData = "email=" + email;
try (OutputStream os = conn.getOutputStream()) {
os.write(postData.getBytes(StandardCharsets.UTF_8));
}

int responseCode = conn.getResponseCode();
StringBuilder response = new StringBuilder();

try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
String line;
while ((line = br.readLine()) != null) {
response.append(line);
}
}

return "{ \"Status\": " + responseCode + ", \"Result\": " + response.toString() + " }";
} catch (Exception e) {
return "{ \"Status\": \"Erro\", \"Result\": \"" + e.getMessage() + "\" }";
}
}

public static void main(String[] args) {
String emailTeste = "teste@email.com";
System.out.println(safetyApi(emailTeste));
}
}
Example code in Go
package main

import (
"crypto/hmac"
"crypto/sha1"
"crypto/sha256"
"encoding/hex"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strings"
"time"
)

const (
apiKey = "<APIKEY INFORMADA NO PAINEL SAFETYMAILS>"
tkOrigem = "<TK ORIGEM INFORMADA NO PAINEL SAFETYMAILS>"
timeout = 10 * time.Second // Timeout da conexĂŁo
)

// Função para gerar SHA1
func generateSHA1(input string) string {
h := sha1.New()
h.Write([]byte(input))
return hex.EncodeToString(h.Sum(nil))
}

// Função para gerar HMAC-SHA256
func generateHMACSHA256(key, data string) string {
h := hmac.New(sha256.New, []byte(key))
h.Write([]byte(data))
return hex.EncodeToString(h.Sum(nil))
}

// Function that makes the request to the API
func safetyAPI(email string) (map[string]interface{}, error) {
urlStr := fmt.Sprintf("https://%s.safetymails.com/api/%s", tkOrigem, generateSHA1(tkOrigem))
hmacSignature := generateHMACSHA256(apiKey, email)

// Creating data in form-data format
formData := url.Values{}
formData.Set("email", email)
formEncoded := formData.Encode() // "email=teste@email.com"

// Creating the POST request
client := http.Client{Timeout: timeout}
req, err := http.NewRequest("POST", urlStr, strings.NewReader(formEncoded))
if err != nil {
return nil, err
}

// Defining headers
req.Header.Set("Sf-Hmac", hmacSignature)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded") // Envio como form-data

// Sending the request
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

// Read reply
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}

// Creating the return
result := map[string]interface{}{
"Status": resp.StatusCode,
"Result": string(body), // Retorna o JSON da API como string
}

return result, nil
}

func main() {
email := "teste@email.com"
resposta, err := safetyAPI(email)
if err != nil {
fmt.Println("Erro:", err)
} else {
fmt.Println(resposta)
}
}

8. Structure and meaning of API responses

After each request, the SafetyMails API returns a response in JSON format, which tells you whether the verification was successful, the status of the email consulted and how many credits are still available in the account.


This information is essential for quickly identifying whether the email is valid, invalid, risky or unknown, as well as pointing out possible technical or operational problems.


Check out the main fields returned by the API below:
Field Or what does it mean
Success Return of type bool (true or false). Indicates whether the request was successfully executed. If it returns false, it means that the query was not carried out, and there may be failures such as: incorrect API key, invalid or inactive ticket, malformed parameters, request limit exceeded or lack of credits.
DomainStatus Status of the e-mail domain consulted.
StatusResult of e-mail validation, if successful. The status can be: Valid, Role-based, low deliverability, disposable, uncertain, junk, invalid, invalid domain, syntax error and pending.
EmailEmail consulted.
LimitedThis tells you if the e-mail you are looking at is from a limited provider, i.e. one that receives a limited number of requests.
PublicIt tells you whether the email being consulted is from a 'Corporate' domain (private domains and/or domains with private rules for receiving emails) or an 'Email provider' domain (domains with public rules for receiving emails).
AdviceThis is a classification suggested by SafetyMails for the status of the email consulted (Valid, Invalid, Risky or Unknown) to facilitate analysis.
BalanceNumber of consultation credits available in your account.
MsgReturns the error message for the call failure (only when the call fails).

Example of a successful return

Retorno em JSON
{
"Success":true,
"Email":"testeemail@safetymails.com",
"Referer":"www.safetymails.com",
"DomainStatus":"VALIDO",
"Status":"VALIDO",
"Advice":"Valid",
"Public":null,
"Limited":null,
"Balance":4112343
}

Example in the event of a query error

Return in JSON
{
"Success":false,
"Email":"testeemail@safetymails.com",
"Referer":"www.safetymails.com",
"Status":"PENDENTE",
"Advice":"Unknown",
"Msg":"Referer inválido"
}

9. Error messages returned by the email verification API

The error messages below will only be displayed when the Success field is false in the API response. In these cases, the query was not successful, and the Msg field will inform you of the reason for the failure.


These errors are usually related to authentication problems, incorrect parameters, lack of credits or exceeded limits.
HTTP CodeErroDescription
400Invalid parametersIncorrect or non-existent access keys.
401Invalid API Key Incorrect or non-existent access keys.
406Invalid or inactive Source TicketYou are trying to perform queries for an inactive API origin. Go to your dashboard and activate the origin correctly.
403Origin different from registered (%s)<>(%s)You are trying to perform queries for an API origin other than the one registered in your account. Check the origin and try again
429Limit of queries per hour or minute or daily exceeded - Contact SupportSafetymails protects your form from misuse by allowing you to limit the number of queries coming from the same IP address. In addition, all plans have limits on the number of queries per hour and minute, protecting you from errors that can cause loops. If you want to make more queries than expected, please contact support (support@safetymails.com).
402No credits for researchYour account does not have the credits to make the query. You need to buy credits.

📌 Tip: Always check the Msg field in the JSON return to understand the exact reason for the failure.

If you need further guidance on configuring your API, please contact our support team:
đź“§ support@safetymails.com

Still need help? Message Us