Scam-Less API v1.4

API documentation

One endpoint checks a message, link, phone number, screenshot or supplier invoice and returns a risk score, a recommended action and the scammer’s indicators. Call it before you release a payout or show a message.

Authentication

Create a key in the dashboard and send it as a bearer token. Keys look like sl_live_ followed by 40 characters. Keep them server-side: never ship a key in a browser or mobile app.

Authorization: Bearer sl_live_…

POST /api/v1/analyze

Known scams are answered from our honeypot cache in milliseconds. Everything else runs deterministic forensics (domain age, IBAN checks, headers, PDF tampering) and then AI analysis. Typical response time is under a second for text and a few seconds for screenshots and PDFs.

curl

curl https://scam-less.com/api/v1/analyze \
  -H "Authorization: Bearer $SCAMLESS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "check_type": "MESSAGE",
    "content": "AIB: your card is blocked. Verify at aib-verify.top today",
    "context": { "default_region": "IE" }
  }'

Node.js

const res = await fetch('https://scam-less.com/api/v1/analyze', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.SCAMLESS_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    check_type: 'INVOICE',
    content: emailBody,
    email: { raw_headers: rawHeaders },
    pdf: { data: invoicePdf.toString('base64') },
    context: { expected_country: 'IE' },
  }),
});
const verdict = await res.json();
if (verdict.recommended_b2b_action === 'HOLD_PAYOUT_FOR_REVIEW' ||
    verdict.recommended_b2b_action === 'BLOCK_AND_ALERT_SECURITY') {
  await holdPayout(paymentId, verdict.request_id);
}

Python

import os, requests

r = requests.post(
    "https://scam-less.com/api/v1/analyze",
    headers={"Authorization": f"Bearer {os.environ['SCAMLESS_API_KEY']}"},
    json={"check_type": "PHONE", "content": "+353 76 612 3456"},
    timeout=10,
)
r.raise_for_status()
v = r.json()
print(v["verdict"], v["risk_score"], v["explanation_for_end_user"])

Request body

FieldTypeNotes
check_typerequiredMESSAGE, URL, PHONE, SCREENSHOT or INVOICE
contentstring ≤ 20,000Required for MESSAGE, URL and PHONE. For INVOICE, the email body.
imageobjectSCREENSHOT only: { media_type, data }, base64, ≤ 5 MB.
pdfobjectINVOICE only: { data }, base64, ≤ 10 MB.
emailobjectraw_headers (best) or from, reply_to, subject, authentication_results.
context.expected_countryISO-2Where the payee should be. Drives cross-border IBAN checks.
context.default_regionIE | GBHow to read national-format phone numbers.
context.recipient_emailstringYour customer’s address. Redacted before analysis, never stored.

Response

{
  "risk_score": 94,
  "confidence": 0.93,
  "verdict": "CRITICAL_BLOCK",
  "scam_category": "BANK_IMPERSONATION",
  "recommended_b2b_action": "BLOCK_AND_ALERT_SECURITY",
  "coercion_tactics_detected": ["Urgency", "Authority / Brand Impersonation"],
  "technical_flags_triggered": ["BRAND_KEYWORD_IN_UNOFFICIAL_DOMAIN", "NEWLY_REGISTERED_DOMAIN", "SUSPICIOUS_TLD"],
  "explanation_for_end_user": "AIB will never ask you to verify your card through a text link…",
  "explanation_for_compliance_team": "Brand keyword on a 3-day-old .top domain; urgency language…",
  "extracted_scammer_iocs": {
    "impersonated_brand": "AIB",
    "malicious_urls": ["http://aib-verify.top"],
    "scammer_phones": [],
    "scammer_ibans_or_accounts": [],
    "scammer_crypto_wallets": []
  },
  "processing_time_ms": 912,
  "tier1_cache_hit": false,
  "request_id": "6f1c0e8a-…",
  "meta": {
    "api_version": "1.4",
    "check_type": "MESSAGE",
    "engine": "claude-haiku-5-5",
    "degraded": false,
    "stage1_ms": 212.4,
    "stage2_ms": 690,
    "enrichment": { "domains": [{ "domain": "aib-verify.top", "age_days": 3, "rdap_status": "OK", "flags": ["…"] }], "ibans": [], "phones": [], "email_auth": null, "pdf": null }
  }
}

extracted_scammer_iocs only ever contains indicators that appear in what you sent. meta.degraded: true means the AI stage was unavailable and the verdict comes from deterministic checks alone.

Verdicts and actions

Scoreverdictrecommended_b2b_actionWhat to do
0–29SAFEALLOW_TRANSACTIONProceed.
30–69SUSPICIOUSSHOW_COOLING_OFF_WARNINGWarn the user and add friction before paying.
70–89HIGH_RISK_SCAMHOLD_PAYOUT_FOR_REVIEWHold the payment for a human to review.
90–100CRITICAL_BLOCKBLOCK_AND_ALERT_SECURITYBlock and alert your fraud team.

Technical flags

TIER1_HONEYPOT_MATCH:<TYPE>An indicator is a confirmed scam in our database (returned in milliseconds, no AI call).
NEWLY_REGISTERED_DOMAINA domain in the content was registered within the last 30 days.
BRAND_LOOKALIKE_DOMAIN / HOMOGLYPH_SPOOFA domain imitates a known brand with swapped or look-alike characters.
BRAND_KEYWORD_IN_UNOFFICIAL_DOMAINA brand name appears in a domain that brand does not own.
CROSS_BORDER_IBAN_MISMATCHAn Irish/UK counterparty asks for payment to a high-risk foreign IBAN (e.g. LT, BG, CY).
FOREIGN_IBAN_FOR_DOMESTIC_SUPPLIERPayee IBAN is outside the expected country.
EMI_OR_NEOBANK_PAYEE_ACCOUNTPayee account is at an e-money institution or neobank (unusual for established suppliers).
REPLY_TO_MISMATCHReplies are redirected to a different domain from the sender.
SPF_FAIL / DKIM_FAIL / DMARC_FAILSender authentication failed.
PDF_INCREMENTAL_UPDATE / PDF_MODIFIED_AFTER_CREATIONThe invoice PDF was edited after it was first created.
VOIP_OR_NON_GEOGRAPHIC_NUMBER / UK_070_PERSONAL_NUMBERNumber types commonly used as burners.
KNOWN_INDICATOR_LOW_CONFIDENCEAn indicator has been reported but is not yet confirmed.

Errors and limits

Errors return { "error": { "code", "message" }, "request_id" }.

400VALIDATION_FAILED, INVALID_JSON. error.details lists the fields.
401INVALID_API_KEY, UNAUTHORIZED
402TRIAL_EXPIRED
413 / 415Body too large / not JSON
429QUOTA_EXCEEDED (monthly plan limit). See X-Quota-Remaining.
503Temporary; retry with backoff (see Retry-After).

GET /api/v1/radar/top-brands

Most-impersonated brands in our Ireland and UK feed over the last days (1–90, default 7). Any active key; does not use quota.

curl "https://scam-less.com/api/v1/radar/top-brands?days=7" -H "Authorization: Bearer $SCAMLESS_API_KEY"

{ "window_days": 7, "brands": [ { "impersonated_brand": "An Post", "scam_category": "SMISHING_DELIVERY",
  "indicators": 41, "reports": 118, "high_confidence": 33, "last_seen_at": "2026-10-20T09:14:00.000Z" } ] }

Email Shield (no code)

Invoice Shield customers forward suspicious invoices and bank-detail changes to check@scam-less.com and get a traffic-light verdict back by email. Forwards from your organisation’s domain are recognised automatically. Use “Forward as attachment” so the original headers are included.

Data handling

Content is processed in memory and is not stored. Victim personal data (names, cards, PPSN, addresses, the recipient’s email) is redacted before AI analysis. We keep check metadata for your audit log, and scammer indicators (malicious links, numbers, IBANs) from confirmed scams to protect other customers.