DEV Community

Smijo Anthonise
Smijo Anthonise

Posted on

Add scam & fraud detection to your app with one API call

If your product has a chat, a marketplace, payments, or any user-generated text,
your users are getting scam messages — fake KYC alerts, "verify your account"
phishing, advance-fee cons, UPI/payment-request fraud. Catching these before a
user acts is a real trust-and-safety win, but building a detector in-house is a
project on its own.

Here's how to add scam detection to your app with a single API call using
ScamCheck. Free tier is 100 scans/month, and
you can try it keyless first.

The idea

You send a piece of text (or a URL). You get back a structured verdict: is it a
scam, how risky, why, and what the user should do. One call, one JSON response.

Try it with no key (curl)

curl -X POST https://scamcheck.tech/api/scan \
  -H "Content-Type: application/json" \
  -d '{"input":"Your account is suspended. Verify at http://hdfc-verify.xyz and share your OTP.","source":"text"}'
Enter fullscreen mode Exit fullscreen mode

Response:

{
  "verdict": "Likely Scam",
  "risk": "high",
  "score": 98,
  "category": "phishing",
  "confidence": 99,
  "summary": "This looks strongly suspicious and should be treated as a likely scam.",
  "reasons": [
    "Asks you to share an OTP, CVV, PIN, card number, or password.",
    "Uses a high-risk free or cheap top-level domain commonly used in phishing.",
    "Domain impersonates \"hdfc\" but is not the official website."
  ],
  "next_steps": ["Do not click any links.", "Block and report the sender."]
}
Enter fullscreen mode Exit fullscreen mode

In production (Node.js, with an API key)

Grab a free key from your dashboard, then:

async function checkScam(text) {
  const res = await fetch("https://scamcheck.tech/api/v1/scan", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.SCAMCHECK_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ input: text, source: "text" }),
  });
  return res.json();
}

// In your message handler:
const verdict = await checkScam(incomingMessage);
if (verdict.risk === "high") {
  flagForReview(incomingMessage, verdict.reasons);
}
Enter fullscreen mode Exit fullscreen mode

Python

import os, requests

def check_scam(text: str) -> dict:
    r = requests.post(
        "https://scamcheck.tech/api/v1/scan",
        headers={"Authorization": f"Bearer {os.environ['SCAMCHECK_API_KEY']}"},
        json={"input": text, "source": "text"},
        timeout=15,
    )
    r.raise_for_status()
    return r.json()

result = check_scam(user_message)
if result["score"] >= 65:
    quarantine(user_message)
Enter fullscreen mode Exit fullscreen mode

Using it from an AI agent (MCP)

ScamCheck is also a Model Context Protocol
server, so you can give an AI agent the ability to check messages itself. Add it
in Claude (Settings → Connectors → Add custom connector):

https://scamcheck.tech/api/mcp
Enter fullscreen mode Exit fullscreen mode

Or install for Claude Desktop / Cursor:

npx scamcheck-mcp-server
Enter fullscreen mode Exit fullscreen mode

Now your agent can call scan_message whenever a user shares something
suspicious — useful for agentic commerce, support bots, and AI assistants.

How it works under the hood

  • A rule engine (~60 weighted patterns) does the fast first pass: URL structure, brand impersonation, credential-request phrasing, risky TLDs, and known-bad domains refreshed daily from public threat feeds.
  • Only borderline cases escalate to an LLM, keeping latency and cost low.
  • Every change runs against a labeled eval harness to guard against regressions and false positives.

Good places to call it

  • Marketplaces: screen buyer/seller chats for off-platform and advance-fee scams.
  • Fintech: flag phishing and fake-payment messages before chargebacks.
  • Chat / social: detect scam links and impersonation in UGC.
  • Trust & Safety: auto-triage reports with a verdict, score, and reasons.

Docs and free key: https://scamcheck.tech/business

I built this and I'm actively improving it — if you find a message it gets wrong,
I'd love to hear about it.

Top comments (0)