SMS & messages
What is smishing?
Coverage: Indicative result based on automatic signals, not sender verification. No result guarantees that a message is safe.
Open toolOn this page
Purpose
Smishing is deception by SMS that impersonates an organization to obtain money, information or codes. Check the sender, text and domain before acting; confirm requests through an official channel you already know.
Paste the text you received and we’ll instantly tell you whether it shows the typical signs of smishing: shortened links, domains imitating banks or couriers, and urgent pressure.
Requirements
Anyone can read these guides, no account needed. Some tools require Pro, as indicated in each guide.
Include the complete message. You do not need to open links or share personal codes.
How to use it
Include the complete message. You do not need to open links or share personal codes.
Check message
Do not share passwords, PINs or verification codes in response to a text message.
Check the link’s real domain: "bank-security.com" is not your bank’s website.
Urgency ("final notice", "account blocked") is a scammer’s favourite tool.
When in doubt, open the official website or app yourself instead of tapping the link.
Synthetic example
Invented example, not a real lookup. Do not call or open its links.
DHL: Last warning. Your parcel is blocked. Action required at https://parcel.exampleInterpret the result
Don’t tap the link, don’t reply and don’t share any details. Delete it and, if unsure, contact the company through its official website or number.
It shows some scam signs. Don’t open the link; check directly on the official website or app.
Only domains are displayed, without active links. A familiar domain does not prove a message is genuine.
Limitations
The check runs in your browser: the message text is never sent to any server.
Indicative result based on automatic signals, not sender verification. No result guarantees that a message is safe.
Troubleshooting
Paste the message text to check it.
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.
Local rule-engine check of one SMS: scam, suspicious or likely safe, with the integer score behind it (4 or more scam, 2–3 suspicious, 0–1 likely safe), signals, hosts, link flags and the named brand with its sms-brand id.
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/smishing
POST https://api.nocall.io/v2/tools {"tool":"smishing","message":"CORREOS: su paquete está retenido. Pague urgente las tasas en https://correos-entrega.info/pago","country":"ES"}Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| message | string (1–2000) | Yes | SMS text to check. |
| 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/smishing' \
--header "Authorization: Bearer $NOCALL_API_KEY" \
--header 'Content-Type: application/json' \
--header "Idempotency-Key: $REQUEST_ID" \
--data '{"message":"CORREOS: su paquete está retenido. Pague urgente las tasas en https://correos-entrega.info/pago","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/smishing',
method='POST',
data=json.dumps({'message': 'CORREOS: su paquete está retenido. Pague urgente las tasas en https://correos-entrega.info/pago', '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/smishing', {
method: 'POST',
headers: {
Authorization: 'Bearer ' + apiKey,
'Content-Type': 'application/json',
'Idempotency-Key': requestId,
},
body: JSON.stringify({ message: 'CORREOS: su paquete está retenido. Pague urgente las tasas en https://correos-entrega.info/pago', 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": "smishing",
"result": {
"verdict": "scam",
"score": 9,
"attention": true,
"signals": [
"suspicious_domain",
"risky_tld",
"urgency",
"brand_impersonation",
"delivery_lure"
],
"hosts": [
"correos-entrega.info"
],
"linkFlags": [],
"brand": "correos",
"brandSlug": "correos"
}
},
"meta": {
"requestId": "req_example",
"unitsCharged": 1,
"usage": {
"periodStart": "2026-10-01",
"unitLimit": 20,
"unitsUsed": 3,
"unitsRemaining": 17
}
}
}Result fields (data.result)
| Field | Type | Description |
|---|---|---|
| verdict | "scam" | "suspicious" | "likely_safe" | Verdict of the local rules. |
| score | integer | Integer rule score: 4 or more is scam, 2–3 suspicious and 0–1 likely safe. |
| attention | boolean | Whether the content deserves a closer look. |
| signals | array<string (enum, 10)> | Rule signals that matched. |
| hosts | array<string> | Host names found in the text. |
| linkFlags | array<"http" | "userinfo" | "internationalHost" | "ipAddress" | "nonStandardPort"> | Structural warnings about the link: http, userinfo, international host, IP address or non-standard port. |
| brand | string | null | Brand named in the message, or null. |
| brandSlug | string (enum, 10) | null | The sms-brand id of the named brand, or null. |
