curl --request POST \
--url https://api.finowl.co/v1/compliance/email \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"email": "priya.sharma@example.in"
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({email: 'priya.sharma@example.in'})
};
fetch('https://api.finowl.co/v1/compliance/email', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.finowl.co/v1/compliance/email"
payload = { "email": "priya.sharma@example.in" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.finowl.co/v1/compliance/email"
payload := strings.NewReader("{\n \"email\": \"priya.sharma@example.in\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.finowl.co/v1/compliance/email",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'email' => 'priya.sharma@example.in'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}require 'uri'
require 'net/http'
url = URI("https://api.finowl.co/v1/compliance/email")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"email\": \"priya.sharma@example.in\"\n}"
response = http.request(request)
puts response.read_bodyHttpResponse<String> response = Unirest.post("https://api.finowl.co/v1/compliance/email")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"email\": \"priya.sharma@example.in\"\n}")
.asString();Check cold-email compliance
Place an email address in a jurisdiction and get that jurisdiction’s cold-email rule.
curl --request POST \
--url https://api.finowl.co/v1/compliance/email \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"email": "priya.sharma@example.in"
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({email: 'priya.sharma@example.in'})
};
fetch('https://api.finowl.co/v1/compliance/email', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.finowl.co/v1/compliance/email"
payload = { "email": "priya.sharma@example.in" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.finowl.co/v1/compliance/email"
payload := strings.NewReader("{\n \"email\": \"priya.sharma@example.in\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.finowl.co/v1/compliance/email",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'email' => 'priya.sharma@example.in'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}require 'uri'
require 'net/http'
url = URI("https://api.finowl.co/v1/compliance/email")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"email\": \"priya.sharma@example.in\"\n}"
response = http.request(request)
puts response.read_bodyHttpResponse<String> response = Unirest.post("https://api.finowl.co/v1/compliance/email")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"email\": \"priya.sharma@example.in\"\n}")
.asString();Good to know
- Branch on
recommendation_code. Therecommendationandmessagetext can change. Treat a code you don’t recognize likecase_by_case. unknownis a valid answer. It means no jurisdiction could be established, so the restrictiveconsent_requireddefault applies. Don’t show a country. Free mailboxes like Gmail and Proton usually come backunknown, because their domain says nothing about where the person is.mediumcan mean several candidates. Whenjurisdictions_applicablehas more than one entry, the strictest rule was applied andcountry_codeis that strictest country.checking: trueis provisional. The website check is still running. Send the same request again a few seconds later. Re-checks are free.- Repeats are free for 6 months. The same account looking up the same address again costs 0 credits, and
result_idstays the same. - This is guidance, not legal advice. The rules are compiled from public sources. Check with counsel before relying on them for a campaign.
Guide: cold-email compliance checks
Authorizations
Your Finowl API key, for example finowl_3f9a.... Create keys in the dashboard under API Keys.
Body
The address to place in a jurisdiction. Leading and trailing spaces are removed. It must be a plain address with a dotted domain.
254"priya.sharma@example.in"
Response
The check completed. An unknown verdict is still a successful response.
The address that was checked.
The jurisdiction's country name. Empty when confidence is unknown.
ISO 3166-1 alpha-2 code. Empty when confidence is unknown. When several countries are possible, the code of the strictest one.
consumer for personal mailbox providers such as Gmail, otherwise business.
consumer, business Machine-readable verdict, strictest first in the list. Branch on this, not on recommendation. Treat codes you don't recognize like case_by_case.
prohibited, consent_required, exception_required, case_by_case, allowed_with_conditions, allowed, allowed_by_policy, safe_to_send Plain-language advice. Wording varies by jurisdiction.
A sentence ready to show to end users.
The laws that govern cold email there.
Official sources for those laws or their regulators.
Key obligations when emailing.
Scope of the rule.
confident: one country backed by two independent checks or a single-country mailbox provider. medium: a likely country with thinner evidence, or several candidates. unknown: no jurisdiction established.
confident, medium, unknown Anonymized summary of the checks behind the verdict. points / max_points is a rough evidence-strength ratio.
Show child attributes
Show child attributes
1 for a charged lookup, 0 for a free repeat within 6 months.
0, 1 Every country still in contention, strictest first. Omitted when unknown. More than one entry means the strictest rule was applied.
true while the website check is still running and the verdict is provisional. Omitted when false.
Stable ID of this verdict. It stays the same across repeat calls.