Links, websites & email
Is this email real?
Coverage: Works with emails from any country and in any language: it reads the SPF, DKIM and DMARC check your own provider (Gmail, Outlook, Yahoo, iCloud and others) records in the headers when it receives the message, and checks the sender’s name and domain with NoCall’s brand rules for this edition.
Open toolOn this page
Purpose
Paste the headers of a suspicious email to check whether your own email provider verified the sender (SPF, DKIM and DMARC), whether the name impersonates a brand and where replies really go.
Requirements
Anyone can read these guides, no account needed. Some tools require Pro, as indicated in each guide.
An email can show any name in “From”. What’s much harder to fake is what your email provider checks when it receives it. Paste the message headers here and we’ll tell you whether the sender is who they claim to be. Nothing is sent or stored.
How to use it
Gmail: open the email, tap the three dots and choose “Show original”. Copy all the text.
Outlook: open the email, click the three dots, “View” and “View message source” or “Message details”.
Apple Mail: open the email and choose “View”, “Message” and “Raw Source”.
Yahoo Mail: open the email, click “More” and “View raw message”.
Check the sender
Synthetic example
Invented example, not a real lookup. Do not call or open its links.
From: "Bank" <[email protected]>Interpret the result
Don’t trust this email: Your provider couldn’t confirm the sender, or the email impersonates a brand. Don’t click links, don’t download attachments and don’t reply. If it claims to be from a company, go to its website or app by typing the address yourself.
Review this email carefully: The sender is verified, but some details are worth checking before you reply or click a link.
The sender is verified: Your email provider checked that the email comes from the domain shown in “From”. That doesn’t guarantee the content is genuine: stay wary if it asks for details or payments.
Limitations
Checked in your browser: the headers are never sent or stored, and the result only shows domains, never full addresses.
Troubleshooting
We couldn’t find email headers in the text. Copy the full original message, not just the body.
The headers have no sender (From). Copy the full original message.
The headers are too long to check (64 KB at most).
Use with the API
Needs an API key and credits. Each completed call costs 1 credit, even when there is no data. An active Pro account includes 20 credits per UTC calendar month, shared by every API route and spent first; unused monthly credits do not roll over. Credits bought on your account page work without Pro and never expire.
Errors are never charged: 401 invalid_api_key (missing or invalid key), 403 pro_required (no Pro credits and no purchased credits), 422 invalid input, 429 quota_exceeded (no credits left), rate_limit_exceeded or ai_busy (the AI of sms-check is at capacity), 503 tool_warming (the data is still being prepared) or tool or provider unavailable. After a 429 or 503, retry once the seconds in the Retry-After header have passed.
Whether the receiving provider authenticated an email (SPF, DKIM and DMARC from the topmost Authentication-Results) and the sender tells: a brand in the display name, free-mail or look-alike domains, replies to another domain. Domains only; nothing is stored.
Send the JSON body to the tool's own route, or to POST /v2/tools with the tool field added. Both routes return the same result.
POST https://api.nocall.io/v2/email-headers
POST https://api.nocall.io/v2/tools {"tool":"email-headers","headers":"Delivered-To: [email protected]\nReceived: from mail.bank.example (mail.bank.example [192.0.2.10]) by mx.google.com with ESMTPS id x1 for <[email protected]>; Tue, 27 Oct 2026 09:00:00 -0700\nAuthentication-Results: mx.google.com; dkim=pass [email protected] header.s=s1; spf=pass (google.com: domain of [email protected] designates 192.0.2.10 as permitted sender) [email protected]; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=bank.example\nFrom: \"Bank Alerts\" <[email protected]>\nReply-To: [email protected]\nSubject: Your statement is ready\nMessage-ID: <[email protected]>","country":"ES"}Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| headers | string (1–65536) | Yes | The raw headers of the email (“Show original”), up to 64 KB; anything after the first blank line is ignored. |
| country | string (enum, 55) | No (default: "ES") | Country whose SMS rule set is used. |
REQUEST_ID="$(uuidgen)" && [ -n "$REQUEST_ID" ] &&
curl --request POST 'https://api.nocall.io/v2/email-headers' \
--header "Authorization: Bearer $NOCALL_API_KEY" \
--header 'Content-Type: application/json' \
--header "Idempotency-Key: $REQUEST_ID" \
--data '{"headers":"Delivered-To: [email protected]\nReceived: from mail.bank.example (mail.bank.example [192.0.2.10]) by mx.google.com with ESMTPS id x1 for <[email protected]>; Tue, 27 Oct 2026 09:00:00 -0700\nAuthentication-Results: mx.google.com; dkim=pass [email protected] header.s=s1; spf=pass (google.com: domain of [email protected] designates 192.0.2.10 as permitted sender) [email protected]; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=bank.example\nFrom: \"Bank Alerts\" <[email protected]>\nReply-To: [email protected]\nSubject: Your statement is ready\nMessage-ID: <[email protected]>","country":"ES"}'import json
import os
import urllib.request
import uuid
api_key = os.environ.get('NOCALL_API_KEY')
if not api_key:
raise SystemExit('Set NOCALL_API_KEY')
request = urllib.request.Request(
'https://api.nocall.io/v2/email-headers',
method='POST',
data=json.dumps({'headers': 'Delivered-To: [email protected]\nReceived: from mail.bank.example (mail.bank.example [192.0.2.10]) by mx.google.com with ESMTPS id x1 for <[email protected]>; Tue, 27 Oct 2026 09:00:00 -0700\nAuthentication-Results: mx.google.com; dkim=pass [email protected] header.s=s1; spf=pass (google.com: domain of [email protected] designates 192.0.2.10 as permitted sender) [email protected]; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=bank.example\nFrom: "Bank Alerts" <[email protected]>\nReply-To: [email protected]\nSubject: Your statement is ready\nMessage-ID: <[email protected]>', 'country': 'ES'}).encode(),
headers={
'Authorization': 'Bearer ' + api_key,
'Content-Type': 'application/json',
'Idempotency-Key': str(uuid.uuid4()),
},
)
with urllib.request.urlopen(request, timeout=30) as response:
result = json.load(response)
print(result['data']['result'], result['meta']['unitsCharged'])import { randomUUID } from 'node:crypto';
const requestId = randomUUID();
const apiKey = process.env.NOCALL_API_KEY;
if (!apiKey) throw new Error('Set NOCALL_API_KEY');
const response = await fetch('https://api.nocall.io/v2/email-headers', {
method: 'POST',
headers: {
Authorization: 'Bearer ' + apiKey,
'Content-Type': 'application/json',
'Idempotency-Key': requestId,
},
body: JSON.stringify({ headers: 'Delivered-To: [email protected]\nReceived: from mail.bank.example (mail.bank.example [192.0.2.10]) by mx.google.com with ESMTPS id x1 for <[email protected]>; Tue, 27 Oct 2026 09:00:00 -0700\nAuthentication-Results: mx.google.com; dkim=pass [email protected] header.s=s1; spf=pass (google.com: domain of [email protected] designates 192.0.2.10 as permitted sender) [email protected]; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=bank.example\nFrom: "Bank Alerts" <[email protected]>\nReply-To: [email protected]\nSubject: Your statement is ready\nMessage-ID: <[email protected]>', country: 'ES' }),
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.code ?? 'request_failed');
console.log(result.data.result, result.meta.unitsCharged);Example response (200)
This is the documented example from the API reference. Lookups use a fictional number, and aggregates and AI answers show the shape of the result, not live data.
{
"data": {
"tool": "email-headers",
"result": {
"fromDomain": "bank.example",
"fromDomainAscii": "bank.example",
"displayName": "Bank Alerts",
"replyToDomain": "other.example",
"returnPathDomain": null,
"senderDomain": null,
"subject": "Your statement is ready",
"auth": {
"provider": "mx.google.com",
"source": "authentication_results",
"spf": "pass",
"spfDomain": "bank.example",
"dkim": "pass",
"dkimDomains": [
"bank.example"
],
"dmarc": "pass",
"dmarcDomain": "bank.example",
"compauth": null,
"aligned": true
},
"authenticated": true,
"brand": null,
"official": false,
"freeMail": false,
"signals": [
"reply_to_mismatch"
],
"attention": true
}
},
"meta": {
"requestId": "req_example",
"unitsCharged": 1,
"usage": {
"periodStart": "2026-10-01",
"unitLimit": 20,
"unitsUsed": 3,
"unitsRemaining": 17
}
}
}Result fields (data.result)
| Field | Type | Description |
|---|---|---|
| fromDomain | string | The From domain in Unicode; never a full address. |
| fromDomainAscii | string | The From domain as mail systems see it (punycode). |
| displayName | string | null | The display name, with any email local part and IP address replaced by …, or null. |
| replyToDomain | string | null | The domain replies go to, or null. |
| returnPathDomain | string | null | The domain delivery notices go to, or null. |
| senderDomain | string | null | The domain of the Sender field, or null. |
| subject | string | null | The decoded subject, with local parts and IP addresses replaced by …, or null. |
| auth | object | The provider’s results: provider, source, spf, dkim and dmarc (pass, fail, softfail, neutral, none, temperror, permerror or policy) with their domains, compauth and whether they align with the From domain. |
| authenticated | boolean | Whether the provider verified that the email comes from the From domain (DMARC pass or an aligned DKIM pass). |
| brand | string | null | The brand named in the display name or subject, or null. |
| official | boolean | Whether the host is an official brand or government domain. |
| freeMail | boolean | Whether the From domain is a free email service anyone can sign up to. |
| signals | array<string (enum, 15)> | no_auth_results, dmarc_fail, dmarc_none, spf_fail, dkim_fail, dkim_unaligned, return_path_mismatch, reply_to_mismatch, display_name_brand, display_name_address, free_mail_brand, lookalike_domain, suspicious_domain, risky_tld or multiple_from. |
| attention | boolean | Whether the content deserves a closer look. |
Frequently asked questions
What are SPF, DKIM and DMARC?
They’re the checks your email provider runs when it receives an email: SPF checks whether the sending server is authorised, DKIM verifies a signature from the domain and DMARC confirms everything matches the domain you see in “From”. If DMARC fails, the sender is fake.
If the sender is verified, is the email safe?
Not always. Verified means it comes from that domain, but a scammer can use their own domain that looks like a brand’s, or a hacked account. Also look at the domain shown and stay wary of any request for details or payments.
Why isn’t the sender’s name enough?
Because the display name is written by whoever sends the email and can say anything, even your bank’s name or a fake address in quotes. What counts is the verified domain.
