Banks & fintech
Customers forward "your KYC is pending" texts to support. Check the message and its links instantly and reply with the reason, before they pay.
Scam-Check API · for business
Send a link, a customer's SMS or WhatsApp message, or a web page. Get back a verdict — safe, suspicious or dangerous — with the reasons in plain words your support team and customers can read.
$ curl https://api.safehop.app/v1/scan/url \
-H "Authorization: Bearer sh_live_…" \
-d '{"url":"paypal-account-verify-center.shop/login"}'
{
"verdict": "dangerous",
"score": 100,
"reasons": [
{ "id": "brand-impersonation", "points": 40,
"text": "uses the name \"paypal\" but is not
paypal's official site" },
{ "id": "new-domain", "points": 35,
"text": "registered only 4 days ago" },
…
],
"domain": { "ageDays": 4, "registrar": "…" }
}
Who it's for
Customers forward "your KYC is pending" texts to support. Check the message and its links instantly and reply with the reason, before they pay.
Scan links sent in buyer–seller chats and listings. Stop fake payment pages and "pay the delivery fee here" links before a user clicks.
Scan advertisers' landing pages. SafeHop unlocks cloaked pages that show reviewers a shop and victims a fake virus alert.
Rate links in messages at delivery time, in English, Japanese, Spanish and Hindi, with the local brands scammers copy.
Why SafeHop
Lists only know scams someone already reported. SafeHop also judges what a link and a page actually do, so brand-new scams are caught on day one.
Every verdict lists why: lookalike brand, domain registered 4 days ago, hidden redirect, fake-alert page. Show them to users or your fraud team.
Cloaked pages keep their scam encrypted until a real person moves the mouse. SafeHop finds the key, unlocks it safely and judges what's inside.
Links and messages you send are checked and forgotten — never stored, logged or used for ads. Only a credit count per key is kept.
Quick start
Your key stays on your server. Your website sends links or messages to your own backend, your backend asks SafeHop, and you decide what to show.
Sign in with Google or your work email. The key is shown once. 1,000 free credits a month.
Get a free keyPut it in your server's environment, not in your code or website. If it ever leaks, sign in again to get a new one.
# .env on your server: never commit it, never put the key in browser code
SAFEHOP_API_KEY=sh_live_your_key_hereCall SafeHop before a link or message is shown to other people, and act on the verdict.
// Node.js 18+ (built-in fetch). Runs on your server, never in the browser.
export async function checkLink(url) {
try {
const res = await fetch('https://api.safehop.app/v1/scan/url', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SAFEHOP_API_KEY}`,
'content-type': 'application/json',
},
body: JSON.stringify({ url }),
signal: AbortSignal.timeout(10000),
});
return res.ok ? await res.json() : null;
} catch {
return null; // SafeHop unreachable: let the content through
}
}
const result = await checkLink(linkFromUser);
if (result?.verdict === 'dangerous') {
// block it, or show result.reasons[0].text to the user
}<?php
function safehop_check_link(string $url): ?array {
$ch = curl_init('https://api.safehop.app/v1/scan/url');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('SAFEHOP_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['url' => $url]),
]);
$body = curl_exec($ch);
$ok = curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200;
curl_close($ch);
return $ok ? json_decode($body, true) : null; // null: let the content through
}
$result = safehop_check_link($linkFromUser);
if ($result && $result['verdict'] === 'dangerous') {
// block it, or show $result['reasons'][0]['text']
}import os
import requests
def check_link(url):
try:
r = requests.post(
"https://api.safehop.app/v1/scan/url",
headers={"Authorization": f"Bearer {os.environ['SAFEHOP_API_KEY']}"},
json={"url": url},
timeout=10,
)
return r.json() if r.ok else None
except requests.RequestException:
return None # SafeHop unreachable: let the content through
result = check_link(link_from_user)
if result and result["verdict"] == "dangerous":
... # block it, or show result["reasons"][0]["text"]curl https://api.safehop.app/v1/scan/url \
-H "Authorization: Bearer $SAFEHOP_API_KEY" \
-H "content-type: application/json" \
-d '{"url":"paypal-account-verify-center.shop/login"}'| Verdict | What to do |
|---|---|
safe | Let it through |
suspicious | Show a warning with reasons[0].text |
dangerous | Block it, or ask the user to confirm |
POST /v1/scan/message with {"text": "…"}.Docs
Base URL https://api.safehop.app. Send your key in the Authorization: Bearer sh_live_… header and a JSON body.
| Endpoint | Body | What it does | Credits |
|---|---|---|---|
POST /v1/scan/url | { "url" } | Rates a link: lookalike brands, domain age and registrar, live scam lists, redirects and ad-click destinations. | 1 |
POST /v1/scan/batch | { "urls": [ … ] } | Up to 100 links in one call. | 1 per link |
POST /v1/scan/message | { "text" } | Rates an SMS, WhatsApp message or email and every link in it: fake delivery, KYC, prize, job, investment and police scams. | 1 |
POST /v1/scan/page | { "url" } | Reads the page (as text, never run): fake logins, fake virus alerts, "can't leave" traps, hidden encrypted loaders. | 5 |
GET /v1/account | Your plan, monthly limit and credits used. | 0 |
400 the body isn't valid401 missing or wrong key · 403 key disabled429 per-minute rate or monthly credits used up{ "text": "IndiaPost: your parcel is on hold due to
incomplete address. Pay Rs 25 to reschedule:
https://indiapost-track.top/pay" }
{
"verdict": "dangerous", "score": 85,
"scamType": "a fake delivery message",
"advice": "Delivery companies don't ask for fees…",
"reasons": [ … ],
"links": [ { "url": "https://indiapost-track.top/pay",
"verdict": "suspicious", … } ]
}
Pricing
What a credit buys: checking one link or one message costs 1 credit (a batch costs 1 per link); a full page scan costs 5. Prices are in US dollars.
Create your key in a minute: 1,000 free credits every month, no card needed. Upgrade or cancel any time from your account page.