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
| Field | Type | Notes |
|---|---|---|
check_type | required | MESSAGE, URL, PHONE, SCREENSHOT or INVOICE |
content | string ≤ 20,000 | Required for MESSAGE, URL and PHONE. For INVOICE, the email body. |
image | object | SCREENSHOT only: { media_type, data }, base64, ≤ 5 MB. |
pdf | object | INVOICE only: { data }, base64, ≤ 10 MB. |
email | object | raw_headers (best) or from, reply_to, subject, authentication_results. |
context.expected_country | ISO-2 | Where the payee should be. Drives cross-border IBAN checks. |
context.default_region | IE | GB | How to read national-format phone numbers. |
context.recipient_email | string | Your 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
| Score | verdict | recommended_b2b_action | What to do |
|---|---|---|---|
| 0–29 | SAFE | ALLOW_TRANSACTION | Proceed. |
| 30–69 | SUSPICIOUS | SHOW_COOLING_OFF_WARNING | Warn the user and add friction before paying. |
| 70–89 | HIGH_RISK_SCAM | HOLD_PAYOUT_FOR_REVIEW | Hold the payment for a human to review. |
| 90–100 | CRITICAL_BLOCK | BLOCK_AND_ALERT_SECURITY | Block 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_DOMAIN | A domain in the content was registered within the last 30 days. |
BRAND_LOOKALIKE_DOMAIN / HOMOGLYPH_SPOOF | A domain imitates a known brand with swapped or look-alike characters. |
BRAND_KEYWORD_IN_UNOFFICIAL_DOMAIN | A brand name appears in a domain that brand does not own. |
CROSS_BORDER_IBAN_MISMATCH | An Irish/UK counterparty asks for payment to a high-risk foreign IBAN (e.g. LT, BG, CY). |
FOREIGN_IBAN_FOR_DOMESTIC_SUPPLIER | Payee IBAN is outside the expected country. |
EMI_OR_NEOBANK_PAYEE_ACCOUNT | Payee account is at an e-money institution or neobank (unusual for established suppliers). |
REPLY_TO_MISMATCH | Replies are redirected to a different domain from the sender. |
SPF_FAIL / DKIM_FAIL / DMARC_FAIL | Sender authentication failed. |
PDF_INCREMENTAL_UPDATE / PDF_MODIFIED_AFTER_CREATION | The invoice PDF was edited after it was first created. |
VOIP_OR_NON_GEOGRAPHIC_NUMBER / UK_070_PERSONAL_NUMBER | Number types commonly used as burners. |
KNOWN_INDICATOR_LOW_CONFIDENCE | An indicator has been reported but is not yet confirmed. |
Errors and limits
Errors return { "error": { "code", "message" }, "request_id" }.
| 400 | VALIDATION_FAILED, INVALID_JSON. error.details lists the fields. |
| 401 | INVALID_API_KEY, UNAUTHORIZED |
| 402 | TRIAL_EXPIRED |
| 413 / 415 | Body too large / not JSON |
| 429 | QUOTA_EXCEEDED (monthly plan limit). See X-Quota-Remaining. |
| 503 | Temporary; 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.